wit-bindgen icon indicating copy to clipboard operation
wit-bindgen copied to clipboard

Prototyping handles and resources using a bindings-based implementation

Open sunfishcode opened this issue 2 years ago • 6 comments

As a way to enable more experimentation with the developer-facing side of resources, I propose we add support for parsing resource declarations and simple handle types, and implement them in bindings by lowering them into code similar to what we currently write by hand and call "pseudo-resources": plain u32 indices, which index into an implied per-store table.

Pseudo-resources don't provide cross-component isolation, and have other limitations, so they are only a temporary measure, but they are enough to open up some important developer ergonomics improvements, such as support for method-calling syntax (eg. thing.action() instead of action(thing)), greater type safety and IDE guidance, automatic destructors, structured documentation, and communication of API intent.

Even though the pseudo-resource technique itself is temporary, some of this work, such as the parsing and AST, and wit-using code that can be built on top of this, should be migratable to full resources when the pieces are in place for that.

If anyone has thoughts or questions about this, please ask! For anyone interested in working in this area, for now, please reach out to me, so we can coordinate efforts. Especially as we get into the guest-side bindings part of this, there are likely to be several parallelizable tasks.

@silesmo

sunfishcode avatar May 26 '23 21:05 sunfishcode

I’d be interested in contributing some time.

juntyr avatar May 27 '23 06:05 juntyr

I have gotten the parsing working now and written some tests for it. Next I will be looking into the lowering, lifting. @sunfishcode

Example below:

package foo:foo

interface types {
resource request { 
  foo: func(),  
  bar: func(arg: list<u32>) 
}

resource response { 
  foo: func(),
  bar: func(arg: list<u32>) 
}
}

interface handler {
use types.{request, response}
handle: func(some: shared<request>) -> shared<response>
}

world proxy {
import handler
export handler
}

silesmo avatar May 27 '23 11:05 silesmo

@silesmo Awesome! Would you mind posting a PR with just the parsing? That'll make it easiest to review. There may also be some discussion on syntax, and if so that'd benefit from being its own discussion rather than being mixed in with lifting/lowering.

One additional syntactic feature I think we'll want is the static keyword for functions in resources, which indicates the function doesn't get a receiver/self/this argument, which is useful for constructors, eg.:

resource thing {
    static make-a-thing: func(from: something) -> shared<thing>
}

sunfishcode avatar May 27 '23 17:05 sunfishcode

@juntyr Thanks! Right now @silesmo is working on the first steps; once we get to the guest-language bindings steps I expect we'll be able to fan out more.

sunfishcode avatar May 27 '23 18:05 sunfishcode

Yes, absolutely! I will make sure to make a pr later today. Should hopefully have the time to add in the static keyword as well.

silesmo avatar May 28 '23 11:05 silesmo

created pr now @sunfishcode https://github.com/bytecodealliance/wasm-tools/pull/1053

silesmo avatar May 28 '23 22:05 silesmo