Skip to content

feat: add {stream,future}.forward canon builtins - #2614

Merged
alexcrichton merged 6 commits into
bytecodealliance:mainfrom
rvolosatovs:feat/stream-forward
Sep 21, 2026
Merged

alexcrichton merged 6 commits into
bytecodealliance:mainfrom
rvolosatovs:feat/stream-forward

Conversation

@rvolosatovs

@rvolosatovs rvolosatovs commented Aug 20, 2026 •

Copy link
Copy Markdown
Member

Add support for {stream,future}.forward builtins as specified in WebAssembly/component-model#717

@rvolosatovs rvolosatovs changed the title feat: add stream.forward canon builtin feat: add stream.splice canon builtin Aug 21, 2026
@rvolosatovs rvolosatovs changed the title feat: add stream.splice canon builtin feat: add stream.{splice,forward} canon builtins Aug 21, 2026
@rvolosatovs
rvolosatovs force-pushed the feat/stream-forward branch 2 times, most recently from 8ff9873 to 6ce0ba5 Compare August 24, 2026 15:19
@rvolosatovs rvolosatovs changed the title feat: add stream.{splice,forward} canon builtins feat: add {stream,future}.forward canon builtins Aug 24, 2026
@rvolosatovs
rvolosatovs force-pushed the feat/stream-forward branch 2 times, most recently from d81e1b4 to a7a7254 Compare August 25, 2026 16:57
rvolosatovs added a commit to rvolosatovs/wasmtime that referenced this pull request Aug 25, 2026
Pick up `wasmparser`/`wast`/`wasm-encoder` support for the
`stream.forward` and `future.forward` canonical built-ins from
bytecodealliance/wasm-tools#2614 until that
lands upstream.
Implement parsing, validation, encoding, and printing support for the
⏩-gated `stream.forward` built-in:

    (canon stream.forward $streamT (core func $f))

where `$f` has type `(func (param i32 i32))`, taking a readable stream
end and a writable stream end.  `stream.forward` transfers both ends
out of the calling instance and returns immediately with no result, so
it takes neither an `n` parameter nor an `async` immediate.  It also
takes no `canonopt`s, since no elements pass through the caller's
linear memory.

The binary encoding uses opcode 0x2e as assigned in the proposed
specification change, and validation gates the built-in behind the
component model async and "more async builtins" features.

Assisted-by: claude:claude-fable-5
Signed-off-by: Roman Volosatovs <rvolosatovs@riseup.net>
Implement parsing, validation, encoding, and printing support for the
⏩-gated `future.forward` built-in:

    (canon future.forward $futureT (core func $f))

where `$f` has type `(func (param i32 i32))`, taking a readable future
end and a writable future end.  Exactly like its `stream.forward`
counterpart, `future.forward` transfers both ends out of the calling
instance and returns immediately with no result, so it takes neither
an `async` immediate nor any `canonopt`s, since the value does not
pass through the caller's linear memory.

The binary encoding uses opcode 0x2f as assigned in the proposed
specification change, and validation gates the built-in behind the
component model async and "more async builtins" features.

Assisted-by: claude:claude-fable-5
Recognize the `[stream-forward-N]` and `[future-forward-N]` mangled core
import names in `wit-component` and wire them up to the corresponding
`canon stream.forward` and `canon future.forward` built-ins when
componentizing, following the same `prefixed_payload` pattern as the
`drop-readable`/`drop-writable` intrinsics: `forward` takes no
`canonopt`s and no `async` immediate, so no shim or memory plumbing is
required and the built-in can be materialized directly.

Also add `Forward` variants to `wit-parser`'s `StreamIntrinsic` and
`FutureIntrinsic` name-mangling helpers so that bindings generators can
emit the new intrinsic imports via `Resolve::wasm_import_name`.

Assisted-by: claude:claude-fable-5
The `{stream,future}.forward` built-ins have now been merged into the
component model specification (WebAssembly/component-model#717) as
their own ➡️-gated feature rather than as part of the "more async
builtins" feature. Add a matching `cm_forward` flag to `WasmFeatures`,
gate validation of both built-ins on it, and drop the notes describing
them as experimental now that they are part of the spec.

Also re-bless the `print` snapshots for the forward tests, which went
stale after rebasing over the printer change that now emits `(param
...)` for imported core functions.

Assisted-by: claude:claude-fable-5-1
Signed-off-by: Roman Volosatovs <rvolosatovs@riseup.net>
Pull in the upstream `test/async/forward.wast` test for the
`{stream,future}.forward` built-ins and regenerate the spec test
wrappers and snapshots.

Assisted-by: claude:claude-fable-5-1
Signed-off-by: Roman Volosatovs <rvolosatovs@riseup.net>
Dummy modules generated for async exports now import the
`[stream-forward-N]` and `[future-forward-N]` intrinsics alongside the
other stream/future intrinsics, so the forward name-mangling and encoding
paths are exercised by `component embed --dummy`. The affected CLI tests
enable `cm-forward` when validating.

Signed-off-by: Roman Volosatovs <rvolosatovs@riseup.net>
@rvolosatovs
rvolosatovs marked this pull request as ready for review September 21, 2026 18:58
@rvolosatovs
rvolosatovs requested a review from a team as a code owner September 21, 2026 18:58
@rvolosatovs
rvolosatovs requested review from alexcrichton and removed request for a team September 21, 2026 18:58
@alexcrichton
alexcrichton added this pull request to the merge queue Sep 21, 2026
@alexcrichton

Copy link
Copy Markdown
Member

Thanks!

Merged via the queue into bytecodealliance:main with commit 1b5b4e2 Sep 21, 2026
37 checks passed
@rvolosatovs
rvolosatovs deleted the feat/stream-forward branch September 22, 2026 15:04
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.

2 participants