cargo-component
cargo-component copied to clipboard
[Question] How to strip component to normal wasm
Can't believe I hadn't seen this before! This + compose is awesome stuff!
I currently have been embedding the wit in a custom section so that a binary can be use in a 1.0 runtime. Your work on wit-bindgen to generate wit from the component is great and was wondering how hard it would be to strip the rest so that I could use the composition of components for building, but still use the final binary in an older runtime while also being able to go back to a component again.
Hi @willemneal!
So a WebAssembly component built with cargo component
cannot be easily stripped to only the original core module without losing all of the information regarding how its imports and exports are expected to be lowered and lifted.
That said, it is possible to, in a way, decompose a WebAssembly component created with cargo component
into just the inner core modules and have some sort of polyfill that performs the lifting and lowering for runtimes that don't support the component model.
That's the approach taken in Guy Bedford's prototype to use WebAssembly components in browsers that don't support the component model.
In theory it could be adapted to spit out code other than JavaScript that interops with a specific WebAssembly runtime to load the extracted core modules and facilitate the lowering and lifting of types passed in and out of the component.
Thanks! Looking at @guybedford 's project it splits up the components into separate binaries. Is this because the runtime is responsible for the dynamic linking at runtime?
Is it possible to combine different components into one core wasm binary? I assume that the data sections and such would need to be relocatable. Is there any work on this front? I would like to work toward publishing components and then allow them to be statically linked for Wasm 1.0 compatibility.
It's the component itself that is responsible for the linking as it describes how imports are lowered to core wasm and exports are lifted from core wasm, in addition to how any inner core modules or inner components are instantiated (core wasm has no concept of inner modules or inner instantiations); the runtime just follows the component's "instructions".
Thus a component model poly-fill implementation, like Guy's tool, requires something (in this case, generated JavaScript code) to emulate, for that specific component, what a component model supporting runtime would do to follow those "instructions".
It's not really possible to combine wasm components into a core wasm module, only into other wasm components.
In theory one could translate a component into a single webassembly module that defines every item from every transitive core module in the component, plus some code at certain call sites to copy data between linear memories (as there can be multiple linear memories inside a component). But you'd also have to rewrite every function because what used to be a separate index space for each inner core module is now unified into a single index space. It'd be quite the undertaking.
I don't know of any work beyond Guy's to do anything in this space. With a generic browser poly-fill implementation (eventually fully) implemented, there's not that many runtimes out there that I think people would use such a tool for. One would hope, should the component model prove compelling, that those runtimes would implement native support for it at that time.
Hi @willemneal. I'm going to close this issue for now, but feel free to reopen if you have additional questions (or create a topic on Zulip, as I'm happy to answer questions there as well). Thanks!