Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Proposal: Component Model v0 #479

Open
gkgoat1 opened this issue Mar 24, 2025 · 5 comments
Open

Proposal: Component Model v0 #479

gkgoat1 opened this issue Mar 24, 2025 · 5 comments

Comments

@gkgoat1
Copy link

gkgoat1 commented Mar 24, 2025

Currently, the component model is very complicated and difficult to understand and to implement. In particular, wasmtime has the only working implementation of the component nodel: wasmtime-environ, which is used by Rust dependents to lower the component model into a representation they can handle, which still has many layers of confusing abstraction.

I propose we create a minimal subset of the component model which can be implemented by other, external, runtimes and compilers, including:

  • Components are not allowed to be nested, imported, or exported
  • Async is disallowed, both in ABI options and types
  • Encodings other than the native encoding, either UTF-8 or WTF-16, are disallowed
  • externrefs are disallowed as handle types

This subset, which I propose to call Component Model v0, should include most single-module components, allowing external tools to parse this simplified representation and thus implement WASI 0.2 for it. At a later point, when the external tool is fully developed, the full component model might be implemented within that tool.

First mention of this complexity

TODO: compare with wasit2
TODO: finalize restrictions

@lukewagner
Copy link
Member

That's a fair question and there are couple of options already in progress:

  • In Add BuildTargets.md #378 there's work to specify just the core wasm ABI needed to compile and run single-module components.
  • jco transpile and gravity show how a bunch of the work to implement "the component model" can be factored out into a component-to-module pre-processing step that allows the resulting module to run on an existing core wasm engine (jco targeting the browser and gravity targeting wazero)

The former is valuable to simplify the lives of producer toolchains: they can just target the core ABI and then anyone downstream can use a tool like wasm-component-ld to wrap the module into a component or run the module directly on a core runtime. Mainly the work left to do here is finish the implementation enough to validate what's specified in #378.

The latter approach is valuable to simplify the lives of runtimes and I think could be generalized to apply to more core runtimes. E.g., I could imagine a standalone project for a "component precompiler" tool that factored as much as it could out of jco, gravity and wasmtime. I think mainly what we'd need here is folks who use or build these core runtimes to help scope out and work on this tool.

I think these two approaches would go much farther in allowing incremental adoption of the Component Model than trying to scope down the Component Model (e.g., trimming out async), although if there was a concrete use case where someone thought this would help, I'd be happy to discuss the options here.

Hope that helps, happy to discuss more.

@gkgoat1
Copy link
Author

gkgoat1 commented Mar 25, 2025

That's a fair question and there are couple of options already in progress:

  • In Add BuildTargets.md #378 there's work to specify just the core wasm ABI needed to compile and run single-module components.
  • jco transpile and gravity show how a bunch of the work to implement "the component model" can be factored out into a component-to-module pre-processing step that allows the resulting module to run on an existing core wasm engine (jco targeting the browser and gravity targeting wazero)

The former is valuable to simplify the lives of producer toolchains: they can just target the core ABI and then anyone downstream can use a tool like wasm-component-ld to wrap the module into a component or run the module directly on a core runtime. Mainly the work left to do here is finish the implementation enough to validate what's specified in #378.

I can agree with this option as a method to produce core wasm, intermediate representations, and components from a single source core wasm module. Implementation of this on the consumer side, however, would require either using a single module exclusively or reinventing the linking part of the component model, neither of which would scale as a standard (but again, WASI 0.1 is still being used due to this implementation issue for the Component Model).

The latter approach is valuable to simplify the lives of runtimes and I think could be generalized to apply to more core runtimes. E.g., I could imagine a standalone project for a "component precompiler" tool that factored as much as it could out of jco, gravity and wasmtime. I think mainly what we'd need here is folks who use or build these core runtimes to help scope out and work on this tool.

While these specialized tools can be generalized, most of their effort is concentrated around wasmtime-environ, a Rust crate with particularly wasmtime-specific interfaces. Most "implementations" of the component model in other core runtimes either defer to wasmtime-environ or just parse enough to say they don't support it. I can agree with your last statement, but we'd also need scoping and work on the Component Model. Given the already-standardized and expansive featureset already existing, a subset seems like the safest option to avoid further division.

Maybe there's another way to kick off implementation (not just adoption) of the component model that I haven't seen though. Thoughts?

I think these two approaches would go much farther in allowing incremental adoption of the Component Model than trying to scope down the Component Model (e.g., trimming out async), although if there was a concrete use case where someone thought this would help, I'd be happy to discuss the options here.

Existing tools are very close to this minimal subset; Binaryen, for instance, can easily implement it, given its built-in support for module merging. I would also see the subset as a stepping stone to full Component Model implementation in other tools--a consumer-side version of wasit2.

Hope that helps, happy to discuss more.

@fitzgen
Copy link
Collaborator

fitzgen commented Mar 25, 2025

In particular, wasmtime has the only working implementation of the component nodel: wasmtime-environ

IIUC, vscode made their own implementation of the component model that does not rely on wasmtime-environ: https://code.visualstudio.com/blogs/2024/05/08/wasm

@gkgoat1
Copy link
Author

gkgoat1 commented Mar 25, 2025

In particular, wasmtime has the only working implementation of the component nodel: wasmtime-environ

IIUC, vscode made their own implementation of the component model that does not rely on wasmtime-environ: https://code.visualstudio.com/blogs/2024/05/08/wasm

Looking at it, it seems to only implement the Canonical ABI for a single module, and cannot parse components at all. It still works better than the current status-quo, where everyone forks WASI 0.1 with ad-hoc interfaces, though.

 const module = await WebAssembly.compile(bits);

@lukewagner
Copy link
Member

WasmEdge also has an independent component-model implementation in progress which is working well enough to support wasi-http.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants