Stream: wasmtime

Topic: ✔ Can I use a engine with CM enabled, to run non-CM modules?


view this post on Zulip code red art (Jun 09 2024 at 14:46):

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.

  1. If I enable CM in the config when creating the engine. Can I use the same engine to compile/instantiate raw non-CM binaries which just export/import extern "C" functions?
  2. I assume linkers must be separate, and I should add native host C functions (opengl fns) separately to a CM linker and a non-CM linker?
  3. Is wasi-threads implemented for wasmtime? Can my plugin spawn a thread to do some background work?
  4. I know components don't share memory, but do normal wasm modules share memory? I am thinking of compiling 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?

view this post on Zulip Pat Hickey (Jun 09 2024 at 17:50):

Hi, great questions!

view this post on Zulip Pat Hickey (Jun 09 2024 at 17:54):

  1. yes, enabling 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.

view this post on Zulip Pat Hickey (Jun 09 2024 at 17:58):

  1. yes the 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.

view this post on Zulip Pat Hickey (Jun 09 2024 at 18:01):

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.

view this post on Zulip Pat Hickey (Jun 09 2024 at 18:06):

  1. wasi-threads is implemented in 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.
A draft proposal for spawning threads in WebAssembly - WebAssembly/shared-everything-threads

view this post on Zulip Pat Hickey (Jun 09 2024 at 18:13):

  1. yes ordinary modules can share memories, a memory can be used by a module if it either defines it internally or imports it from elsewhere, and a module can also export any of its memories to be used elsewhere. so, if you want to define a reusable 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.

view this post on Zulip Pat Hickey (Jun 09 2024 at 18:17):

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.

view this post on Zulip Pat Hickey (Jun 09 2024 at 18:20):

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.

Repository for design and specification of the Component Model - WebAssembly/component-model

view this post on Zulip Pat Hickey (Jun 09 2024 at 18:21):

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.

view this post on Zulip Pat Hickey (Jun 09 2024 at 18:23):

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.

view this post on Zulip code red art (Jun 10 2024 at 05:47):

Thanks for the detailed answer. That clarifies a lot. I will give up on threading. I do have a few follow up questions.

  1. Lets say plugins might have dependencies like a 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?
  2. wasmtime-wasi works for both CM and non-CM plugins, but others like wasmtime-wasm-http only work for Components. Is that correct?
WebAssembly Composition (WAC) tooling. Contribute to bytecodealliance/wac development by creating an account on GitHub.

view this post on Zulip Pat Hickey (Jun 10 2024 at 15:41):

  1. yes, that is exactly the use case for wac.

view this post on Zulip Pat Hickey (Jun 10 2024 at 15:44):

  1. wasmtime-wasi is a host implementation of wasi that exposes two interfaces to wasm code: the preview 2 interface - use the 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.

view this post on Zulip Pat Hickey (Jun 10 2024 at 15:46):

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.

view this post on Zulip code red art (Jun 10 2024 at 16:00):

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.

view this post on Zulip Notification Bot (Jun 10 2024 at 16:02):

code red art has marked this topic as resolved.

view this post on Zulip fitzgen (he/him) (Jun 10 2024 at 17:09):

this channel should be web accessible, and the motivation is exactly that reason

view this post on Zulip Lann Martin (Jun 10 2024 at 17:29):

It is accessible, but it isn't indexed. I believe that would require a separate archival process: https://github.com/zulip/zulip-archive

Generate a static HTML archive of messages in any combination of streams in a Zulip organization. - zulip/zulip-archive

view this post on Zulip code red art (Jun 10 2024 at 18:02):

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.

view this post on Zulip Pat Hickey (Jun 10 2024 at 18:03):

did you try adding non-toxic glue to your linker to make the cheese stick better?

view this post on Zulip Pat Hickey (Jun 10 2024 at 18:05):

now we'll know its indexed things when it starts suggesting that

view this post on Zulip code red art (Jun 12 2024 at 11:03):

I raised an issue at https://github.com/bytecodealliance/component-docs/issues/143 for the search engine indexing support.

Zulip conversations are already public at https://bytecodealliance.zulipchat.com/ . But they are not index-able by search engines and the zulip issue zulip/zulip#21881 for this feature has had no a...

Last updated: Nov 22 2024 at 16:03 UTC