I do observe that C++ is not among the languages for which host bindings can be generated with wit-bindgen. I would like to know the reason(s) for this: is it just a matter of priority? Is there a conceptual problem providing these or are there still other reasons?
Nah just priority! The Wasmtime C++ bindings are for the core wasm layer and right now no one's implemented the C++ side of things. One option would be to add component support to Wasmtime's C API (a pretty big undertaking), and another option would be to build a C++ bindings generator targetting the current core wasm API (but this is limited to running a single component, so limited in its functionality). In any case no fundamental reason C++ can't have this, just a matter of time and effort
First post here. I'm interested in using WASM+WIT to create a plugin ecosystem for an application in industrial automation. I have gotten some basic demos running using Rust as the host and guest using wasmtime + wit-bindgen. I realize that WIT is early days still.
A few questions:
1) I'm struggling a bit with terminology. Reading the docs on WIT, it appears that resources are a way of passing an abstract/opaque type (i.e. something that has methods but no data fields like a class or interface in OOP languages ) back and forth between the guest and the host. Am I this correctly?
2) Am I understanding correctly that wit-bindgen does not yet support resources/handles?
3) Is there any estimate of when prototype support might be available?
4) Is there any way of emulating this kind of pattern ATM in WIT?
Here's a simple example. From the Host, I'd like my interface to the guest to allow the ability to create an instance of something opaque.
// 'plugin' is a component instance
// create an another opaque
let mut instance: <opaque type> = plugin.create(<bytes>, <opaque type>)?;
...
// call methods on the opaque type once created
instance.tick()
Reading the docs on WIT, it appears that resources are a way of passing an abstract/opaque type ... back and forth between the guest and the host. Am I this correctly?
Correct yeah, think of it sort of like a file descriptor if that helps.
Am I understanding correctly that wit-bindgen does not yet support resources/handles?
Correct, although it's what I'm currently working on!
Is there any estimate of when prototype support might be available?
Hopefully soon.
Is there any way of emulating this kind of pattern ATM in WIT?
Not currently, no.
Thanks Alex. That's all extremely helpful! Thanks for your insights.
Adam Crain has marked this topic as resolved.
Do we have a time estimate on new languages support?
Cole Nelms has marked this topic as unresolved.
@Cole Nelms that's a very broad question. Do you mean "host language Wasmtime support for new languages" or "guest language support in their respective toolchains" or something else?
Christoph Brewing said:
I do observe that C++ is not among the languages for which host bindings can be generated with wit-bindgen. I would like to know the reason(s) for this: is it just a matter of priority? Is there a conceptual problem providing these or are there still other reasons?
I have c++ host bindings for wamr generation working for my small necessary subset of wit in my fork at https://github.com/cpetig/wit-bindgen, that might work as a starting point. I am currently extending it to guest bindings and more types as well, but I didn't figure out how to best share the most amount of code across generators, yet.
@Christof Petig thank you for sharing that, Christof! That may become very interesting for me.
Alex Crichton said:
Nah just priority! The Wasmtime C++ bindings are for the core wasm layer and right now no one's implemented the C++ side of things. One option would be to add component support to Wasmtime's C API (a pretty big undertaking), and another option would be to build a C++ bindings generator targetting the current core wasm API (but this is limited to running a single component, so limited in its functionality). In any case no fundamental reason C++ can't have this, just a matter of time and effort
Is the guts of this essentially implementing a C++ ABI equivalent to: https://github.com/WebAssembly/component-model/blob/main/design/mvp/CanonicalABI.md?
No the canonical ABI is for how Wasmtime interacts with components, where the Wasmtime C API is for how C hosts interact with Wasmtime written in Rust. Wasmtime has native Rust APIs for interacting with the component model, and these are what would be surfaced in the C API and they handle the canonical abi internally
At the moment I am testing wasmtime in a c++ host with wit generated guest bindings and am just getting to the more interesting parts (strings and data structs / records etc.) so had been porting those functions as needed (the c++ is a runtime for a domain specific language, so having wit generate the c++ host wouldn't be that useful). I just wanted to sanity check that there isn't something about to be released, which would make it a complete waste of time (the ABI porting has been mostly painless to date)?
Ah sorry, I misunderstood! If you're targetting the core wasm API layer of Wasmtime then yes you'd need to implement the canonical ABI. That being said "exploding" a component into its core wasms and running them is not trivial
I am somewhat assuming that c/c++ support will overtake my wrapper at some point in the future (but am keen to get something in place now).
Little followup to my original post. I'm guessing that the answer is also "wait for Resources".
Is there currently a way to get state/mutability in the Guest at all? All of the trait methods on the host side of things take &mut self
whereas the Guest traits are just static methods. Is there any way to have state inside the Guest ATM?
From what I've read in the WIT docs it looks like resources address this issue, i.e. host calls a static function on the guest to create a resource, then it can call mutating methods on the resource.
Yes, resources will be the way to do this.
I just realized that an easy way to quickly support resources would be to add a function to wit-bindgen which transforms the wit_parser::UnresolvedPackage
by desugaring the resource to a handle type (u32
) and its associated functions. This would immediately support ressources for all languages supported by wit-bindgen.
Then of course one could likewise transform future<t>
into resource future-of-t { pollable: func(this: u32) -> pollable ; value: func(this: u32) -> t }
and similarly for stream<t>
and support these with already existing preview2 technology with little effort.
Did I miss something or could it really be that straightforward.
the bottleneck for resources support is at this point much more the runtime implementation @Alex Crichton is working on than the guest bindings. @Joel Dice is making very good progress on those in this PR, and I'd hope that applying that work to other guest languages wouldn't be a prohibitive amount of work, either. If that turns out to be wrong, we could fall back to the kind of desugaring you mention
Joel's work looks really promising (although the Rust code generator currently panics on the examples added by this MR :confused:) - but my primary motivation was getting a first support for future
and stream
ready - because I realized that I was doing the desugaring in WIT by hand for a lot of functions returning a "future" and this really hurts readability. And as indicated by https://github.com/WebAssembly/WASI/blob/main/docs/WitInWasi.md#streams resources are the best approximation for typed streams available today.
Hi Christof! Can you point me to the examples that are causing panics? I'd be happy to add them to the set of test cases (and fix the panics).
The resources.wit and resource_alias.wit from tests/codegen paniced when creating rust code but worked with c (in debug mode)
Ah, was the message something like "world export implementation required"? If so, that's trying to tell you that the generator needs to be told the name of the world trait implementation to use. One of the changes Alex and I decided to make was remove the export_*!
macro that was previously used to specify the trait implementation and instead require that information up front (i.e. as command line options or generate!
macro parameters, depending on how the generator is invoked).
So the complete command to generate the bindings for resources.wit, specifying the world, interface, and resource impls, would be something like:
wit-bindgen rust --world-exports MyResources --interface-exports exports=MyExports --resource-exports 'exports::x=MyX' tests/codegen/resources.wit
or, alternatively, you can tell the generator to generate stub impls instead:
wit-bindgen rust --stubs tests/codegen/resources.wit
You can see the discussion in the PR for details on _why_ we made this change, but in a nutshell the generics needed to support the export_*!
macro with resources get hairy fast, and there wasn't a lot of value to it given that everything ends up monomorphic anyway.
That said, the UX could definitely need some work, i.e. wit-bindgen
should print a friendly, helpful message when it needs more info instead of panicking. We could also consider making --stubs
the default, at least when using the CLI. I'm open to suggestions!
Thank you, I already suspected that it might require a different codegen configuration to work, but was unsure whether the default should panic.
I will take a closer look into implementing future polyfilled by resources in the coming days and make a more informed UX suggestion from there.
I found that Joel's branch works really well, especially the Rust bindings. I was even able to define a function which consumes a resource (static consume: func(obj: own<my-object>)
) and it was correctly mapped to call by value in Rust.
But some C bindings use a different module name __import_module__("test_example_my_interface"), __import_name__("[resource-drop-own]my-object")
and __import_module__("my_world"), __import_name__("[resource-drop-borrow]my-object")
(I guess the Rust module "test:example/my-interface"
is more correct) .
Is there a description on how these methods should be named? I looked into WIT.md and CanonicalABI.md but didn't find them there.
Last updated: Dec 23 2024 at 12:05 UTC