Stream: endive

Topic: WIT Bindgen and WASI


view this post on Zulip Jeremy Grelle (Sep 01 2026 at 17:34):

As touched upon in the #endive > Component Model support thread, now that the runtime support for components has reached a sufficient level (assuming my current PR lands :sweat_smile: ), I've been giving some thought to building out host-side WIT bindings that would be able to be used to implement WASI p2+ interfaces in Endive.

Ergonomically, I would like the development experience to be quite close to what Wasmtime's bindgen! macro provides. I think this is readily achievable using a Java annotation processor with a @Bindgen annotation, giving us the ability to hook in at compile time to generate the needed bindings.

The goal of the bindings is of course to reduce the amount of boilerplate code that needs to be written in order to implement the imports of a given WIT world on the host side and provide them to a guest component that targets that world. Ideally, the task of implementing the imports is reduced down to providing an implementation of a strongly typed Java interface that is generated from the WIT, and invoking the exports of a component looks as close as possible to calling any other Java class.

I have made some good progress on an initial sketch of this:
https://github.com/jeremyg484/endive-cm/compare/extract-runtime-for-pr...jeremyg484:endive-cm:bindgen-2?expand=1

There are some further details to be worked out such as handling of Records and so forth, but thus far I have implemented everything necessary to replicate the bindgen! macro's examples (https://docs.wasmtime.dev/api/wasmtime/component/bindgen_examples/index.html). This would probably be the basis for an initial PR.

The integration tests in the added bindgen-processor-tests module give a good picture of what usage would look like. For example, https://github.com/jeremyg484/endive-cm/blob/bindgen-2/bindgen-processor-tests/src/test/java/run/endive/cm/bindgen/it/helloworld/HelloWorldTest.java

If the shape of this is agreed upon, then I'll finish up the remaining details of type conversion and so forth. After that, it would be feasible to use it to start working on WASI p2+.

I am currently on the fence on whether to start a full WASI implementation before starting on the async ABI features. I haven't fully wrapped my head around this, but from a quick review of the details of Wasmtime's implementation, it seems like much of WASI p2 can be implemented using the async ABI primitives internally. Thus it could be that implementing the async ABI features first could lead to a reduction in the effort needed to support both p2 and p3.

view this post on Zulip andreaTP (Sep 02 2026 at 09:54):

assuming my current PR lands

my bad, sorry, really swamped, I'll do my best to get things sorted by EOW.
(side note: I'll be on vacation next week)

@Bindgen annotation
invoking the exports of a component looks as close as possible to calling any other Java class

Fully agree :+1:

initial sketch

That's really nice! I still need to look into the details, but seems a great starting point!

Regarding Wasi p2/p3, gut feeling is that Wasi p2 is the first reasonable target to get to something that is usable in real-world projects today(e.g. compiler toolchains should support it better than p3).
But I'm not a CM expert myself, and we would benefit insights from @Till Schneidereit or @Alex Crichton .

view this post on Zulip Jeremy Grelle (Sep 02 2026 at 12:27):

andreaTP said:

Regarding Wasi p2/p3, gut feeling is that Wasi p2 is the first reasonable target to get to something that is usable in real-world projects today(e.g. compiler toolchains should support it better than p3).

Yes, I agree that providing p2 support before p3 is a worthy target and we should absolutely do that. It's more a question of whether it's worthwhile to attempt it without building out the async ABI support in the runtime first.

The user-facing component model docs call this out:

WASI 0.3 runtimes can polyfill 0.2 by mapping 0.2 imports onto native 0.3 primitives at the host boundary, and Wasmtime’s wasmtime serve already runs both 0.3 and 0.2 components from the same binary, dispatching per component.

view this post on Zulip Alex Crichton (Sep 02 2026 at 15:08):

For Wasmtime we found that implementing WASI for both wasip2 and wasip3 heavily shaped how the APIs in the wasmtime crate looked like. In that sense what I'd say is that implementing either 0.2 or 0.3 is likely to provide valuable feedback in terms of API design, runtime implementation, etc. Wasmtime's WASI implementation has the same underlying primitives but 0.2 is not implemented in terms of 0.3. We had to do refactoring to get everything extracted between them but async was different enough they didn't naturally build on top of one another as cleanly as wasip1 being implemented in terms of pretty much exactly wasip2.

view this post on Zulip Alex Crichton (Sep 02 2026 at 15:09):

It's true though that as of right now wasip2 has the broadest toolchain support between wasip2/wasip3, although the delta between the two is in theory expected to shink rapidly over the coming months

view this post on Zulip Jeremy Grelle (Sep 02 2026 at 16:14):

That's great insight, thanks @Alex Crichton.

I believe I have a fairly decent idea at this point of the Java primitives we would use to implement the host side of the async ABI and WASI 0.3, so perhaps the thing to do would be to go ahead and start experimenting with implementation of WASI 0.2 with those same primitives where possible and leave the appropriate space for things to further evolve as async support is introduced and we then proceed to 0.3. This is essentially what I've been doing already within our runtime module, leaving space for what I have a strong sense will be needed when we get around to async support.


Last updated: Sep 20 2026 at 18:08 UTC