For my plugin system, I would like to have both CM and non-CM wasm plugins. I also have a few more questions about wasmtime.
extern "C"
functions?flecs
ecs library into a wasm module. Then, I can provide it as a import to all of my plugins, which now get free ECS without having to statically link it themselves. But flecs
provides pointers to its data, and with CM, it won't work due to shared-nothing approach. In that case, will it work if its just a normal wasm module? Can I link it to both non-CM and CM wasm plugins?Hi, great questions!
wasm_component_model
on a Config enables the wasmtime::component apis, but it doesnt disable any others from working. in general, the way to think about the wasm_<feature>
methods on Config are, they permit new wasm proposals to be used on your Engine, many wasm features such as SIMD, bulk memory, multi memory and etc would never show up in the public interfaces you use to invoke wasm. components are sort of an exception to that because they are all about giving you a richer, higher level interface for invoking wasm.wasmtime::Linker
type for modules and the wasmtime::component::Linker
type for components are totally distinct, because they operate at different levels of abstraction. with a wasmtime::Linker
the function arguments and returns are always just i32/i64/f32/f64. since you'll probably be passing some larger or variable length data at some point, you need to interpret the relevant integers and the Caller
https://docs.rs/wasmtime/latest/wasmtime/struct.Caller.html provides access to other internals of the instance, e.g. most instances export their linear memory with the name memory
, and then its up to the wasmtime::Linker user to do the juggling to marshal things out of linear memory and into types your application can use.on the other hand, wasmtime::component::Linker
works with much higher level types (typically defined by running wasmtime::component::bindgen! on your wit document), and it doesnt expose any of that complexity from Caller
- the component model standardizes the way that complex or variable length structures are read/written to linear memory, and the wasmtime user can use the much higher level interfaces of MyStruct, MyEnum, Vec<MyType>, String etc passed right to the linker. You also probably are using bindgen!
to create your add_to_linker
calls for you, and defining trait impls instead of manually hooking up to the linker. I assume you are following some sort of guide that is based on bindgen but if you have more questions we can explore that more.
wasmtime-wasi-threads
, but it is not compatible with components. it is only compatible with wasm modules and the wasi preview 1 implementation provided in wasi-common
. thats actually a spec problem, rather than strictly an implementation problem - the way wasi-threads was specified had some corner cases that just weren't scaling without changes to core wasm itself, and the folks working on the wasi-threads proposal changed tack to a core wasm proposal called shared-everything-threads
https://github.com/WebAssembly/shared-everything-threads . you should basically consider wasi-threads a dead proposal that will never advance beyond phase 1, and not adopt it in new code unless you understand it will never work with components and it will probably be discontinued and deleted from the wasmtime tree at some point after shared-everything-threads becomes available. we know threads are really important to users, but we believe its more important to get it done right (in a way that will work across all wasm engines, and not have O(nthreads^2) scaling problems) than ship it quickly.flecs
module that has an api based on raw pointers and allow it to be used by your modules, you'll want to make that module take an import of the user module's memory. i'll warn you that creating libraries like this and maintaining them is definitely an advanced use case, there isnt a ton of prior art out there for it right now because its an optimization opportunity that, afaik, none of the current users of wasmtime have gotten to the point of really needing yet.4 continued: however, components dont ignore that this is a use case that someone may have! but again its out in pretty advanced territory where there isnt prior art yet because we havent gotten to it outside of unit tests and the like. a component itself may take a module (declared by the modules type, which are the things it exports) as an import, and then the host (or other component) that is responsible for instantiating the component can provide a concrete module. that would allow you to ship components that all depend on some trusted, but factored out, flecs
module, just like in the way where you hook the same thing up "by hand" in the first part of my answer.
the component side of that is even more out on the bleeding edge, the spec explainer shows it in this section https://github.com/WebAssembly/component-model/blob/main/design/mvp/Explainer.md#canonical-abi in the snippet below Using canonical function definitions, we can finally write a non-trivial component that takes a string, does some logging, then returns a string.
the example there is some shared definition of libc that is exporting a memory that the "main" module imports, but the effect is basically the same.
like in the first part of my answer: we think this use case is important, but its really an optimization rather than a fundamental bit of functionality for the folks actively working on components, and right now in general the focus is on getting the fundamentals working really well with better docs and UX. you can expect to see better docs and tooling and examples built out for the module import pattern some day, but right now i dont think anyone has the bandwidth to take it on, and so if you go down that path we can support you as much as we can but you'll be doing exploratory work on your own.
Thanks for the detailed answer. That clarifies a lot. I will give up on threading. I do have a few follow up questions.
png_decoder
component hosted on https://wa.dev/ . The host downloads png_decoder
component. Can I use https://github.com/bytecodealliance/wac as a library to link [compose] them both?wasmtime-wasi
works for both CM and non-CM plugins, but others like wasmtime-wasm-http
only work for Components. Is that correct?add_to_linker
with a wasmtime::component::Linker
- and the preview 1 interface, use preview1::add_to_linker
with a wasmtime::Linker
. the functionality provided in preview 2 is a superset of preview 1, most notably preview 2 adds support for sockets.2 continued. we made wasmtime-wasi-http
a separate crate from wasmtime-wasi
because its more "opinionated" on only supporting async rust hosts, because it relies so heavily on hyper
. like sockets, theres no http interfaces in preview 1, so there is no way to use it with a non-component Linker.
Nice. I think that covers all my doubts. Thanks for all the information.
Off topic, but is it possible to archive/host zulip chats publicly so that its indexed by google? It seems like there's a lot of useful questions/answer in these threads, and I think a search engine like google would make it more accessible for normal folks.
code red art has marked this topic as resolved.
this channel should be web accessible, and the motivation is exactly that reason
It is accessible, but it isn't indexed. I believe that would require a separate archival process: https://github.com/zulip/zulip-archive
I tried to search for some wasmtime topics, and even added "zulip" at the end of my search, but none of the zulip conversations seem to be indexed by google.
did you try adding non-toxic glue to your linker to make the cheese stick better?
now we'll know its indexed things when it starts suggesting that
I raised an issue at https://github.com/bytecodealliance/component-docs/issues/143 for the search engine indexing support.
Last updated: Nov 22 2024 at 16:03 UTC