Skip to content

Conversation

@alexcrichton
Copy link
Member

This commit is a breaking change to the component-model-async implementation in this repository. This will effectively invalidate all WASIp3 binaries created prior to this commit. Given that this feature is off-by-default everywhere (right? right?) it's expected that while this will have churn it's the appropriate time to make such a change as this.

Concretely the changes here are:

  • Function types in the component model now reflect whether they're async-or-not. This is no longer WIT-level sugar.
  • Kebab names no longer support [async], [async method], or [async static].
  • The text format now supports (func async? (param ...)).

The binary format previously used 0x40 as the prefix byte for "this is a component function type" and now 0x43 is used as "this is an async function type". The async_ boolean is plumbed throughout component function type locations and is required to be handled by callers. For now there is no subtyping relationship between async and non-async functions, they must be exactly the same when linking.

The rationale for this change is going to be expanded on more fully in an upcoming PR to the component-model repository itself. The rough tl;dr; is that to fully support JS in/out of components the component model is going to need to require traps in some dynamic situations such as when a synchronous function-type function tries to block. This is required to respect JS's "cannot block the main thread" semantics, for example. This will be more fully explain in the component-model PR and this PR is not intended to serve as justification alone for this change. Instead this PR is intended to change/update Wasmtime as quickly as possible to understand the new binary format so implementation work can proceed as most of the work here is on the runtime side of things, not validation.

One minor caveat for this change is that the wit-dylib crate has some tests which exercise async functionality. Those are now all disabled or set as "expect this to fail" because Wasmtime, the runner for these tests, no longer understands the binaries it's ingesting.

This commit is a breaking change to the component-model-async
implementation in this repository. This will effectively invalidate all
WASIp3 binaries created prior to this commit. Given that this feature is
off-by-default everywhere (right? right?) it's expected that while this
will have churn it's the appropriate time to make such a change as this.

Concretely the changes here are:

* Function types in the component model now reflect whether they're
  `async`-or-not. This is no longer WIT-level sugar.
* Kebab names no longer support `[async]`, `[async method]`, or
  `[async static]`.
* The text format now supports `(func async? (param ...))`.

The binary format previously used 0x40 as the prefix byte for "this is a
component function type" and now 0x43 is used as "this is an async
function type". The `async_` boolean is plumbed throughout component
function type locations and is required to be handled by callers. For
now there is no subtyping relationship between async and non-async
functions, they must be exactly the same when linking.

The rationale for this change is going to be expanded on more fully in
an upcoming PR to the component-model repository itself. The rough
tl;dr; is that to fully support JS in/out of components the component
model is going to need to require traps in some dynamic situations such
as when a synchronous function-type function tries to block. This is
required to respect JS's "cannot block the main thread" semantics, for
example. This will be more fully explain in the component-model PR and
this PR is not intended to serve as justification alone for this change.
Instead this PR is intended to change/update Wasmtime as quickly as
possible to understand the new binary format so implementation work can
proceed as most of the work here is on the runtime side of things, not
validation.

One minor caveat for this change is that the `wit-dylib` crate has some
tests which exercise async functionality. Those are now all disabled or
set as "expect this to fail" because Wasmtime, the runner for these
tests, no longer understands the binaries it's ingesting.
@alexcrichton alexcrichton requested a review from a team as a code owner November 13, 2025 22:16
@alexcrichton alexcrichton requested review from dicej and removed request for a team November 13, 2025 22:16
@tschneidereit
Copy link
Member

@vados-cosmonic as a heads-up, this will be quite important for JCO.

@alexcrichton alexcrichton added this pull request to the merge queue Nov 14, 2025
Merged via the queue into bytecodealliance:main with commit b5d95aa Nov 14, 2025
34 checks passed
@alexcrichton alexcrichton deleted the component-async-function-type branch November 14, 2025 15:48
alexcrichton added a commit to dicej/wasm-tools that referenced this pull request Nov 17, 2025
github-merge-queue bot pushed a commit that referenced this pull request Nov 17, 2025
* require memory for async lifts as needed

Per WebAssembly/component-model#575, both `wasm-tools`
and Wasmtime have been too permissive, allowing async lifts to optionally omit a
memory canonopt if only the return type (and not the parameter types) would need
one.  This fixes validation to require the option in such cases.

Signed-off-by: Joel Dice <[email protected]>

* Fix streams-and-futures test

Fixing a mistake from #2376

* add memory option to lifts when needed in wit-component

Signed-off-by: Joel Dice <[email protected]>

---------

Signed-off-by: Joel Dice <[email protected]>
Co-authored-by: Alex Crichton <[email protected]>
@cpetig
Copy link
Contributor

cpetig commented Dec 9, 2025

I believe the proper link to the spec change is WebAssembly/component-model#578 (I was expecting a link from there but didn't find it)

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

Successfully merging this pull request may close these issues.

4 participants