Skip to content

Add 'stream' and 'future' types - #405

Merged
lukewagner merged 22 commits into
mainfrom
add-stream
Nov 7, 2024
Merged

Add 'stream' and 'future' types#405
lukewagner merged 22 commits into
mainfrom
add-stream

Conversation

@lukewagner

Copy link
Copy Markdown
Member

This PR builds on #363 to add future and stream type constructors along with the associated canon built-ins ({stream,future}.new, {stream,future}.{read,write}, {stream,future}.cancel-{read,write}). It also generalizes the "async_subtasks" table to also hold futures and streams, renaming it to be the "waitables" table and renaming subtask.drop to waitable.drop. Lastly, a new canonopt called always-task-return is added so that sync-lifted exports can use task.return to return their value, which you need if you want to return a stream or future from a synchronous function.

I'd suggest reading the new text in Explainer.md/Binary to get a short overview of the concrete syntactic/binary additions, then Async.md to get the high-level summary, then CanonicalABI.md to get the full details.

Comment threaddesign/mvp/Async.md
Comment threaddesign/mvp/Async.md Outdated
Comment threaddesign/mvp/Binary.md Outdated
Comment threaddesign/mvp/Explainer.md Outdated
Comment threaddesign/mvp/Explainer.md Outdated
Comment threaddesign/mvp/CanonicalABI.md Outdated
Comment threaddesign/mvp/Binary.md Outdated
Comment threaddesign/mvp/Binary.md Outdated
Comment threaddesign/mvp/Async.md
Comment threaddesign/mvp/Async.md Outdated
Comment threaddesign/mvp/Async.md
Comment threaddesign/mvp/Async.md Outdated
Comment threaddesign/mvp/Explainer.md
Comment threaddesign/mvp/Binary.md Outdated
Comment threaddesign/mvp/canonical-abi/definitions.py
@dicej

Copy link
Copy Markdown
Collaborator

An earlier version of the design had separate drop built-in functions for the readable and writable ends of streams and futures, e.g. {stream|future}.drop-{reader|writer}, and the ABI included a t:<typeidx> for each of those, allowing tools and host implementations to know statically what specific type to expect, just like we've done for {stream|future}.{read|write|new}.

For symmetry with the rest of the built-ins, could we split waitable.drop back into subtask.drop and {stream|future}.drop-{reader|writer}? That would also make it clearer that {stream|future|.drop-writer can take an optional error parameter, but {stream|future}.drop-reader cannot.

@lukewagner

Copy link
Copy Markdown
MemberAuthor

@dicej Great point, and agreed. Split back up in this commit.

Comment threaddesign/mvp/Explainer.md
@lukewagner

Copy link
Copy Markdown
MemberAuthor

For visibility: this commit adds error and its associated canon built-ins, closing the TODOs in the original PR.

Comment threaddesign/mvp/CanonicalABI.md
Comment threaddesign/mvp/Explainer.md
@lukewagner

Copy link
Copy Markdown
MemberAuthor

Thanks for all the excellent feedback everyone! I think the comments are dying down and it sounds like this is on a convergence path with @dicej's impl, so if nothing new pops up, I think I'll merge mid next week (and then we can continue to iterate on async in new issues and PRs).

FWIW, I think the next change I'd like to make is a PR that removes the DONE state from subtasks, which should simplify things and allow bindings for async borrows to make sense, and, after that, go through the top bullets of Async.md#TODO.

Comment threaddesign/mvp/Binary.md Outdated
@lukewagner

Copy link
Copy Markdown
MemberAuthor

One other update: for both the pragmatic short-term benefit of avoiding parsing conflicts with the error resource type (defined by wasi:io/error) and, more generally, to help make it clear that it's just meant to convey non-deterministic, debugging-oriented contextual data, this commit renames error to error-context. This also nicely distinguishes error-context from the error case of the result variant (which contains the "whole" error value, including the WIT-defined error payload value).

dicej added a commit to dicej/wasm-tools that referenced this pull request Nov 5, 2024
This adds support for encoding and parsing components which use the [Async
ABI](https://github.com/WebAssembly/component-model/blob/main/design/mvp/Async.md)
and associated canonical options and functions, along with the [`stream`,
`future`, and `error`](WebAssembly/component-model#405)
types.
Note that the `error` type was recently (about 30 minutes ago) renamed to
`error-context` in Luke's spec PR. I haven't updated this implementation to
reflect that yet, but will do so in a follow-up commit. That should allow us to
avoid conflicts with existing WIT files that use `error` as a type and/or
interface name.
This does not include any new tests; I'll also add those in a follow-up commit.
See bytecodealliance/rfcs#38 for more context.
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
dicej added a commit to dicej/wit-bindgen that referenced this pull request Nov 6, 2024
This adds support for generating bindings which use the [Async
ABI](https://github.com/WebAssembly/component-model/blob/main/design/mvp/Async.md)
along with the [`stream`, `future`, and
`error-context`](WebAssembly/component-model#405) types.
By default, normal synchronous bindings are generated, but the user may opt-in
to async bindings for all or some of the imported and/or exported functions in
the target world and interfaces -- provided the default-enabled `async` feature
is enabled.
In addition, we generate `StreamPayload` and/or `FuturePayload` trait
implementations for any types appearing as the `T` in `stream<T>` or `future<T>`
in the WIT files, respectively. That enables user code to call `new_stream` or
`new_future` to create `stream`s or `future`s with those payload types, then
write to them, read from them, and/or pass the readable end as a parameter to a
component import or return value of a component export.
Note that I've added new `core::abi::Instruction` enum variants to handle async
lifting and lowering, but they're currently tailored to the Rust generator and
will probably change somewhat as we add support for other languages.
This does not include any new tests; I'll add those in a follow-up commit.
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
dicej added a commit to dicej/wasmtime that referenced this pull request Nov 7, 2024
This adds support for loading, compiling, linking, and running components which
use the [Async
ABI](https://github.com/WebAssembly/component-model/blob/main/design/mvp/Async.md)
along with the [`stream`, `future`, and
`error-context`](WebAssembly/component-model#405) types.
It also adds support for generating host bindings such that multiple host
functions can be run concurrently with guest tasks -- without monopolizing the
`Store`.
See the [implementation RFC](bytecodealliance/rfcs#38)
for details, as well as [this
repo](https://github.com/dicej/component-async-demo) containing end-to-end smoke
tests.
This is very much a work-in progress, with a number of tasks remaining:
- [ ] Avoid exposing global task IDs to guests and use per-instance IDs instead
- [ ] Track `task.return` type during compilation and assert the actual and expected types match at runtime
- [ ] Ensure all guest pointers are bounds-checked when lifting, lowering, or copying values
- [ ] Reduce code duplication in `wasmtime_cranelift::compiler::component`
- [ ] Add support for `(Typed)Func::call_concurrent` per the RFC
- [ ] Add support for multiplexing stream/future reads/writes and concurrent calls to guest exports per the RFC
- [ ] Refactor, clean up, and unify handling of backpressure, yields, and even polling
- [ ] Guard against reentrance where required (e.g. in certain fused adapter calls)
- [ ] Add integration test cases covering new functionality to tests/all/component_model (starting by porting over the tests in https://github.com/dicej/component-async-demo)
- [ ] Add binding generation test cases to crates/component-macro/tests
- [ ] Add WAST tests to tests/misc_testsuite/component-model
- [ ] Add support and test coverage for callback-less async functions (e.g. goroutines)
- [ ] Switch to back to upstream `wasm-tools` once bytecodealliance/wasm-tools#1895 has been merged and released
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
dicej added a commit to dicej/wasmtime that referenced this pull request Nov 7, 2024
This adds support for loading, compiling, linking, and running components which
use the [Async
ABI](https://github.com/WebAssembly/component-model/blob/main/design/mvp/Async.md)
along with the [`stream`, `future`, and
`error-context`](WebAssembly/component-model#405) types.
It also adds support for generating host bindings such that multiple host
functions can be run concurrently with guest tasks -- without monopolizing the
`Store`.
See the [implementation RFC](bytecodealliance/rfcs#38)
for details, as well as [this
repo](https://github.com/dicej/component-async-demo) containing end-to-end smoke
tests.
This is very much a work-in progress, with a number of tasks remaining:
- [ ] Avoid exposing global task IDs to guests and use per-instance IDs instead
- [ ] Track `task.return` type during compilation and assert the actual and expected types match at runtime
- [ ] Ensure all guest pointers are bounds-checked when lifting, lowering, or copying values
- [ ] Reduce code duplication in `wasmtime_cranelift::compiler::component`
- [ ] Reduce code duplication between `StoreContextMut::on_fiber` and `concurrent::on_fiber`
- [ ] Minimize and/or document the use of unsafe code
- [ ] Add support for `(Typed)Func::call_concurrent` per the RFC
- [ ] Add support for multiplexing stream/future reads/writes and concurrent calls to guest exports per the RFC
- [ ] Refactor, clean up, and unify handling of backpressure, yields, and even polling
- [ ] Guard against reentrance where required (e.g. in certain fused adapter calls)
- [ ] Add integration test cases covering new functionality to tests/all/component_model (starting by porting over the tests in https://github.com/dicej/component-async-demo)
- [ ] Add binding generation test cases to crates/component-macro/tests
- [ ] Add WAST tests to tests/misc_testsuite/component-model
- [ ] Add support and test coverage for callback-less async functions (e.g. goroutines)
- [ ] Switch to back to upstream `wasm-tools` once bytecodealliance/wasm-tools#1895 has been merged and released
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
dicej added a commit to dicej/wasmtime that referenced this pull request Dec 20, 2024
This adds support for loading, compiling, linking, and running components which
use the [Async
ABI](https://github.com/WebAssembly/component-model/blob/main/design/mvp/Async.md)
along with the [`stream`, `future`, and
`error-context`](WebAssembly/component-model#405) types.
It also adds support for generating host bindings such that multiple host
functions can be run concurrently with guest tasks -- without monopolizing the
`Store`.
See the [implementation RFC](bytecodealliance/rfcs#38)
for details, as well as [this
repo](https://github.com/dicej/component-async-demo) containing end-to-end smoke
tests.
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
fix clippy warnings and bench/fuzzing errors
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
revert atomic.wit whitespace change
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
fix build when component-model disabled
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
bless component-macro expected output
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
fix no-std build error
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
fix build with --no-default-features --features runtime,component-model
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
partly fix no-std build
It's still broken due to the use of `std::collections::HashMap` in
crates/wasmtime/src/runtime/vm/component.rs. I'll address that as part of the
work to avoid exposing global task/future/stream/error-context handles to
guests.
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
maintain per-instance tables for futures, streams, and error-contexts
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
refactor task/stream/future handle lifting/lowering
This addresses a couple of issues:
- Previously, we were passing task/stream/future/error-context reps directly to
instances while keeping track of which instance had access to which rep. That
worked fine in that there was no way to forge access to inaccessible reps, but
it leaked information about what other instances were doing. Now we maintain
per-instance waitable and error-context tables which map the reps to and from
the handles which the instance sees.
- The `no_std` build was broken due to use of `HashMap` in
`runtime::vm::component`, which is now fixed.
Note that we use one single table per instance for all tasks, streams, and
futures. This is partly necessary because, when async events are delivered to
the guest, it wouldn't have enough context to know which stream or future we're
talking about if each unique stream and future type had its own table. So at
minimum, we need to use the same table for all streams (regardless of payload
type), and likewise for futures. Also, per
WebAssembly/component-model#395 (comment),
the plan is to move towards a shared table for all resource types as well, so
this moves us in that direction.
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
fix wave breakage due to new stream/future/error-context types
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
switch wasm-tools to v1.220.0-based branch
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
check `task.return` type at runtime
We can't statically verify a given call to `task.return` corresponds to the
expected core signature appropriate for the currently running task, so we must
do so at runtime. In order to make that check efficient, we intern the types.
My initial plan was to use `ModuleInternedTypeIndex` and/or `VMSharedTypeIndex`
for interning, but that got hairy with WasmGC considerations, so instead I added
new fields to `ComponentTypes` and `ComponentTypesBuilder`.
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
add `TypedFunc::call_concurrent` and refine stream/future APIs
This implements what I proposed in https://github.com/dicej/rfcs/blob/component-async/accepted/component-model-async.md#wasmtime. Specifically, it adds:
- A new `Promise` type, useful for working with concurrent operations that require access to a `Store` to make progress.
- A new `PromisesUnordered` type for `await`ing multiple promises concurrently
-`TypedFunc::call_concurrent` (which returns a `Promise`), allowing multiple host->guest calls to run concurrently on the same instance.
- Updated `{Stream|Future}{Writer|Reader}` APIs which use `Promise`
The upshot is that the embedder can now ergonomically manage arbitrary numbers
of concurrent operations. Previously, this was a lot more difficult to do
without accidentally starving some of the operations due to another one
monopolizing the `Store`.
Finally, this includes various refactorings and fixes for bugs exposed by the
newer, more versatile APIs.
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
clean up verbosity in component/func.rs
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
snapshot
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
implement stream/future read/write cancellation
This required a somewhat viral addition of `Send` and `Sync` bounds for async
host function closure types, unfortunately.
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
add `Func::call_concurrent` and `LinkerInstance::func_new_concurrent`
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
dynamic API support for streams/futures/error-contexts
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
support callback-less (AKA stackful) async lifts
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
fix `call_host` regression
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
add component model async end-to-end tests
I've ported these over from https://github.com/dicej/component-async-demo
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
fix test regressions and clippy warnings
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
satisfy clippy
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
dicej added a commit to dicej/wasmtime that referenced this pull request Jan 2, 2025
This adds support for loading, compiling, linking, and running components which
use the [Async
ABI](https://github.com/WebAssembly/component-model/blob/main/design/mvp/Async.md)
along with the [`stream`, `future`, and
`error-context`](WebAssembly/component-model#405) types.
It also adds support for generating host bindings such that multiple host
functions can be run concurrently with guest tasks -- without monopolizing the
`Store`.
See the [implementation RFC](bytecodealliance/rfcs#38)
for details, as well as [this
repo](https://github.com/dicej/component-async-demo) containing end-to-end smoke
tests.
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
fix clippy warnings and bench/fuzzing errors
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
revert atomic.wit whitespace change
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
fix build when component-model disabled
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
bless component-macro expected output
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
fix no-std build error
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
fix build with --no-default-features --features runtime,component-model
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
partly fix no-std build
It's still broken due to the use of `std::collections::HashMap` in
crates/wasmtime/src/runtime/vm/component.rs. I'll address that as part of the
work to avoid exposing global task/future/stream/error-context handles to
guests.
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
maintain per-instance tables for futures, streams, and error-contexts
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
refactor task/stream/future handle lifting/lowering
This addresses a couple of issues:
- Previously, we were passing task/stream/future/error-context reps directly to
instances while keeping track of which instance had access to which rep. That
worked fine in that there was no way to forge access to inaccessible reps, but
it leaked information about what other instances were doing. Now we maintain
per-instance waitable and error-context tables which map the reps to and from
the handles which the instance sees.
- The `no_std` build was broken due to use of `HashMap` in
`runtime::vm::component`, which is now fixed.
Note that we use one single table per instance for all tasks, streams, and
futures. This is partly necessary because, when async events are delivered to
the guest, it wouldn't have enough context to know which stream or future we're
talking about if each unique stream and future type had its own table. So at
minimum, we need to use the same table for all streams (regardless of payload
type), and likewise for futures. Also, per
WebAssembly/component-model#395 (comment),
the plan is to move towards a shared table for all resource types as well, so
this moves us in that direction.
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
fix wave breakage due to new stream/future/error-context types
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
switch wasm-tools to v1.220.0-based branch
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
check `task.return` type at runtime
We can't statically verify a given call to `task.return` corresponds to the
expected core signature appropriate for the currently running task, so we must
do so at runtime. In order to make that check efficient, we intern the types.
My initial plan was to use `ModuleInternedTypeIndex` and/or `VMSharedTypeIndex`
for interning, but that got hairy with WasmGC considerations, so instead I added
new fields to `ComponentTypes` and `ComponentTypesBuilder`.
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
add `TypedFunc::call_concurrent` and refine stream/future APIs
This implements what I proposed in https://github.com/dicej/rfcs/blob/component-async/accepted/component-model-async.md#wasmtime. Specifically, it adds:
- A new `Promise` type, useful for working with concurrent operations that require access to a `Store` to make progress.
- A new `PromisesUnordered` type for `await`ing multiple promises concurrently
-`TypedFunc::call_concurrent` (which returns a `Promise`), allowing multiple host->guest calls to run concurrently on the same instance.
- Updated `{Stream|Future}{Writer|Reader}` APIs which use `Promise`
The upshot is that the embedder can now ergonomically manage arbitrary numbers
of concurrent operations. Previously, this was a lot more difficult to do
without accidentally starving some of the operations due to another one
monopolizing the `Store`.
Finally, this includes various refactorings and fixes for bugs exposed by the
newer, more versatile APIs.
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
clean up verbosity in component/func.rs
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
snapshot
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
implement stream/future read/write cancellation
This required a somewhat viral addition of `Send` and `Sync` bounds for async
host function closure types, unfortunately.
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
add `Func::call_concurrent` and `LinkerInstance::func_new_concurrent`
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
dynamic API support for streams/futures/error-contexts
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
support callback-less (AKA stackful) async lifts
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
fix `call_host` regression
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
add component model async end-to-end tests
I've ported these over from https://github.com/dicej/component-async-demo
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
fix test regressions and clippy warnings
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
satisfy clippy
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
fix async tests when `component-model-async` enabled
Enabling this feature for all tests revealed various missing pieces in the new
`concurrent.rs` fiber mechanism, which I've addressed.
This adds a bunch of ugly `#[cfg(feature = "component-model-async")]` guards,
but those will all go away once I unify the two async fiber implementations.
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
dicej added a commit to dicej/wasmtime that referenced this pull request Jan 6, 2025
This adds support for loading, compiling, linking, and running components which
use the [Async
ABI](https://github.com/WebAssembly/component-model/blob/main/design/mvp/Async.md)
along with the [`stream`, `future`, and
`error-context`](WebAssembly/component-model#405) types.
It also adds support for generating host bindings such that multiple host
functions can be run concurrently with guest tasks -- without monopolizing the
`Store`.
See the [implementation RFC](bytecodealliance/rfcs#38)
for details, as well as [this
repo](https://github.com/dicej/component-async-demo) containing end-to-end smoke
tests.
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
fix clippy warnings and bench/fuzzing errors
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
revert atomic.wit whitespace change
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
fix build when component-model disabled
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
bless component-macro expected output
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
fix no-std build error
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
fix build with --no-default-features --features runtime,component-model
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
partly fix no-std build
It's still broken due to the use of `std::collections::HashMap` in
crates/wasmtime/src/runtime/vm/component.rs. I'll address that as part of the
work to avoid exposing global task/future/stream/error-context handles to
guests.
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
maintain per-instance tables for futures, streams, and error-contexts
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
refactor task/stream/future handle lifting/lowering
This addresses a couple of issues:
- Previously, we were passing task/stream/future/error-context reps directly to
instances while keeping track of which instance had access to which rep. That
worked fine in that there was no way to forge access to inaccessible reps, but
it leaked information about what other instances were doing. Now we maintain
per-instance waitable and error-context tables which map the reps to and from
the handles which the instance sees.
- The `no_std` build was broken due to use of `HashMap` in
`runtime::vm::component`, which is now fixed.
Note that we use one single table per instance for all tasks, streams, and
futures. This is partly necessary because, when async events are delivered to
the guest, it wouldn't have enough context to know which stream or future we're
talking about if each unique stream and future type had its own table. So at
minimum, we need to use the same table for all streams (regardless of payload
type), and likewise for futures. Also, per
WebAssembly/component-model#395 (comment),
the plan is to move towards a shared table for all resource types as well, so
this moves us in that direction.
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
fix wave breakage due to new stream/future/error-context types
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
switch wasm-tools to v1.220.0-based branch
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
check `task.return` type at runtime
We can't statically verify a given call to `task.return` corresponds to the
expected core signature appropriate for the currently running task, so we must
do so at runtime. In order to make that check efficient, we intern the types.
My initial plan was to use `ModuleInternedTypeIndex` and/or `VMSharedTypeIndex`
for interning, but that got hairy with WasmGC considerations, so instead I added
new fields to `ComponentTypes` and `ComponentTypesBuilder`.
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
add `TypedFunc::call_concurrent` and refine stream/future APIs
This implements what I proposed in https://github.com/dicej/rfcs/blob/component-async/accepted/component-model-async.md#wasmtime. Specifically, it adds:
- A new `Promise` type, useful for working with concurrent operations that require access to a `Store` to make progress.
- A new `PromisesUnordered` type for `await`ing multiple promises concurrently
-`TypedFunc::call_concurrent` (which returns a `Promise`), allowing multiple host->guest calls to run concurrently on the same instance.
- Updated `{Stream|Future}{Writer|Reader}` APIs which use `Promise`
The upshot is that the embedder can now ergonomically manage arbitrary numbers
of concurrent operations. Previously, this was a lot more difficult to do
without accidentally starving some of the operations due to another one
monopolizing the `Store`.
Finally, this includes various refactorings and fixes for bugs exposed by the
newer, more versatile APIs.
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
clean up verbosity in component/func.rs
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
snapshot
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
implement stream/future read/write cancellation
This required a somewhat viral addition of `Send` and `Sync` bounds for async
host function closure types, unfortunately.
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
add `Func::call_concurrent` and `LinkerInstance::func_new_concurrent`
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
dynamic API support for streams/futures/error-contexts
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
support callback-less (AKA stackful) async lifts
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
fix `call_host` regression
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
add component model async end-to-end tests
I've ported these over from https://github.com/dicej/component-async-demo
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
fix test regressions and clippy warnings
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
satisfy clippy
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
fix async tests when `component-model-async` enabled
Enabling this feature for all tests revealed various missing pieces in the new
`concurrent.rs` fiber mechanism, which I've addressed.
This adds a bunch of ugly `#[cfg(feature = "component-model-async")]` guards,
but those will all go away once I unify the two async fiber implementations.
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
add and modify tests to cover concurrent APIs
Primarily, this tests and implements cases where parameters and/or results must
be passed via linear memory instead of the stack.
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
`concurrent_{imports|exports}` component macro codegen tests
This enables codegen testing of the `concurrent_imports` and
`concurrent_exports` options to `wasmtime::component::bindgen` and also fixes
code generation for world-level function and resource exports that use the
concurrent call style.
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
`concurrent_{imports|exports}` component macro expanded tests
This enables testing of the `concurrent_imports` and `concurrent_exports`
options in `crates/component-macro/tests/expanded.rs`.
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
add tests/misc_testsuite/component-model-async/*.wast
These only test instantiation of components which use various async options and
built-ins so far. Next, I'll happy and sad path tests which actually execute
code.
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
appease clippy
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
add tests/misc_testsuite/component-model-async/fused.wast
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
add non-panicking bounds checks where appropriate
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
dicej added a commit to dicej/wit-bindgen that referenced this pull request Jan 7, 2025
This adds support for generating bindings which use the [Async
ABI](https://github.com/WebAssembly/component-model/blob/main/design/mvp/Async.md)
along with the [`stream`, `future`, and
`error-context`](WebAssembly/component-model#405) types.
By default, normal synchronous bindings are generated, but the user may opt-in
to async bindings for all or some of the imported and/or exported functions in
the target world and interfaces -- provided the default-enabled `async` feature
is enabled.
In addition, we generate `StreamPayload` and/or `FuturePayload` trait
implementations for any types appearing as the `T` in `stream<T>` or `future<T>`
in the WIT files, respectively. That enables user code to call `new_stream` or
`new_future` to create `stream`s or `future`s with those payload types, then
write to them, read from them, and/or pass the readable end as a parameter to a
component import or return value of a component export.
Note that I've added new `core::abi::Instruction` enum variants to handle async
lifting and lowering, but they're currently tailored to the Rust generator and
will probably change somewhat as we add support for other languages.
This does not include any new tests; I'll add those in a follow-up commit.
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
add `async: true` case to Rust `codegen_tests`
This ensures that all the codegen test WIT files produce compile-able bindings
with `async: true` (i.e. all imports lowered and all exports lifted using the
async ABI). That revealed some issues involving resource methods and
constructors, as well as missing stub support, which I've resolved.
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
add codegen tests for futures, streams, and error-contexts
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
remove async_support::poll_future
It was both unsafe to use and intended only for testing (and not even good for
that, it turns out).
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
add stream/future read/write cancellation support
Also, fix some issues with stream/future payload lifting/lowering which I
_thought_ I had already tested but actually hadn't.
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
support callback-less (AKA stackful) async lifts
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
revert incorrect test change in flavorful/wasm.rs
I had thoughtlessly removed test code based on a clippy warning, not realizing
it was testing (at compile time) that the generated types implemented `Debug`.
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
test `async: true` option in Rust codegen tests
I had meant to do this originally, but apparently forgot to actually use the
option.
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
add docs for new `debug` and `async` Rust macro options
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
address `cargo check` lifetime warning
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
minimize use of features based on PR feedback
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
dicej added a commit to dicej/wit-bindgen that referenced this pull request Jan 7, 2025
This adds support for generating bindings which use the [Async
ABI](https://github.com/WebAssembly/component-model/blob/main/design/mvp/Async.md)
along with the [`stream`, `future`, and
`error-context`](WebAssembly/component-model#405) types.
By default, normal synchronous bindings are generated, but the user may opt-in
to async bindings for all or some of the imported and/or exported functions in
the target world and interfaces -- provided the default-enabled `async` feature
is enabled.
In addition, we generate `StreamPayload` and/or `FuturePayload` trait
implementations for any types appearing as the `T` in `stream<T>` or `future<T>`
in the WIT files, respectively. That enables user code to call `new_stream` or
`new_future` to create `stream`s or `future`s with those payload types, then
write to them, read from them, and/or pass the readable end as a parameter to a
component import or return value of a component export.
Note that I've added new `core::abi::Instruction` enum variants to handle async
lifting and lowering, but they're currently tailored to the Rust generator and
will probably change somewhat as we add support for other languages.
This does not include any new tests; I'll add those in a follow-up commit.
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
add `async: true` case to Rust `codegen_tests`
This ensures that all the codegen test WIT files produce compile-able bindings
with `async: true` (i.e. all imports lowered and all exports lifted using the
async ABI). That revealed some issues involving resource methods and
constructors, as well as missing stub support, which I've resolved.
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
add codegen tests for futures, streams, and error-contexts
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
remove async_support::poll_future
It was both unsafe to use and intended only for testing (and not even good for
that, it turns out).
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
add stream/future read/write cancellation support
Also, fix some issues with stream/future payload lifting/lowering which I
_thought_ I had already tested but actually hadn't.
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
support callback-less (AKA stackful) async lifts
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
revert incorrect test change in flavorful/wasm.rs
I had thoughtlessly removed test code based on a clippy warning, not realizing
it was testing (at compile time) that the generated types implemented `Debug`.
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
test `async: true` option in Rust codegen tests
I had meant to do this originally, but apparently forgot to actually use the
option.
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
add docs for new `debug` and `async` Rust macro options
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
address `cargo check` lifetime warning
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
minimize use of features based on PR feedback
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
github-merge-queueBot pushed a commit to bytecodealliance/wit-bindgen that referenced this pull request Jan 8, 2025
* Add support for async/streams/futures to Rust generator
This adds support for generating bindings which use the [Async
ABI](https://github.com/WebAssembly/component-model/blob/main/design/mvp/Async.md)
along with the [`stream`, `future`, and
`error-context`](WebAssembly/component-model#405) types.
By default, normal synchronous bindings are generated, but the user may opt-in
to async bindings for all or some of the imported and/or exported functions in
the target world and interfaces -- provided the default-enabled `async` feature
is enabled.
In addition, we generate `StreamPayload` and/or `FuturePayload` trait
implementations for any types appearing as the `T` in `stream<T>` or `future<T>`
in the WIT files, respectively. That enables user code to call `new_stream` or
`new_future` to create `stream`s or `future`s with those payload types, then
write to them, read from them, and/or pass the readable end as a parameter to a
component import or return value of a component export.
Note that I've added new `core::abi::Instruction` enum variants to handle async
lifting and lowering, but they're currently tailored to the Rust generator and
will probably change somewhat as we add support for other languages.
This does not include any new tests; I'll add those in a follow-up commit.
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
add `async: true` case to Rust `codegen_tests`
This ensures that all the codegen test WIT files produce compile-able bindings
with `async: true` (i.e. all imports lowered and all exports lifted using the
async ABI). That revealed some issues involving resource methods and
constructors, as well as missing stub support, which I've resolved.
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
add codegen tests for futures, streams, and error-contexts
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
remove async_support::poll_future
It was both unsafe to use and intended only for testing (and not even good for
that, it turns out).
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
add stream/future read/write cancellation support
Also, fix some issues with stream/future payload lifting/lowering which I
_thought_ I had already tested but actually hadn't.
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
support callback-less (AKA stackful) async lifts
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
revert incorrect test change in flavorful/wasm.rs
I had thoughtlessly removed test code based on a clippy warning, not realizing
it was testing (at compile time) that the generated types implemented `Debug`.
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
test `async: true` option in Rust codegen tests
I had meant to do this originally, but apparently forgot to actually use the
option.
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
add docs for new `debug` and `async` Rust macro options
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
address `cargo check` lifetime warning
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
minimize use of features based on PR feedback
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
* add comment explaining lack of recursion in `type_id_info`
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
* refactor stream and future support for Rust generator
Per a discussion with Alex, this moves most of the stream and future code into
the `wit-bindgen-rt` crate. That's where I had intended to put it to begin
with, but ran into orphan rule issues given the trait-based approach I was
using.
The new approach uses dynamic dispatch via a vtable type. Thus we've traded a
small (theoretical) amount of performance for much better compatibility in cases
of separately-generated bindings (e.g. passing `FutureWriter<T>` between crates
should work fine now), easier debugging, etc.
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
* break `streams_and_futures` into two modules
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
* restore previously-removed feature check in Rust macro
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
---------
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
dicej added a commit to dicej/wasmtime that referenced this pull request Jan 10, 2025
This adds support for loading, compiling, linking, and running components which
use the [Async
ABI](https://github.com/WebAssembly/component-model/blob/main/design/mvp/Async.md)
along with the [`stream`, `future`, and
`error-context`](WebAssembly/component-model#405) types.
It also adds support for generating host bindings such that multiple host
functions can be run concurrently with guest tasks -- without monopolizing the
`Store`.
See the [implementation RFC](bytecodealliance/rfcs#38)
for details, as well as [this
repo](https://github.com/dicej/component-async-demo) containing end-to-end smoke
tests.
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
fix clippy warnings and bench/fuzzing errors
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
revert atomic.wit whitespace change
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
fix build when component-model disabled
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
bless component-macro expected output
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
fix no-std build error
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
fix build with --no-default-features --features runtime,component-model
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
partly fix no-std build
It's still broken due to the use of `std::collections::HashMap` in
crates/wasmtime/src/runtime/vm/component.rs. I'll address that as part of the
work to avoid exposing global task/future/stream/error-context handles to
guests.
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
maintain per-instance tables for futures, streams, and error-contexts
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
refactor task/stream/future handle lifting/lowering
This addresses a couple of issues:
- Previously, we were passing task/stream/future/error-context reps directly to
instances while keeping track of which instance had access to which rep. That
worked fine in that there was no way to forge access to inaccessible reps, but
it leaked information about what other instances were doing. Now we maintain
per-instance waitable and error-context tables which map the reps to and from
the handles which the instance sees.
- The `no_std` build was broken due to use of `HashMap` in
`runtime::vm::component`, which is now fixed.
Note that we use one single table per instance for all tasks, streams, and
futures. This is partly necessary because, when async events are delivered to
the guest, it wouldn't have enough context to know which stream or future we're
talking about if each unique stream and future type had its own table. So at
minimum, we need to use the same table for all streams (regardless of payload
type), and likewise for futures. Also, per
WebAssembly/component-model#395 (comment),
the plan is to move towards a shared table for all resource types as well, so
this moves us in that direction.
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
fix wave breakage due to new stream/future/error-context types
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
switch wasm-tools to v1.220.0-based branch
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
check `task.return` type at runtime
We can't statically verify a given call to `task.return` corresponds to the
expected core signature appropriate for the currently running task, so we must
do so at runtime. In order to make that check efficient, we intern the types.
My initial plan was to use `ModuleInternedTypeIndex` and/or `VMSharedTypeIndex`
for interning, but that got hairy with WasmGC considerations, so instead I added
new fields to `ComponentTypes` and `ComponentTypesBuilder`.
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
add `TypedFunc::call_concurrent` and refine stream/future APIs
This implements what I proposed in https://github.com/dicej/rfcs/blob/component-async/accepted/component-model-async.md#wasmtime. Specifically, it adds:
- A new `Promise` type, useful for working with concurrent operations that require access to a `Store` to make progress.
- A new `PromisesUnordered` type for `await`ing multiple promises concurrently
-`TypedFunc::call_concurrent` (which returns a `Promise`), allowing multiple host->guest calls to run concurrently on the same instance.
- Updated `{Stream|Future}{Writer|Reader}` APIs which use `Promise`
The upshot is that the embedder can now ergonomically manage arbitrary numbers
of concurrent operations. Previously, this was a lot more difficult to do
without accidentally starving some of the operations due to another one
monopolizing the `Store`.
Finally, this includes various refactorings and fixes for bugs exposed by the
newer, more versatile APIs.
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
clean up verbosity in component/func.rs
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
snapshot
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
implement stream/future read/write cancellation
This required a somewhat viral addition of `Send` and `Sync` bounds for async
host function closure types, unfortunately.
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
add `Func::call_concurrent` and `LinkerInstance::func_new_concurrent`
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
dynamic API support for streams/futures/error-contexts
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
support callback-less (AKA stackful) async lifts
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
fix `call_host` regression
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
add component model async end-to-end tests
I've ported these over from https://github.com/dicej/component-async-demo
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
fix test regressions and clippy warnings
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
satisfy clippy
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
fix async tests when `component-model-async` enabled
Enabling this feature for all tests revealed various missing pieces in the new
`concurrent.rs` fiber mechanism, which I've addressed.
This adds a bunch of ugly `#[cfg(feature = "component-model-async")]` guards,
but those will all go away once I unify the two async fiber implementations.
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
add and modify tests to cover concurrent APIs
Primarily, this tests and implements cases where parameters and/or results must
be passed via linear memory instead of the stack.
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
`concurrent_{imports|exports}` component macro codegen tests
This enables codegen testing of the `concurrent_imports` and
`concurrent_exports` options to `wasmtime::component::bindgen` and also fixes
code generation for world-level function and resource exports that use the
concurrent call style.
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
`concurrent_{imports|exports}` component macro expanded tests
This enables testing of the `concurrent_imports` and `concurrent_exports`
options in `crates/component-macro/tests/expanded.rs`.
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
add tests/misc_testsuite/component-model-async/*.wast
These only test instantiation of components which use various async options and
built-ins so far. Next, I'll happy and sad path tests which actually execute
code.
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
appease clippy
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
add tests/misc_testsuite/component-model-async/fused.wast
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
add non-panicking bounds checks where appropriate
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
remove post-return bits from async result lift code
...at least until we've determined whether post-return options even make sense
for async-lifted exports.
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
fix component-model-async/fused.wast test failure
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
use `enum` types to represent status and event codes
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
fix component-model-async/fused.wast test failure (2nd try)
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
use `gc_types = true` in component-model-async/fused.wast
We use `Instruction::RefFunc` when generating adapters for async lifts and/or
lowers, which Winch doesn't understand, and apparently `gc_types = true` is what
tells the test infra not to use Winch.
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
trap if async function finishes without calling `task.return`
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
update wit-bindgen and fix rebase damage
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
call post-return function if any for async->sync fused calls
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
dicej added a commit to dicej/wasmtime that referenced this pull request Jan 10, 2025
This adds support for loading, compiling, linking, and running components which
use the [Async
ABI](https://github.com/WebAssembly/component-model/blob/main/design/mvp/Async.md)
along with the [`stream`, `future`, and
`error-context`](WebAssembly/component-model#405) types.
It also adds support for generating host bindings such that multiple host
functions can be run concurrently with guest tasks -- without monopolizing the
`Store`.
See the [implementation RFC](bytecodealliance/rfcs#38)
for details, as well as [this
repo](https://github.com/dicej/component-async-demo) containing end-to-end smoke
tests.
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
fix clippy warnings and bench/fuzzing errors
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
revert atomic.wit whitespace change
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
fix build when component-model disabled
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
bless component-macro expected output
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
fix no-std build error
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
fix build with --no-default-features --features runtime,component-model
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
partly fix no-std build
It's still broken due to the use of `std::collections::HashMap` in
crates/wasmtime/src/runtime/vm/component.rs. I'll address that as part of the
work to avoid exposing global task/future/stream/error-context handles to
guests.
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
maintain per-instance tables for futures, streams, and error-contexts
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
refactor task/stream/future handle lifting/lowering
This addresses a couple of issues:
- Previously, we were passing task/stream/future/error-context reps directly to
instances while keeping track of which instance had access to which rep. That
worked fine in that there was no way to forge access to inaccessible reps, but
it leaked information about what other instances were doing. Now we maintain
per-instance waitable and error-context tables which map the reps to and from
the handles which the instance sees.
- The `no_std` build was broken due to use of `HashMap` in
`runtime::vm::component`, which is now fixed.
Note that we use one single table per instance for all tasks, streams, and
futures. This is partly necessary because, when async events are delivered to
the guest, it wouldn't have enough context to know which stream or future we're
talking about if each unique stream and future type had its own table. So at
minimum, we need to use the same table for all streams (regardless of payload
type), and likewise for futures. Also, per
WebAssembly/component-model#395 (comment),
the plan is to move towards a shared table for all resource types as well, so
this moves us in that direction.
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
fix wave breakage due to new stream/future/error-context types
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
switch wasm-tools to v1.220.0-based branch
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
check `task.return` type at runtime
We can't statically verify a given call to `task.return` corresponds to the
expected core signature appropriate for the currently running task, so we must
do so at runtime. In order to make that check efficient, we intern the types.
My initial plan was to use `ModuleInternedTypeIndex` and/or `VMSharedTypeIndex`
for interning, but that got hairy with WasmGC considerations, so instead I added
new fields to `ComponentTypes` and `ComponentTypesBuilder`.
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
add `TypedFunc::call_concurrent` and refine stream/future APIs
This implements what I proposed in https://github.com/dicej/rfcs/blob/component-async/accepted/component-model-async.md#wasmtime. Specifically, it adds:
- A new `Promise` type, useful for working with concurrent operations that require access to a `Store` to make progress.
- A new `PromisesUnordered` type for `await`ing multiple promises concurrently
-`TypedFunc::call_concurrent` (which returns a `Promise`), allowing multiple host->guest calls to run concurrently on the same instance.
- Updated `{Stream|Future}{Writer|Reader}` APIs which use `Promise`
The upshot is that the embedder can now ergonomically manage arbitrary numbers
of concurrent operations. Previously, this was a lot more difficult to do
without accidentally starving some of the operations due to another one
monopolizing the `Store`.
Finally, this includes various refactorings and fixes for bugs exposed by the
newer, more versatile APIs.
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
clean up verbosity in component/func.rs
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
snapshot
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
implement stream/future read/write cancellation
This required a somewhat viral addition of `Send` and `Sync` bounds for async
host function closure types, unfortunately.
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
add `Func::call_concurrent` and `LinkerInstance::func_new_concurrent`
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
dynamic API support for streams/futures/error-contexts
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
support callback-less (AKA stackful) async lifts
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
fix `call_host` regression
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
add component model async end-to-end tests
I've ported these over from https://github.com/dicej/component-async-demo
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
fix test regressions and clippy warnings
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
satisfy clippy
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
fix async tests when `component-model-async` enabled
Enabling this feature for all tests revealed various missing pieces in the new
`concurrent.rs` fiber mechanism, which I've addressed.
This adds a bunch of ugly `#[cfg(feature = "component-model-async")]` guards,
but those will all go away once I unify the two async fiber implementations.
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
add and modify tests to cover concurrent APIs
Primarily, this tests and implements cases where parameters and/or results must
be passed via linear memory instead of the stack.
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
`concurrent_{imports|exports}` component macro codegen tests
This enables codegen testing of the `concurrent_imports` and
`concurrent_exports` options to `wasmtime::component::bindgen` and also fixes
code generation for world-level function and resource exports that use the
concurrent call style.
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
`concurrent_{imports|exports}` component macro expanded tests
This enables testing of the `concurrent_imports` and `concurrent_exports`
options in `crates/component-macro/tests/expanded.rs`.
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
add tests/misc_testsuite/component-model-async/*.wast
These only test instantiation of components which use various async options and
built-ins so far. Next, I'll happy and sad path tests which actually execute
code.
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
appease clippy
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
add tests/misc_testsuite/component-model-async/fused.wast
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
add non-panicking bounds checks where appropriate
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
remove post-return bits from async result lift code
...at least until we've determined whether post-return options even make sense
for async-lifted exports.
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
fix component-model-async/fused.wast test failure
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
use `enum` types to represent status and event codes
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
fix component-model-async/fused.wast test failure (2nd try)
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
use `gc_types = true` in component-model-async/fused.wast
We use `Instruction::RefFunc` when generating adapters for async lifts and/or
lowers, which Winch doesn't understand, and apparently `gc_types = true` is what
tells the test infra not to use Winch.
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
trap if async function finishes without calling `task.return`
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
update wit-bindgen and fix rebase damage
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
call post-return function if any for async->sync fused calls
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
dicej added a commit to dicej/wasmtime that referenced this pull request Jan 16, 2025
This adds support for loading, compiling, linking, and running components which
use the [Async
ABI](https://github.com/WebAssembly/component-model/blob/main/design/mvp/Async.md)
along with the [`stream`, `future`, and
`error-context`](WebAssembly/component-model#405) types.
It also adds support for generating host bindings such that multiple host
functions can be run concurrently with guest tasks -- without monopolizing the
`Store`.
See the [implementation RFC](bytecodealliance/rfcs#38)
for details, as well as [this
repo](https://github.com/dicej/component-async-demo) containing end-to-end smoke
tests.
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
fix clippy warnings and bench/fuzzing errors
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
revert atomic.wit whitespace change
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
fix build when component-model disabled
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
bless component-macro expected output
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
fix no-std build error
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
fix build with --no-default-features --features runtime,component-model
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
partly fix no-std build
It's still broken due to the use of `std::collections::HashMap` in
crates/wasmtime/src/runtime/vm/component.rs. I'll address that as part of the
work to avoid exposing global task/future/stream/error-context handles to
guests.
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
maintain per-instance tables for futures, streams, and error-contexts
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
refactor task/stream/future handle lifting/lowering
This addresses a couple of issues:
- Previously, we were passing task/stream/future/error-context reps directly to
instances while keeping track of which instance had access to which rep. That
worked fine in that there was no way to forge access to inaccessible reps, but
it leaked information about what other instances were doing. Now we maintain
per-instance waitable and error-context tables which map the reps to and from
the handles which the instance sees.
- The `no_std` build was broken due to use of `HashMap` in
`runtime::vm::component`, which is now fixed.
Note that we use one single table per instance for all tasks, streams, and
futures. This is partly necessary because, when async events are delivered to
the guest, it wouldn't have enough context to know which stream or future we're
talking about if each unique stream and future type had its own table. So at
minimum, we need to use the same table for all streams (regardless of payload
type), and likewise for futures. Also, per
WebAssembly/component-model#395 (comment),
the plan is to move towards a shared table for all resource types as well, so
this moves us in that direction.
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
fix wave breakage due to new stream/future/error-context types
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
switch wasm-tools to v1.220.0-based branch
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
check `task.return` type at runtime
We can't statically verify a given call to `task.return` corresponds to the
expected core signature appropriate for the currently running task, so we must
do so at runtime. In order to make that check efficient, we intern the types.
My initial plan was to use `ModuleInternedTypeIndex` and/or `VMSharedTypeIndex`
for interning, but that got hairy with WasmGC considerations, so instead I added
new fields to `ComponentTypes` and `ComponentTypesBuilder`.
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
add `TypedFunc::call_concurrent` and refine stream/future APIs
This implements what I proposed in https://github.com/dicej/rfcs/blob/component-async/accepted/component-model-async.md#wasmtime. Specifically, it adds:
- A new `Promise` type, useful for working with concurrent operations that require access to a `Store` to make progress.
- A new `PromisesUnordered` type for `await`ing multiple promises concurrently
-`TypedFunc::call_concurrent` (which returns a `Promise`), allowing multiple host->guest calls to run concurrently on the same instance.
- Updated `{Stream|Future}{Writer|Reader}` APIs which use `Promise`
The upshot is that the embedder can now ergonomically manage arbitrary numbers
of concurrent operations. Previously, this was a lot more difficult to do
without accidentally starving some of the operations due to another one
monopolizing the `Store`.
Finally, this includes various refactorings and fixes for bugs exposed by the
newer, more versatile APIs.
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
clean up verbosity in component/func.rs
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
snapshot
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
implement stream/future read/write cancellation
This required a somewhat viral addition of `Send` and `Sync` bounds for async
host function closure types, unfortunately.
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
add `Func::call_concurrent` and `LinkerInstance::func_new_concurrent`
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
dynamic API support for streams/futures/error-contexts
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
support callback-less (AKA stackful) async lifts
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
fix `call_host` regression
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
add component model async end-to-end tests
I've ported these over from https://github.com/dicej/component-async-demo
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
fix test regressions and clippy warnings
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
satisfy clippy
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
fix async tests when `component-model-async` enabled
Enabling this feature for all tests revealed various missing pieces in the new
`concurrent.rs` fiber mechanism, which I've addressed.
This adds a bunch of ugly `#[cfg(feature = "component-model-async")]` guards,
but those will all go away once I unify the two async fiber implementations.
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
add and modify tests to cover concurrent APIs
Primarily, this tests and implements cases where parameters and/or results must
be passed via linear memory instead of the stack.
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
`concurrent_{imports|exports}` component macro codegen tests
This enables codegen testing of the `concurrent_imports` and
`concurrent_exports` options to `wasmtime::component::bindgen` and also fixes
code generation for world-level function and resource exports that use the
concurrent call style.
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
`concurrent_{imports|exports}` component macro expanded tests
This enables testing of the `concurrent_imports` and `concurrent_exports`
options in `crates/component-macro/tests/expanded.rs`.
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
add tests/misc_testsuite/component-model-async/*.wast
These only test instantiation of components which use various async options and
built-ins so far. Next, I'll happy and sad path tests which actually execute
code.
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
appease clippy
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
add tests/misc_testsuite/component-model-async/fused.wast
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
add non-panicking bounds checks where appropriate
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
remove post-return bits from async result lift code
...at least until we've determined whether post-return options even make sense
for async-lifted exports.
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
fix component-model-async/fused.wast test failure
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
use `enum` types to represent status and event codes
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
fix component-model-async/fused.wast test failure (2nd try)
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
use `gc_types = true` in component-model-async/fused.wast
We use `Instruction::RefFunc` when generating adapters for async lifts and/or
lowers, which Winch doesn't understand, and apparently `gc_types = true` is what
tells the test infra not to use Winch.
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
trap if async function finishes without calling `task.return`
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
update wit-bindgen and fix rebase damage
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
call post-return function if any for async->sync fused calls
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
fix non-component-model-async build; appease clippy
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
bless bindgen output whitespace changes
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
enforce resource borrow requirements for async calls
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
update `wit-bindgen` and simplify `async_borrowing_callee` test
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
call `InstanceFlags::set_may_enter` where appropriate
There's still more work to do to fully implement (and test) the reentrance rules
for concurrent tasks, but this is a start.
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
finish implementing reentrance checks
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
vados-cosmonic pushed a commit to vados-cosmonic/wasmtime that referenced this pull request Jan 16, 2025
This adds support for loading, compiling, linking, and running components which
use the [Async
ABI](https://github.com/WebAssembly/component-model/blob/main/design/mvp/Async.md)
along with the [`stream`, `future`, and
`error-context`](WebAssembly/component-model#405) types.
It also adds support for generating host bindings such that multiple host
functions can be run concurrently with guest tasks -- without monopolizing the
`Store`.
See the [implementation RFC](bytecodealliance/rfcs#38)
for details, as well as [this
repo](https://github.com/dicej/component-async-demo) containing end-to-end smoke
tests.
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
fix clippy warnings and bench/fuzzing errors
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
revert atomic.wit whitespace change
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
fix build when component-model disabled
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
bless component-macro expected output
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
fix no-std build error
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
fix build with --no-default-features --features runtime,component-model
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
partly fix no-std build
It's still broken due to the use of `std::collections::HashMap` in
crates/wasmtime/src/runtime/vm/component.rs. I'll address that as part of the
work to avoid exposing global task/future/stream/error-context handles to
guests.
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
maintain per-instance tables for futures, streams, and error-contexts
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
refactor task/stream/future handle lifting/lowering
This addresses a couple of issues:
- Previously, we were passing task/stream/future/error-context reps directly to
instances while keeping track of which instance had access to which rep. That
worked fine in that there was no way to forge access to inaccessible reps, but
it leaked information about what other instances were doing. Now we maintain
per-instance waitable and error-context tables which map the reps to and from
the handles which the instance sees.
- The `no_std` build was broken due to use of `HashMap` in
`runtime::vm::component`, which is now fixed.
Note that we use one single table per instance for all tasks, streams, and
futures. This is partly necessary because, when async events are delivered to
the guest, it wouldn't have enough context to know which stream or future we're
talking about if each unique stream and future type had its own table. So at
minimum, we need to use the same table for all streams (regardless of payload
type), and likewise for futures. Also, per
WebAssembly/component-model#395 (comment),
the plan is to move towards a shared table for all resource types as well, so
this moves us in that direction.
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
fix wave breakage due to new stream/future/error-context types
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
switch wasm-tools to v1.220.0-based branch
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
check `task.return` type at runtime
We can't statically verify a given call to `task.return` corresponds to the
expected core signature appropriate for the currently running task, so we must
do so at runtime. In order to make that check efficient, we intern the types.
My initial plan was to use `ModuleInternedTypeIndex` and/or `VMSharedTypeIndex`
for interning, but that got hairy with WasmGC considerations, so instead I added
new fields to `ComponentTypes` and `ComponentTypesBuilder`.
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
add `TypedFunc::call_concurrent` and refine stream/future APIs
This implements what I proposed in https://github.com/dicej/rfcs/blob/component-async/accepted/component-model-async.md#wasmtime. Specifically, it adds:
- A new `Promise` type, useful for working with concurrent operations that require access to a `Store` to make progress.
- A new `PromisesUnordered` type for `await`ing multiple promises concurrently
-`TypedFunc::call_concurrent` (which returns a `Promise`), allowing multiple host->guest calls to run concurrently on the same instance.
- Updated `{Stream|Future}{Writer|Reader}` APIs which use `Promise`
The upshot is that the embedder can now ergonomically manage arbitrary numbers
of concurrent operations. Previously, this was a lot more difficult to do
without accidentally starving some of the operations due to another one
monopolizing the `Store`.
Finally, this includes various refactorings and fixes for bugs exposed by the
newer, more versatile APIs.
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
clean up verbosity in component/func.rs
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
snapshot
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
implement stream/future read/write cancellation
This required a somewhat viral addition of `Send` and `Sync` bounds for async
host function closure types, unfortunately.
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
add `Func::call_concurrent` and `LinkerInstance::func_new_concurrent`
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
dynamic API support for streams/futures/error-contexts
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
support callback-less (AKA stackful) async lifts
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
fix `call_host` regression
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
add component model async end-to-end tests
I've ported these over from https://github.com/dicej/component-async-demo
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
fix test regressions and clippy warnings
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
satisfy clippy
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
fix async tests when `component-model-async` enabled
Enabling this feature for all tests revealed various missing pieces in the new
`concurrent.rs` fiber mechanism, which I've addressed.
This adds a bunch of ugly `#[cfg(feature = "component-model-async")]` guards,
but those will all go away once I unify the two async fiber implementations.
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
add and modify tests to cover concurrent APIs
Primarily, this tests and implements cases where parameters and/or results must
be passed via linear memory instead of the stack.
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
`concurrent_{imports|exports}` component macro codegen tests
This enables codegen testing of the `concurrent_imports` and
`concurrent_exports` options to `wasmtime::component::bindgen` and also fixes
code generation for world-level function and resource exports that use the
concurrent call style.
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
`concurrent_{imports|exports}` component macro expanded tests
This enables testing of the `concurrent_imports` and `concurrent_exports`
options in `crates/component-macro/tests/expanded.rs`.
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
add tests/misc_testsuite/component-model-async/*.wast
These only test instantiation of components which use various async options and
built-ins so far. Next, I'll happy and sad path tests which actually execute
code.
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
appease clippy
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
add tests/misc_testsuite/component-model-async/fused.wast
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
add non-panicking bounds checks where appropriate
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
remove post-return bits from async result lift code
...at least until we've determined whether post-return options even make sense
for async-lifted exports.
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
fix component-model-async/fused.wast test failure
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
use `enum` types to represent status and event codes
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
fix component-model-async/fused.wast test failure (2nd try)
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
use `gc_types = true` in component-model-async/fused.wast
We use `Instruction::RefFunc` when generating adapters for async lifts and/or
lowers, which Winch doesn't understand, and apparently `gc_types = true` is what
tells the test infra not to use Winch.
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
trap if async function finishes without calling `task.return`
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
update wit-bindgen and fix rebase damage
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
call post-return function if any for async->sync fused calls
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
dicej added a commit to dicej/wasmtime that referenced this pull request Jan 17, 2025
This adds support for loading, compiling, linking, and running components which
use the [Async
ABI](https://github.com/WebAssembly/component-model/blob/main/design/mvp/Async.md)
along with the [`stream`, `future`, and
`error-context`](WebAssembly/component-model#405) types.
It also adds support for generating host bindings such that multiple host
functions can be run concurrently with guest tasks -- without monopolizing the
`Store`.
See the [implementation RFC](bytecodealliance/rfcs#38)
for details, as well as [this
repo](https://github.com/dicej/component-async-demo) containing end-to-end smoke
tests.
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
fix clippy warnings and bench/fuzzing errors
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
revert atomic.wit whitespace change
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
fix build when component-model disabled
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
bless component-macro expected output
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
fix no-std build error
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
fix build with --no-default-features --features runtime,component-model
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
partly fix no-std build
It's still broken due to the use of `std::collections::HashMap` in
crates/wasmtime/src/runtime/vm/component.rs. I'll address that as part of the
work to avoid exposing global task/future/stream/error-context handles to
guests.
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
maintain per-instance tables for futures, streams, and error-contexts
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
refactor task/stream/future handle lifting/lowering
This addresses a couple of issues:
- Previously, we were passing task/stream/future/error-context reps directly to
instances while keeping track of which instance had access to which rep. That
worked fine in that there was no way to forge access to inaccessible reps, but
it leaked information about what other instances were doing. Now we maintain
per-instance waitable and error-context tables which map the reps to and from
the handles which the instance sees.
- The `no_std` build was broken due to use of `HashMap` in
`runtime::vm::component`, which is now fixed.
Note that we use one single table per instance for all tasks, streams, and
futures. This is partly necessary because, when async events are delivered to
the guest, it wouldn't have enough context to know which stream or future we're
talking about if each unique stream and future type had its own table. So at
minimum, we need to use the same table for all streams (regardless of payload
type), and likewise for futures. Also, per
WebAssembly/component-model#395 (comment),
the plan is to move towards a shared table for all resource types as well, so
this moves us in that direction.
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
fix wave breakage due to new stream/future/error-context types
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
switch wasm-tools to v1.220.0-based branch
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
check `task.return` type at runtime
We can't statically verify a given call to `task.return` corresponds to the
expected core signature appropriate for the currently running task, so we must
do so at runtime. In order to make that check efficient, we intern the types.
My initial plan was to use `ModuleInternedTypeIndex` and/or `VMSharedTypeIndex`
for interning, but that got hairy with WasmGC considerations, so instead I added
new fields to `ComponentTypes` and `ComponentTypesBuilder`.
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
add `TypedFunc::call_concurrent` and refine stream/future APIs
This implements what I proposed in https://github.com/dicej/rfcs/blob/component-async/accepted/component-model-async.md#wasmtime. Specifically, it adds:
- A new `Promise` type, useful for working with concurrent operations that require access to a `Store` to make progress.
- A new `PromisesUnordered` type for `await`ing multiple promises concurrently
-`TypedFunc::call_concurrent` (which returns a `Promise`), allowing multiple host->guest calls to run concurrently on the same instance.
- Updated `{Stream|Future}{Writer|Reader}` APIs which use `Promise`
The upshot is that the embedder can now ergonomically manage arbitrary numbers
of concurrent operations. Previously, this was a lot more difficult to do
without accidentally starving some of the operations due to another one
monopolizing the `Store`.
Finally, this includes various refactorings and fixes for bugs exposed by the
newer, more versatile APIs.
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
clean up verbosity in component/func.rs
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
snapshot
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
implement stream/future read/write cancellation
This required a somewhat viral addition of `Send` and `Sync` bounds for async
host function closure types, unfortunately.
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
add `Func::call_concurrent` and `LinkerInstance::func_new_concurrent`
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
dynamic API support for streams/futures/error-contexts
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
support callback-less (AKA stackful) async lifts
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
fix `call_host` regression
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
add component model async end-to-end tests
I've ported these over from https://github.com/dicej/component-async-demo
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
fix test regressions and clippy warnings
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
satisfy clippy
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
fix async tests when `component-model-async` enabled
Enabling this feature for all tests revealed various missing pieces in the new
`concurrent.rs` fiber mechanism, which I've addressed.
This adds a bunch of ugly `#[cfg(feature = "component-model-async")]` guards,
but those will all go away once I unify the two async fiber implementations.
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
add and modify tests to cover concurrent APIs
Primarily, this tests and implements cases where parameters and/or results must
be passed via linear memory instead of the stack.
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
`concurrent_{imports|exports}` component macro codegen tests
This enables codegen testing of the `concurrent_imports` and
`concurrent_exports` options to `wasmtime::component::bindgen` and also fixes
code generation for world-level function and resource exports that use the
concurrent call style.
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
`concurrent_{imports|exports}` component macro expanded tests
This enables testing of the `concurrent_imports` and `concurrent_exports`
options in `crates/component-macro/tests/expanded.rs`.
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
add tests/misc_testsuite/component-model-async/*.wast
These only test instantiation of components which use various async options and
built-ins so far. Next, I'll happy and sad path tests which actually execute
code.
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
appease clippy
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
add tests/misc_testsuite/component-model-async/fused.wast
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
add non-panicking bounds checks where appropriate
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
remove post-return bits from async result lift code
...at least until we've determined whether post-return options even make sense
for async-lifted exports.
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
fix component-model-async/fused.wast test failure
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
use `enum` types to represent status and event codes
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
fix component-model-async/fused.wast test failure (2nd try)
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
use `gc_types = true` in component-model-async/fused.wast
We use `Instruction::RefFunc` when generating adapters for async lifts and/or
lowers, which Winch doesn't understand, and apparently `gc_types = true` is what
tells the test infra not to use Winch.
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
trap if async function finishes without calling `task.return`
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
update wit-bindgen and fix rebase damage
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
call post-return function if any for async->sync fused calls
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
fix non-component-model-async build; appease clippy
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
bless bindgen output whitespace changes
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
enforce resource borrow requirements for async calls
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
update `wit-bindgen` and simplify `async_borrowing_callee` test
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
call `InstanceFlags::set_may_enter` where appropriate
There's still more work to do to fully implement (and test) the reentrance rules
for concurrent tasks, but this is a start.
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
finish implementing reentrance checks
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
feat: implement error-context (#1)
* feat: initial error-context implementation
This commit implements error-context related functions inside the VM,
along with tests to ensure that basic error-context.new and
error-context.debug-message functionality works.
Signed-off-by: Victor Adossi <vadossi@cosmonic.com>
* wip: add test for error context callee/caller transfer
Signed-off-by: Victor Adossi <vadossi@cosmonic.com>
* wip: test for async context transfer
Signed-off-by: Victor Adossi <vadossi@cosmonic.com>
---------
Signed-off-by: Victor Adossi <vadossi@cosmonic.com>
run cargo fmt
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
appease clippy
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
pull in Roman's unit stream work; add world-level export test
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
dicej added a commit to dicej/wasmtime that referenced this pull request Jan 17, 2025
This adds support for loading, compiling, linking, and running components which
use the [Async
ABI](https://github.com/WebAssembly/component-model/blob/main/design/mvp/Async.md)
along with the [`stream`, `future`, and
`error-context`](WebAssembly/component-model#405) types.
It also adds support for generating host bindings such that multiple host
functions can be run concurrently with guest tasks -- without monopolizing the
`Store`.
See the [implementation RFC](bytecodealliance/rfcs#38)
for details, as well as [this
repo](https://github.com/dicej/component-async-demo) containing end-to-end smoke
tests.
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
fix clippy warnings and bench/fuzzing errors
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
revert atomic.wit whitespace change
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
fix build when component-model disabled
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
bless component-macro expected output
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
fix no-std build error
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
fix build with --no-default-features --features runtime,component-model
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
partly fix no-std build
It's still broken due to the use of `std::collections::HashMap` in
crates/wasmtime/src/runtime/vm/component.rs. I'll address that as part of the
work to avoid exposing global task/future/stream/error-context handles to
guests.
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
maintain per-instance tables for futures, streams, and error-contexts
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
refactor task/stream/future handle lifting/lowering
This addresses a couple of issues:
- Previously, we were passing task/stream/future/error-context reps directly to
instances while keeping track of which instance had access to which rep. That
worked fine in that there was no way to forge access to inaccessible reps, but
it leaked information about what other instances were doing. Now we maintain
per-instance waitable and error-context tables which map the reps to and from
the handles which the instance sees.
- The `no_std` build was broken due to use of `HashMap` in
`runtime::vm::component`, which is now fixed.
Note that we use one single table per instance for all tasks, streams, and
futures. This is partly necessary because, when async events are delivered to
the guest, it wouldn't have enough context to know which stream or future we're
talking about if each unique stream and future type had its own table. So at
minimum, we need to use the same table for all streams (regardless of payload
type), and likewise for futures. Also, per
WebAssembly/component-model#395 (comment),
the plan is to move towards a shared table for all resource types as well, so
this moves us in that direction.
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
fix wave breakage due to new stream/future/error-context types
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
switch wasm-tools to v1.220.0-based branch
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
check `task.return` type at runtime
We can't statically verify a given call to `task.return` corresponds to the
expected core signature appropriate for the currently running task, so we must
do so at runtime. In order to make that check efficient, we intern the types.
My initial plan was to use `ModuleInternedTypeIndex` and/or `VMSharedTypeIndex`
for interning, but that got hairy with WasmGC considerations, so instead I added
new fields to `ComponentTypes` and `ComponentTypesBuilder`.
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
add `TypedFunc::call_concurrent` and refine stream/future APIs
This implements what I proposed in https://github.com/dicej/rfcs/blob/component-async/accepted/component-model-async.md#wasmtime. Specifically, it adds:
- A new `Promise` type, useful for working with concurrent operations that require access to a `Store` to make progress.
- A new `PromisesUnordered` type for `await`ing multiple promises concurrently
-`TypedFunc::call_concurrent` (which returns a `Promise`), allowing multiple host->guest calls to run concurrently on the same instance.
- Updated `{Stream|Future}{Writer|Reader}` APIs which use `Promise`
The upshot is that the embedder can now ergonomically manage arbitrary numbers
of concurrent operations. Previously, this was a lot more difficult to do
without accidentally starving some of the operations due to another one
monopolizing the `Store`.
Finally, this includes various refactorings and fixes for bugs exposed by the
newer, more versatile APIs.
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
clean up verbosity in component/func.rs
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
snapshot
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
implement stream/future read/write cancellation
This required a somewhat viral addition of `Send` and `Sync` bounds for async
host function closure types, unfortunately.
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
add `Func::call_concurrent` and `LinkerInstance::func_new_concurrent`
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
dynamic API support for streams/futures/error-contexts
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
support callback-less (AKA stackful) async lifts
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
fix `call_host` regression
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
add component model async end-to-end tests
I've ported these over from https://github.com/dicej/component-async-demo
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
fix test regressions and clippy warnings
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
satisfy clippy
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
fix async tests when `component-model-async` enabled
Enabling this feature for all tests revealed various missing pieces in the new
`concurrent.rs` fiber mechanism, which I've addressed.
This adds a bunch of ugly `#[cfg(feature = "component-model-async")]` guards,
but those will all go away once I unify the two async fiber implementations.
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
add and modify tests to cover concurrent APIs
Primarily, this tests and implements cases where parameters and/or results must
be passed via linear memory instead of the stack.
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
`concurrent_{imports|exports}` component macro codegen tests
This enables codegen testing of the `concurrent_imports` and
`concurrent_exports` options to `wasmtime::component::bindgen` and also fixes
code generation for world-level function and resource exports that use the
concurrent call style.
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
`concurrent_{imports|exports}` component macro expanded tests
This enables testing of the `concurrent_imports` and `concurrent_exports`
options in `crates/component-macro/tests/expanded.rs`.
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
add tests/misc_testsuite/component-model-async/*.wast
These only test instantiation of components which use various async options and
built-ins so far. Next, I'll happy and sad path tests which actually execute
code.
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
appease clippy
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
add tests/misc_testsuite/component-model-async/fused.wast
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
add non-panicking bounds checks where appropriate
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
remove post-return bits from async result lift code
...at least until we've determined whether post-return options even make sense
for async-lifted exports.
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
fix component-model-async/fused.wast test failure
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
use `enum` types to represent status and event codes
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
fix component-model-async/fused.wast test failure (2nd try)
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
use `gc_types = true` in component-model-async/fused.wast
We use `Instruction::RefFunc` when generating adapters for async lifts and/or
lowers, which Winch doesn't understand, and apparently `gc_types = true` is what
tells the test infra not to use Winch.
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
trap if async function finishes without calling `task.return`
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
update wit-bindgen and fix rebase damage
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
call post-return function if any for async->sync fused calls
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
fix non-component-model-async build; appease clippy
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
bless bindgen output whitespace changes
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
enforce resource borrow requirements for async calls
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
update `wit-bindgen` and simplify `async_borrowing_callee` test
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
call `InstanceFlags::set_may_enter` where appropriate
There's still more work to do to fully implement (and test) the reentrance rules
for concurrent tasks, but this is a start.
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
finish implementing reentrance checks
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
feat: implement error-context (#1)
* feat: initial error-context implementation
This commit implements error-context related functions inside the VM,
along with tests to ensure that basic error-context.new and
error-context.debug-message functionality works.
Signed-off-by: Victor Adossi <vadossi@cosmonic.com>
* wip: add test for error context callee/caller transfer
Signed-off-by: Victor Adossi <vadossi@cosmonic.com>
* wip: test for async context transfer
Signed-off-by: Victor Adossi <vadossi@cosmonic.com>
---------
Signed-off-by: Victor Adossi <vadossi@cosmonic.com>
run cargo fmt
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
appease clippy
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
pull in Roman's unit stream work; add world-level export test
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
dicej added a commit to dicej/wasmtime that referenced this pull request Jan 21, 2025
This adds support for loading, compiling, linking, and running components which
use the [Async
ABI](https://github.com/WebAssembly/component-model/blob/main/design/mvp/Async.md)
along with the [`stream`, `future`, and
`error-context`](WebAssembly/component-model#405) types.
It also adds support for generating host bindings such that multiple host
functions can be run concurrently with guest tasks -- without monopolizing the
`Store`.
See the [implementation RFC](bytecodealliance/rfcs#38)
for details, as well as [this
repo](https://github.com/dicej/component-async-demo) containing end-to-end smoke
tests.
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
fix clippy warnings and bench/fuzzing errors
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
revert atomic.wit whitespace change
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
fix build when component-model disabled
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
bless component-macro expected output
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
fix no-std build error
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
fix build with --no-default-features --features runtime,component-model
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
partly fix no-std build
It's still broken due to the use of `std::collections::HashMap` in
crates/wasmtime/src/runtime/vm/component.rs. I'll address that as part of the
work to avoid exposing global task/future/stream/error-context handles to
guests.
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
maintain per-instance tables for futures, streams, and error-contexts
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
refactor task/stream/future handle lifting/lowering
This addresses a couple of issues:
- Previously, we were passing task/stream/future/error-context reps directly to
instances while keeping track of which instance had access to which rep. That
worked fine in that there was no way to forge access to inaccessible reps, but
it leaked information about what other instances were doing. Now we maintain
per-instance waitable and error-context tables which map the reps to and from
the handles which the instance sees.
- The `no_std` build was broken due to use of `HashMap` in
`runtime::vm::component`, which is now fixed.
Note that we use one single table per instance for all tasks, streams, and
futures. This is partly necessary because, when async events are delivered to
the guest, it wouldn't have enough context to know which stream or future we're
talking about if each unique stream and future type had its own table. So at
minimum, we need to use the same table for all streams (regardless of payload
type), and likewise for futures. Also, per
WebAssembly/component-model#395 (comment),
the plan is to move towards a shared table for all resource types as well, so
this moves us in that direction.
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
fix wave breakage due to new stream/future/error-context types
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
switch wasm-tools to v1.220.0-based branch
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
check `task.return` type at runtime
We can't statically verify a given call to `task.return` corresponds to the
expected core signature appropriate for the currently running task, so we must
do so at runtime. In order to make that check efficient, we intern the types.
My initial plan was to use `ModuleInternedTypeIndex` and/or `VMSharedTypeIndex`
for interning, but that got hairy with WasmGC considerations, so instead I added
new fields to `ComponentTypes` and `ComponentTypesBuilder`.
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
add `TypedFunc::call_concurrent` and refine stream/future APIs
This implements what I proposed in https://github.com/dicej/rfcs/blob/component-async/accepted/component-model-async.md#wasmtime. Specifically, it adds:
- A new `Promise` type, useful for working with concurrent operations that require access to a `Store` to make progress.
- A new `PromisesUnordered` type for `await`ing multiple promises concurrently
-`TypedFunc::call_concurrent` (which returns a `Promise`), allowing multiple host->guest calls to run concurrently on the same instance.
- Updated `{Stream|Future}{Writer|Reader}` APIs which use `Promise`
The upshot is that the embedder can now ergonomically manage arbitrary numbers
of concurrent operations. Previously, this was a lot more difficult to do
without accidentally starving some of the operations due to another one
monopolizing the `Store`.
Finally, this includes various refactorings and fixes for bugs exposed by the
newer, more versatile APIs.
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
clean up verbosity in component/func.rs
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
snapshot
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
implement stream/future read/write cancellation
This required a somewhat viral addition of `Send` and `Sync` bounds for async
host function closure types, unfortunately.
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
add `Func::call_concurrent` and `LinkerInstance::func_new_concurrent`
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
dynamic API support for streams/futures/error-contexts
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
support callback-less (AKA stackful) async lifts
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
fix `call_host` regression
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
add component model async end-to-end tests
I've ported these over from https://github.com/dicej/component-async-demo
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
fix test regressions and clippy warnings
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
satisfy clippy
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
fix async tests when `component-model-async` enabled
Enabling this feature for all tests revealed various missing pieces in the new
`concurrent.rs` fiber mechanism, which I've addressed.
This adds a bunch of ugly `#[cfg(feature = "component-model-async")]` guards,
but those will all go away once I unify the two async fiber implementations.
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
add and modify tests to cover concurrent APIs
Primarily, this tests and implements cases where parameters and/or results must
be passed via linear memory instead of the stack.
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
`concurrent_{imports|exports}` component macro codegen tests
This enables codegen testing of the `concurrent_imports` and
`concurrent_exports` options to `wasmtime::component::bindgen` and also fixes
code generation for world-level function and resource exports that use the
concurrent call style.
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
`concurrent_{imports|exports}` component macro expanded tests
This enables testing of the `concurrent_imports` and `concurrent_exports`
options in `crates/component-macro/tests/expanded.rs`.
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
add tests/misc_testsuite/component-model-async/*.wast
These only test instantiation of components which use various async options and
built-ins so far. Next, I'll happy and sad path tests which actually execute
code.
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
appease clippy
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
add tests/misc_testsuite/component-model-async/fused.wast
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
add non-panicking bounds checks where appropriate
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
remove post-return bits from async result lift code
...at least until we've determined whether post-return options even make sense
for async-lifted exports.
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
fix component-model-async/fused.wast test failure
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
use `enum` types to represent status and event codes
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
fix component-model-async/fused.wast test failure (2nd try)
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
use `gc_types = true` in component-model-async/fused.wast
We use `Instruction::RefFunc` when generating adapters for async lifts and/or
lowers, which Winch doesn't understand, and apparently `gc_types = true` is what
tells the test infra not to use Winch.
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
trap if async function finishes without calling `task.return`
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
update wit-bindgen and fix rebase damage
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
call post-return function if any for async->sync fused calls
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
fix non-component-model-async build; appease clippy
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
bless bindgen output whitespace changes
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
enforce resource borrow requirements for async calls
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
update `wit-bindgen` and simplify `async_borrowing_callee` test
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
call `InstanceFlags::set_may_enter` where appropriate
There's still more work to do to fully implement (and test) the reentrance rules
for concurrent tasks, but this is a start.
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
finish implementing reentrance checks
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
feat: implement error-context (#1)
* feat: initial error-context implementation
This commit implements error-context related functions inside the VM,
along with tests to ensure that basic error-context.new and
error-context.debug-message functionality works.
Signed-off-by: Victor Adossi <vadossi@cosmonic.com>
* wip: add test for error context callee/caller transfer
Signed-off-by: Victor Adossi <vadossi@cosmonic.com>
* wip: test for async context transfer
Signed-off-by: Victor Adossi <vadossi@cosmonic.com>
---------
Signed-off-by: Victor Adossi <vadossi@cosmonic.com>
run cargo fmt
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
appease clippy
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
pull in Roman's unit stream work; add world-level export test
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
add unit stream tests
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
dicej added a commit to dicej/wasmtime that referenced this pull request Jan 22, 2025
This adds support for loading, compiling, linking, and running components which
use the [Async
ABI](https://github.com/WebAssembly/component-model/blob/main/design/mvp/Async.md)
along with the [`stream`, `future`, and
`error-context`](WebAssembly/component-model#405) types.
It also adds support for generating host bindings such that multiple host
functions can be run concurrently with guest tasks -- without monopolizing the
`Store`.
See the [implementation RFC](bytecodealliance/rfcs#38)
for details, as well as [this
repo](https://github.com/dicej/component-async-demo) containing end-to-end smoke
tests.
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
fix clippy warnings and bench/fuzzing errors
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
revert atomic.wit whitespace change
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
fix build when component-model disabled
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
bless component-macro expected output
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
fix no-std build error
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
fix build with --no-default-features --features runtime,component-model
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
partly fix no-std build
It's still broken due to the use of `std::collections::HashMap` in
crates/wasmtime/src/runtime/vm/component.rs. I'll address that as part of the
work to avoid exposing global task/future/stream/error-context handles to
guests.
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
maintain per-instance tables for futures, streams, and error-contexts
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
refactor task/stream/future handle lifting/lowering
This addresses a couple of issues:
- Previously, we were passing task/stream/future/error-context reps directly to
instances while keeping track of which instance had access to which rep. That
worked fine in that there was no way to forge access to inaccessible reps, but
it leaked information about what other instances were doing. Now we maintain
per-instance waitable and error-context tables which map the reps to and from
the handles which the instance sees.
- The `no_std` build was broken due to use of `HashMap` in
`runtime::vm::component`, which is now fixed.
Note that we use one single table per instance for all tasks, streams, and
futures. This is partly necessary because, when async events are delivered to
the guest, it wouldn't have enough context to know which stream or future we're
talking about if each unique stream and future type had its own table. So at
minimum, we need to use the same table for all streams (regardless of payload
type), and likewise for futures. Also, per
WebAssembly/component-model#395 (comment),
the plan is to move towards a shared table for all resource types as well, so
this moves us in that direction.
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
fix wave breakage due to new stream/future/error-context types
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
switch wasm-tools to v1.220.0-based branch
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
check `task.return` type at runtime
We can't statically verify a given call to `task.return` corresponds to the
expected core signature appropriate for the currently running task, so we must
do so at runtime. In order to make that check efficient, we intern the types.
My initial plan was to use `ModuleInternedTypeIndex` and/or `VMSharedTypeIndex`
for interning, but that got hairy with WasmGC considerations, so instead I added
new fields to `ComponentTypes` and `ComponentTypesBuilder`.
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
add `TypedFunc::call_concurrent` and refine stream/future APIs
This implements what I proposed in https://github.com/dicej/rfcs/blob/component-async/accepted/component-model-async.md#wasmtime. Specifically, it adds:
- A new `Promise` type, useful for working with concurrent operations that require access to a `Store` to make progress.
- A new `PromisesUnordered` type for `await`ing multiple promises concurrently
-`TypedFunc::call_concurrent` (which returns a `Promise`), allowing multiple host->guest calls to run concurrently on the same instance.
- Updated `{Stream|Future}{Writer|Reader}` APIs which use `Promise`
The upshot is that the embedder can now ergonomically manage arbitrary numbers
of concurrent operations. Previously, this was a lot more difficult to do
without accidentally starving some of the operations due to another one
monopolizing the `Store`.
Finally, this includes various refactorings and fixes for bugs exposed by the
newer, more versatile APIs.
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
clean up verbosity in component/func.rs
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
snapshot
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
implement stream/future read/write cancellation
This required a somewhat viral addition of `Send` and `Sync` bounds for async
host function closure types, unfortunately.
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
add `Func::call_concurrent` and `LinkerInstance::func_new_concurrent`
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
dynamic API support for streams/futures/error-contexts
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
support callback-less (AKA stackful) async lifts
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
fix `call_host` regression
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
add component model async end-to-end tests
I've ported these over from https://github.com/dicej/component-async-demo
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
fix test regressions and clippy warnings
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
satisfy clippy
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
fix async tests when `component-model-async` enabled
Enabling this feature for all tests revealed various missing pieces in the new
`concurrent.rs` fiber mechanism, which I've addressed.
This adds a bunch of ugly `#[cfg(feature = "component-model-async")]` guards,
but those will all go away once I unify the two async fiber implementations.
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
add and modify tests to cover concurrent APIs
Primarily, this tests and implements cases where parameters and/or results must
be passed via linear memory instead of the stack.
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
`concurrent_{imports|exports}` component macro codegen tests
This enables codegen testing of the `concurrent_imports` and
`concurrent_exports` options to `wasmtime::component::bindgen` and also fixes
code generation for world-level function and resource exports that use the
concurrent call style.
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
`concurrent_{imports|exports}` component macro expanded tests
This enables testing of the `concurrent_imports` and `concurrent_exports`
options in `crates/component-macro/tests/expanded.rs`.
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
add tests/misc_testsuite/component-model-async/*.wast
These only test instantiation of components which use various async options and
built-ins so far. Next, I'll happy and sad path tests which actually execute
code.
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
appease clippy
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
add tests/misc_testsuite/component-model-async/fused.wast
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
add non-panicking bounds checks where appropriate
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
remove post-return bits from async result lift code
...at least until we've determined whether post-return options even make sense
for async-lifted exports.
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
fix component-model-async/fused.wast test failure
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
use `enum` types to represent status and event codes
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
fix component-model-async/fused.wast test failure (2nd try)
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
use `gc_types = true` in component-model-async/fused.wast
We use `Instruction::RefFunc` when generating adapters for async lifts and/or
lowers, which Winch doesn't understand, and apparently `gc_types = true` is what
tells the test infra not to use Winch.
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
trap if async function finishes without calling `task.return`
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
update wit-bindgen and fix rebase damage
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
call post-return function if any for async->sync fused calls
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
fix non-component-model-async build; appease clippy
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
bless bindgen output whitespace changes
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
enforce resource borrow requirements for async calls
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
update `wit-bindgen` and simplify `async_borrowing_callee` test
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
call `InstanceFlags::set_may_enter` where appropriate
There's still more work to do to fully implement (and test) the reentrance rules
for concurrent tasks, but this is a start.
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
finish implementing reentrance checks
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
feat: implement error-context (#1)
* feat: initial error-context implementation
This commit implements error-context related functions inside the VM,
along with tests to ensure that basic error-context.new and
error-context.debug-message functionality works.
Signed-off-by: Victor Adossi <vadossi@cosmonic.com>
* wip: add test for error context callee/caller transfer
Signed-off-by: Victor Adossi <vadossi@cosmonic.com>
* wip: test for async context transfer
Signed-off-by: Victor Adossi <vadossi@cosmonic.com>
---------
Signed-off-by: Victor Adossi <vadossi@cosmonic.com>
run cargo fmt
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
appease clippy
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
pull in Roman's unit stream work; add world-level export test
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
add unit stream tests
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
dicej added a commit to dicej/wasmtime that referenced this pull request Jan 22, 2025
This adds support for loading, compiling, linking, and running components which
use the [Async
ABI](https://github.com/WebAssembly/component-model/blob/main/design/mvp/Async.md)
along with the [`stream`, `future`, and
`error-context`](WebAssembly/component-model#405) types.
It also adds support for generating host bindings such that multiple host
functions can be run concurrently with guest tasks -- without monopolizing the
`Store`.
See the [implementation RFC](bytecodealliance/rfcs#38)
for details, as well as [this
repo](https://github.com/dicej/component-async-demo) containing end-to-end smoke
tests.
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
fix clippy warnings and bench/fuzzing errors
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
revert atomic.wit whitespace change
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
fix build when component-model disabled
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
bless component-macro expected output
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
fix no-std build error
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
fix build with --no-default-features --features runtime,component-model
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
partly fix no-std build
It's still broken due to the use of `std::collections::HashMap` in
crates/wasmtime/src/runtime/vm/component.rs. I'll address that as part of the
work to avoid exposing global task/future/stream/error-context handles to
guests.
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
maintain per-instance tables for futures, streams, and error-contexts
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
refactor task/stream/future handle lifting/lowering
This addresses a couple of issues:
- Previously, we were passing task/stream/future/error-context reps directly to
instances while keeping track of which instance had access to which rep. That
worked fine in that there was no way to forge access to inaccessible reps, but
it leaked information about what other instances were doing. Now we maintain
per-instance waitable and error-context tables which map the reps to and from
the handles which the instance sees.
- The `no_std` build was broken due to use of `HashMap` in
`runtime::vm::component`, which is now fixed.
Note that we use one single table per instance for all tasks, streams, and
futures. This is partly necessary because, when async events are delivered to
the guest, it wouldn't have enough context to know which stream or future we're
talking about if each unique stream and future type had its own table. So at
minimum, we need to use the same table for all streams (regardless of payload
type), and likewise for futures. Also, per
WebAssembly/component-model#395 (comment),
the plan is to move towards a shared table for all resource types as well, so
this moves us in that direction.
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
fix wave breakage due to new stream/future/error-context types
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
switch wasm-tools to v1.220.0-based branch
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
check `task.return` type at runtime
We can't statically verify a given call to `task.return` corresponds to the
expected core signature appropriate for the currently running task, so we must
do so at runtime. In order to make that check efficient, we intern the types.
My initial plan was to use `ModuleInternedTypeIndex` and/or `VMSharedTypeIndex`
for interning, but that got hairy with WasmGC considerations, so instead I added
new fields to `ComponentTypes` and `ComponentTypesBuilder`.
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
add `TypedFunc::call_concurrent` and refine stream/future APIs
This implements what I proposed in https://github.com/dicej/rfcs/blob/component-async/accepted/component-model-async.md#wasmtime. Specifically, it adds:
- A new `Promise` type, useful for working with concurrent operations that require access to a `Store` to make progress.
- A new `PromisesUnordered` type for `await`ing multiple promises concurrently
-`TypedFunc::call_concurrent` (which returns a `Promise`), allowing multiple host->guest calls to run concurrently on the same instance.
- Updated `{Stream|Future}{Writer|Reader}` APIs which use `Promise`
The upshot is that the embedder can now ergonomically manage arbitrary numbers
of concurrent operations. Previously, this was a lot more difficult to do
without accidentally starving some of the operations due to another one
monopolizing the `Store`.
Finally, this includes various refactorings and fixes for bugs exposed by the
newer, more versatile APIs.
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
clean up verbosity in component/func.rs
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
snapshot
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
implement stream/future read/write cancellation
This required a somewhat viral addition of `Send` and `Sync` bounds for async
host function closure types, unfortunately.
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
add `Func::call_concurrent` and `LinkerInstance::func_new_concurrent`
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
dynamic API support for streams/futures/error-contexts
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
support callback-less (AKA stackful) async lifts
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
fix `call_host` regression
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
add component model async end-to-end tests
I've ported these over from https://github.com/dicej/component-async-demo
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
fix test regressions and clippy warnings
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
satisfy clippy
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
fix async tests when `component-model-async` enabled
Enabling this feature for all tests revealed various missing pieces in the new
`concurrent.rs` fiber mechanism, which I've addressed.
This adds a bunch of ugly `#[cfg(feature = "component-model-async")]` guards,
but those will all go away once I unify the two async fiber implementations.
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
add and modify tests to cover concurrent APIs
Primarily, this tests and implements cases where parameters and/or results must
be passed via linear memory instead of the stack.
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
`concurrent_{imports|exports}` component macro codegen tests
This enables codegen testing of the `concurrent_imports` and
`concurrent_exports` options to `wasmtime::component::bindgen` and also fixes
code generation for world-level function and resource exports that use the
concurrent call style.
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
`concurrent_{imports|exports}` component macro expanded tests
This enables testing of the `concurrent_imports` and `concurrent_exports`
options in `crates/component-macro/tests/expanded.rs`.
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
add tests/misc_testsuite/component-model-async/*.wast
These only test instantiation of components which use various async options and
built-ins so far. Next, I'll happy and sad path tests which actually execute
code.
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
appease clippy
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
add tests/misc_testsuite/component-model-async/fused.wast
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
add non-panicking bounds checks where appropriate
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
remove post-return bits from async result lift code
...at least until we've determined whether post-return options even make sense
for async-lifted exports.
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
fix component-model-async/fused.wast test failure
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
use `enum` types to represent status and event codes
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
fix component-model-async/fused.wast test failure (2nd try)
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
use `gc_types = true` in component-model-async/fused.wast
We use `Instruction::RefFunc` when generating adapters for async lifts and/or
lowers, which Winch doesn't understand, and apparently `gc_types = true` is what
tells the test infra not to use Winch.
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
trap if async function finishes without calling `task.return`
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
update wit-bindgen and fix rebase damage
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
call post-return function if any for async->sync fused calls
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
fix non-component-model-async build; appease clippy
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
bless bindgen output whitespace changes
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
enforce resource borrow requirements for async calls
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
update `wit-bindgen` and simplify `async_borrowing_callee` test
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
call `InstanceFlags::set_may_enter` where appropriate
There's still more work to do to fully implement (and test) the reentrance rules
for concurrent tasks, but this is a start.
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
finish implementing reentrance checks
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
feat: implement error-context (#1)
* feat: initial error-context implementation
This commit implements error-context related functions inside the VM,
along with tests to ensure that basic error-context.new and
error-context.debug-message functionality works.
Signed-off-by: Victor Adossi <vadossi@cosmonic.com>
* wip: add test for error context callee/caller transfer
Signed-off-by: Victor Adossi <vadossi@cosmonic.com>
* wip: test for async context transfer
Signed-off-by: Victor Adossi <vadossi@cosmonic.com>
---------
Signed-off-by: Victor Adossi <vadossi@cosmonic.com>
run cargo fmt
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
appease clippy
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
pull in Roman's unit stream work; add world-level export test
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
add unit stream tests
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
vados-cosmonic pushed a commit to vados-cosmonic/wasmtime that referenced this pull request Jan 23, 2025
This adds support for loading, compiling, linking, and running components which
use the [Async
ABI](https://github.com/WebAssembly/component-model/blob/main/design/mvp/Async.md)
along with the [`stream`, `future`, and
`error-context`](WebAssembly/component-model#405) types.
It also adds support for generating host bindings such that multiple host
functions can be run concurrently with guest tasks -- without monopolizing the
`Store`.
See the [implementation RFC](bytecodealliance/rfcs#38)
for details, as well as [this
repo](https://github.com/dicej/component-async-demo) containing end-to-end smoke
tests.
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
fix clippy warnings and bench/fuzzing errors
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
revert atomic.wit whitespace change
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
fix build when component-model disabled
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
bless component-macro expected output
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
fix no-std build error
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
fix build with --no-default-features --features runtime,component-model
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
partly fix no-std build
It's still broken due to the use of `std::collections::HashMap` in
crates/wasmtime/src/runtime/vm/component.rs. I'll address that as part of the
work to avoid exposing global task/future/stream/error-context handles to
guests.
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
maintain per-instance tables for futures, streams, and error-contexts
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
refactor task/stream/future handle lifting/lowering
This addresses a couple of issues:
- Previously, we were passing task/stream/future/error-context reps directly to
instances while keeping track of which instance had access to which rep. That
worked fine in that there was no way to forge access to inaccessible reps, but
it leaked information about what other instances were doing. Now we maintain
per-instance waitable and error-context tables which map the reps to and from
the handles which the instance sees.
- The `no_std` build was broken due to use of `HashMap` in
`runtime::vm::component`, which is now fixed.
Note that we use one single table per instance for all tasks, streams, and
futures. This is partly necessary because, when async events are delivered to
the guest, it wouldn't have enough context to know which stream or future we're
talking about if each unique stream and future type had its own table. So at
minimum, we need to use the same table for all streams (regardless of payload
type), and likewise for futures. Also, per
WebAssembly/component-model#395 (comment),
the plan is to move towards a shared table for all resource types as well, so
this moves us in that direction.
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
fix wave breakage due to new stream/future/error-context types
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
switch wasm-tools to v1.220.0-based branch
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
check `task.return` type at runtime
We can't statically verify a given call to `task.return` corresponds to the
expected core signature appropriate for the currently running task, so we must
do so at runtime. In order to make that check efficient, we intern the types.
My initial plan was to use `ModuleInternedTypeIndex` and/or `VMSharedTypeIndex`
for interning, but that got hairy with WasmGC considerations, so instead I added
new fields to `ComponentTypes` and `ComponentTypesBuilder`.
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
add `TypedFunc::call_concurrent` and refine stream/future APIs
This implements what I proposed in https://github.com/dicej/rfcs/blob/component-async/accepted/component-model-async.md#wasmtime. Specifically, it adds:
- A new `Promise` type, useful for working with concurrent operations that require access to a `Store` to make progress.
- A new `PromisesUnordered` type for `await`ing multiple promises concurrently
-`TypedFunc::call_concurrent` (which returns a `Promise`), allowing multiple host->guest calls to run concurrently on the same instance.
- Updated `{Stream|Future}{Writer|Reader}` APIs which use `Promise`
The upshot is that the embedder can now ergonomically manage arbitrary numbers
of concurrent operations. Previously, this was a lot more difficult to do
without accidentally starving some of the operations due to another one
monopolizing the `Store`.
Finally, this includes various refactorings and fixes for bugs exposed by the
newer, more versatile APIs.
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
clean up verbosity in component/func.rs
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
snapshot
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
implement stream/future read/write cancellation
This required a somewhat viral addition of `Send` and `Sync` bounds for async
host function closure types, unfortunately.
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
add `Func::call_concurrent` and `LinkerInstance::func_new_concurrent`
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
dynamic API support for streams/futures/error-contexts
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
support callback-less (AKA stackful) async lifts
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
fix `call_host` regression
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
add component model async end-to-end tests
I've ported these over from https://github.com/dicej/component-async-demo
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
fix test regressions and clippy warnings
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
satisfy clippy
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
fix async tests when `component-model-async` enabled
Enabling this feature for all tests revealed various missing pieces in the new
`concurrent.rs` fiber mechanism, which I've addressed.
This adds a bunch of ugly `#[cfg(feature = "component-model-async")]` guards,
but those will all go away once I unify the two async fiber implementations.
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
add and modify tests to cover concurrent APIs
Primarily, this tests and implements cases where parameters and/or results must
be passed via linear memory instead of the stack.
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
`concurrent_{imports|exports}` component macro codegen tests
This enables codegen testing of the `concurrent_imports` and
`concurrent_exports` options to `wasmtime::component::bindgen` and also fixes
code generation for world-level function and resource exports that use the
concurrent call style.
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
`concurrent_{imports|exports}` component macro expanded tests
This enables testing of the `concurrent_imports` and `concurrent_exports`
options in `crates/component-macro/tests/expanded.rs`.
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
add tests/misc_testsuite/component-model-async/*.wast
These only test instantiation of components which use various async options and
built-ins so far. Next, I'll happy and sad path tests which actually execute
code.
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
appease clippy
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
add tests/misc_testsuite/component-model-async/fused.wast
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
add non-panicking bounds checks where appropriate
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
remove post-return bits from async result lift code
...at least until we've determined whether post-return options even make sense
for async-lifted exports.
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
fix component-model-async/fused.wast test failure
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
use `enum` types to represent status and event codes
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
fix component-model-async/fused.wast test failure (2nd try)
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
use `gc_types = true` in component-model-async/fused.wast
We use `Instruction::RefFunc` when generating adapters for async lifts and/or
lowers, which Winch doesn't understand, and apparently `gc_types = true` is what
tells the test infra not to use Winch.
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
trap if async function finishes without calling `task.return`
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
update wit-bindgen and fix rebase damage
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
call post-return function if any for async->sync fused calls
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
fix non-component-model-async build; appease clippy
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
bless bindgen output whitespace changes
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
enforce resource borrow requirements for async calls
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
update `wit-bindgen` and simplify `async_borrowing_callee` test
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
call `InstanceFlags::set_may_enter` where appropriate
There's still more work to do to fully implement (and test) the reentrance rules
for concurrent tasks, but this is a start.
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
finish implementing reentrance checks
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
feat: implement error-context (bytecodealliance#1)
* feat: initial error-context implementation
This commit implements error-context related functions inside the VM,
along with tests to ensure that basic error-context.new and
error-context.debug-message functionality works.
Signed-off-by: Victor Adossi <vadossi@cosmonic.com>
* wip: add test for error context callee/caller transfer
Signed-off-by: Victor Adossi <vadossi@cosmonic.com>
* wip: test for async context transfer
Signed-off-by: Victor Adossi <vadossi@cosmonic.com>
---------
Signed-off-by: Victor Adossi <vadossi@cosmonic.com>
run cargo fmt
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
appease clippy
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
pull in Roman's unit stream work; add world-level export test
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
add unit stream tests
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
rvolosatovs pushed a commit to rvolosatovs/wasmtime that referenced this pull request Jan 24, 2025
This adds support for loading, compiling, linking, and running components which
use the [Async
ABI](https://github.com/WebAssembly/component-model/blob/main/design/mvp/Async.md)
along with the [`stream`, `future`, and
`error-context`](WebAssembly/component-model#405) types.
It also adds support for generating host bindings such that multiple host
functions can be run concurrently with guest tasks -- without monopolizing the
`Store`.
See the [implementation RFC](bytecodealliance/rfcs#38)
for details, as well as [this
repo](https://github.com/dicej/component-async-demo) containing end-to-end smoke
tests.
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
fix clippy warnings and bench/fuzzing errors
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
revert atomic.wit whitespace change
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
fix build when component-model disabled
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
bless component-macro expected output
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
fix no-std build error
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
fix build with --no-default-features --features runtime,component-model
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
partly fix no-std build
It's still broken due to the use of `std::collections::HashMap` in
crates/wasmtime/src/runtime/vm/component.rs. I'll address that as part of the
work to avoid exposing global task/future/stream/error-context handles to
guests.
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
maintain per-instance tables for futures, streams, and error-contexts
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
refactor task/stream/future handle lifting/lowering
This addresses a couple of issues:
- Previously, we were passing task/stream/future/error-context reps directly to
instances while keeping track of which instance had access to which rep. That
worked fine in that there was no way to forge access to inaccessible reps, but
it leaked information about what other instances were doing. Now we maintain
per-instance waitable and error-context tables which map the reps to and from
the handles which the instance sees.
- The `no_std` build was broken due to use of `HashMap` in
`runtime::vm::component`, which is now fixed.
Note that we use one single table per instance for all tasks, streams, and
futures. This is partly necessary because, when async events are delivered to
the guest, it wouldn't have enough context to know which stream or future we're
talking about if each unique stream and future type had its own table. So at
minimum, we need to use the same table for all streams (regardless of payload
type), and likewise for futures. Also, per
WebAssembly/component-model#395 (comment),
the plan is to move towards a shared table for all resource types as well, so
this moves us in that direction.
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
fix wave breakage due to new stream/future/error-context types
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
switch wasm-tools to v1.220.0-based branch
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
check `task.return` type at runtime
We can't statically verify a given call to `task.return` corresponds to the
expected core signature appropriate for the currently running task, so we must
do so at runtime. In order to make that check efficient, we intern the types.
My initial plan was to use `ModuleInternedTypeIndex` and/or `VMSharedTypeIndex`
for interning, but that got hairy with WasmGC considerations, so instead I added
new fields to `ComponentTypes` and `ComponentTypesBuilder`.
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
add `TypedFunc::call_concurrent` and refine stream/future APIs
This implements what I proposed in https://github.com/dicej/rfcs/blob/component-async/accepted/component-model-async.md#wasmtime. Specifically, it adds:
- A new `Promise` type, useful for working with concurrent operations that require access to a `Store` to make progress.
- A new `PromisesUnordered` type for `await`ing multiple promises concurrently
-`TypedFunc::call_concurrent` (which returns a `Promise`), allowing multiple host->guest calls to run concurrently on the same instance.
- Updated `{Stream|Future}{Writer|Reader}` APIs which use `Promise`
The upshot is that the embedder can now ergonomically manage arbitrary numbers
of concurrent operations. Previously, this was a lot more difficult to do
without accidentally starving some of the operations due to another one
monopolizing the `Store`.
Finally, this includes various refactorings and fixes for bugs exposed by the
newer, more versatile APIs.
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
clean up verbosity in component/func.rs
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
snapshot
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
implement stream/future read/write cancellation
This required a somewhat viral addition of `Send` and `Sync` bounds for async
host function closure types, unfortunately.
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
add `Func::call_concurrent` and `LinkerInstance::func_new_concurrent`
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
dynamic API support for streams/futures/error-contexts
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
support callback-less (AKA stackful) async lifts
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
fix `call_host` regression
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
add component model async end-to-end tests
I've ported these over from https://github.com/dicej/component-async-demo
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
fix test regressions and clippy warnings
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
satisfy clippy
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
fix async tests when `component-model-async` enabled
Enabling this feature for all tests revealed various missing pieces in the new
`concurrent.rs` fiber mechanism, which I've addressed.
This adds a bunch of ugly `#[cfg(feature = "component-model-async")]` guards,
but those will all go away once I unify the two async fiber implementations.
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
add and modify tests to cover concurrent APIs
Primarily, this tests and implements cases where parameters and/or results must
be passed via linear memory instead of the stack.
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
`concurrent_{imports|exports}` component macro codegen tests
This enables codegen testing of the `concurrent_imports` and
`concurrent_exports` options to `wasmtime::component::bindgen` and also fixes
code generation for world-level function and resource exports that use the
concurrent call style.
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
`concurrent_{imports|exports}` component macro expanded tests
This enables testing of the `concurrent_imports` and `concurrent_exports`
options in `crates/component-macro/tests/expanded.rs`.
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
add tests/misc_testsuite/component-model-async/*.wast
These only test instantiation of components which use various async options and
built-ins so far. Next, I'll happy and sad path tests which actually execute
code.
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
appease clippy
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
add tests/misc_testsuite/component-model-async/fused.wast
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
add non-panicking bounds checks where appropriate
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
remove post-return bits from async result lift code
...at least until we've determined whether post-return options even make sense
for async-lifted exports.
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
fix component-model-async/fused.wast test failure
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
use `enum` types to represent status and event codes
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
fix component-model-async/fused.wast test failure (2nd try)
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
use `gc_types = true` in component-model-async/fused.wast
We use `Instruction::RefFunc` when generating adapters for async lifts and/or
lowers, which Winch doesn't understand, and apparently `gc_types = true` is what
tells the test infra not to use Winch.
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
trap if async function finishes without calling `task.return`
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
update wit-bindgen and fix rebase damage
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
call post-return function if any for async->sync fused calls
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
fix non-component-model-async build; appease clippy
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
bless bindgen output whitespace changes
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
enforce resource borrow requirements for async calls
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
update `wit-bindgen` and simplify `async_borrowing_callee` test
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
call `InstanceFlags::set_may_enter` where appropriate
There's still more work to do to fully implement (and test) the reentrance rules
for concurrent tasks, but this is a start.
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
finish implementing reentrance checks
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
feat: implement error-context (#1)
* feat: initial error-context implementation
This commit implements error-context related functions inside the VM,
along with tests to ensure that basic error-context.new and
error-context.debug-message functionality works.
Signed-off-by: Victor Adossi <vadossi@cosmonic.com>
* wip: add test for error context callee/caller transfer
Signed-off-by: Victor Adossi <vadossi@cosmonic.com>
* wip: test for async context transfer
Signed-off-by: Victor Adossi <vadossi@cosmonic.com>
---------
Signed-off-by: Victor Adossi <vadossi@cosmonic.com>
run cargo fmt
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
appease clippy
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
pull in Roman's unit stream work; add world-level export test
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
add unit stream tests
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
rvolosatovs pushed a commit to rvolosatovs/wasmtime that referenced this pull request Jan 28, 2025
This adds support for loading, compiling, linking, and running components which
use the [Async
ABI](https://github.com/WebAssembly/component-model/blob/main/design/mvp/Async.md)
along with the [`stream`, `future`, and
`error-context`](WebAssembly/component-model#405) types.
It also adds support for generating host bindings such that multiple host
functions can be run concurrently with guest tasks -- without monopolizing the
`Store`.
See the [implementation RFC](bytecodealliance/rfcs#38)
for details, as well as [this
repo](https://github.com/dicej/component-async-demo) containing end-to-end smoke
tests.
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
fix clippy warnings and bench/fuzzing errors
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
revert atomic.wit whitespace change
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
fix build when component-model disabled
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
bless component-macro expected output
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
fix no-std build error
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
fix build with --no-default-features --features runtime,component-model
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
partly fix no-std build
It's still broken due to the use of `std::collections::HashMap` in
crates/wasmtime/src/runtime/vm/component.rs. I'll address that as part of the
work to avoid exposing global task/future/stream/error-context handles to
guests.
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
maintain per-instance tables for futures, streams, and error-contexts
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
refactor task/stream/future handle lifting/lowering
This addresses a couple of issues:
- Previously, we were passing task/stream/future/error-context reps directly to
instances while keeping track of which instance had access to which rep. That
worked fine in that there was no way to forge access to inaccessible reps, but
it leaked information about what other instances were doing. Now we maintain
per-instance waitable and error-context tables which map the reps to and from
the handles which the instance sees.
- The `no_std` build was broken due to use of `HashMap` in
`runtime::vm::component`, which is now fixed.
Note that we use one single table per instance for all tasks, streams, and
futures. This is partly necessary because, when async events are delivered to
the guest, it wouldn't have enough context to know which stream or future we're
talking about if each unique stream and future type had its own table. So at
minimum, we need to use the same table for all streams (regardless of payload
type), and likewise for futures. Also, per
WebAssembly/component-model#395 (comment),
the plan is to move towards a shared table for all resource types as well, so
this moves us in that direction.
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
fix wave breakage due to new stream/future/error-context types
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
switch wasm-tools to v1.220.0-based branch
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
check `task.return` type at runtime
We can't statically verify a given call to `task.return` corresponds to the
expected core signature appropriate for the currently running task, so we must
do so at runtime. In order to make that check efficient, we intern the types.
My initial plan was to use `ModuleInternedTypeIndex` and/or `VMSharedTypeIndex`
for interning, but that got hairy with WasmGC considerations, so instead I added
new fields to `ComponentTypes` and `ComponentTypesBuilder`.
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
add `TypedFunc::call_concurrent` and refine stream/future APIs
This implements what I proposed in https://github.com/dicej/rfcs/blob/component-async/accepted/component-model-async.md#wasmtime. Specifically, it adds:
- A new `Promise` type, useful for working with concurrent operations that require access to a `Store` to make progress.
- A new `PromisesUnordered` type for `await`ing multiple promises concurrently
-`TypedFunc::call_concurrent` (which returns a `Promise`), allowing multiple host->guest calls to run concurrently on the same instance.
- Updated `{Stream|Future}{Writer|Reader}` APIs which use `Promise`
The upshot is that the embedder can now ergonomically manage arbitrary numbers
of concurrent operations. Previously, this was a lot more difficult to do
without accidentally starving some of the operations due to another one
monopolizing the `Store`.
Finally, this includes various refactorings and fixes for bugs exposed by the
newer, more versatile APIs.
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
clean up verbosity in component/func.rs
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
snapshot
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
implement stream/future read/write cancellation
This required a somewhat viral addition of `Send` and `Sync` bounds for async
host function closure types, unfortunately.
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
add `Func::call_concurrent` and `LinkerInstance::func_new_concurrent`
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
dynamic API support for streams/futures/error-contexts
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
support callback-less (AKA stackful) async lifts
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
fix `call_host` regression
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
add component model async end-to-end tests
I've ported these over from https://github.com/dicej/component-async-demo
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
fix test regressions and clippy warnings
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
satisfy clippy
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
fix async tests when `component-model-async` enabled
Enabling this feature for all tests revealed various missing pieces in the new
`concurrent.rs` fiber mechanism, which I've addressed.
This adds a bunch of ugly `#[cfg(feature = "component-model-async")]` guards,
but those will all go away once I unify the two async fiber implementations.
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
add and modify tests to cover concurrent APIs
Primarily, this tests and implements cases where parameters and/or results must
be passed via linear memory instead of the stack.
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
`concurrent_{imports|exports}` component macro codegen tests
This enables codegen testing of the `concurrent_imports` and
`concurrent_exports` options to `wasmtime::component::bindgen` and also fixes
code generation for world-level function and resource exports that use the
concurrent call style.
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
`concurrent_{imports|exports}` component macro expanded tests
This enables testing of the `concurrent_imports` and `concurrent_exports`
options in `crates/component-macro/tests/expanded.rs`.
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
add tests/misc_testsuite/component-model-async/*.wast
These only test instantiation of components which use various async options and
built-ins so far. Next, I'll happy and sad path tests which actually execute
code.
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
appease clippy
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
add tests/misc_testsuite/component-model-async/fused.wast
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
add non-panicking bounds checks where appropriate
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
remove post-return bits from async result lift code
...at least until we've determined whether post-return options even make sense
for async-lifted exports.
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
fix component-model-async/fused.wast test failure
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
use `enum` types to represent status and event codes
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
fix component-model-async/fused.wast test failure (2nd try)
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
use `gc_types = true` in component-model-async/fused.wast
We use `Instruction::RefFunc` when generating adapters for async lifts and/or
lowers, which Winch doesn't understand, and apparently `gc_types = true` is what
tells the test infra not to use Winch.
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
trap if async function finishes without calling `task.return`
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
update wit-bindgen and fix rebase damage
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
call post-return function if any for async->sync fused calls
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
fix non-component-model-async build; appease clippy
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
bless bindgen output whitespace changes
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
enforce resource borrow requirements for async calls
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
update `wit-bindgen` and simplify `async_borrowing_callee` test
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
call `InstanceFlags::set_may_enter` where appropriate
There's still more work to do to fully implement (and test) the reentrance rules
for concurrent tasks, but this is a start.
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
finish implementing reentrance checks
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
feat: implement error-context (#1)
* feat: initial error-context implementation
This commit implements error-context related functions inside the VM,
along with tests to ensure that basic error-context.new and
error-context.debug-message functionality works.
Signed-off-by: Victor Adossi <vadossi@cosmonic.com>
* wip: add test for error context callee/caller transfer
Signed-off-by: Victor Adossi <vadossi@cosmonic.com>
* wip: test for async context transfer
Signed-off-by: Victor Adossi <vadossi@cosmonic.com>
---------
Signed-off-by: Victor Adossi <vadossi@cosmonic.com>
run cargo fmt
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
appease clippy
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
pull in Roman's unit stream work; add world-level export test
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
add unit stream tests
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
dicej added a commit to dicej/wasmtime that referenced this pull request Jan 29, 2025
This adds support for loading, compiling, linking, and running components which
use the [Async
ABI](https://github.com/WebAssembly/component-model/blob/main/design/mvp/Async.md)
along with the [`stream`, `future`, and
`error-context`](WebAssembly/component-model#405) types.
It also adds support for generating host bindings such that multiple host
functions can be run concurrently with guest tasks -- without monopolizing the
`Store`.
See the [implementation RFC](bytecodealliance/rfcs#38)
for details, as well as [this
repo](https://github.com/dicej/component-async-demo) containing end-to-end smoke
tests.
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
fix clippy warnings and bench/fuzzing errors
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
revert atomic.wit whitespace change
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
fix build when component-model disabled
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
bless component-macro expected output
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
fix no-std build error
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
fix build with --no-default-features --features runtime,component-model
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
partly fix no-std build
It's still broken due to the use of `std::collections::HashMap` in
crates/wasmtime/src/runtime/vm/component.rs. I'll address that as part of the
work to avoid exposing global task/future/stream/error-context handles to
guests.
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
maintain per-instance tables for futures, streams, and error-contexts
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
refactor task/stream/future handle lifting/lowering
This addresses a couple of issues:
- Previously, we were passing task/stream/future/error-context reps directly to
instances while keeping track of which instance had access to which rep. That
worked fine in that there was no way to forge access to inaccessible reps, but
it leaked information about what other instances were doing. Now we maintain
per-instance waitable and error-context tables which map the reps to and from
the handles which the instance sees.
- The `no_std` build was broken due to use of `HashMap` in
`runtime::vm::component`, which is now fixed.
Note that we use one single table per instance for all tasks, streams, and
futures. This is partly necessary because, when async events are delivered to
the guest, it wouldn't have enough context to know which stream or future we're
talking about if each unique stream and future type had its own table. So at
minimum, we need to use the same table for all streams (regardless of payload
type), and likewise for futures. Also, per
WebAssembly/component-model#395 (comment),
the plan is to move towards a shared table for all resource types as well, so
this moves us in that direction.
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
fix wave breakage due to new stream/future/error-context types
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
switch wasm-tools to v1.220.0-based branch
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
check `task.return` type at runtime
We can't statically verify a given call to `task.return` corresponds to the
expected core signature appropriate for the currently running task, so we must
do so at runtime. In order to make that check efficient, we intern the types.
My initial plan was to use `ModuleInternedTypeIndex` and/or `VMSharedTypeIndex`
for interning, but that got hairy with WasmGC considerations, so instead I added
new fields to `ComponentTypes` and `ComponentTypesBuilder`.
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
add `TypedFunc::call_concurrent` and refine stream/future APIs
This implements what I proposed in https://github.com/dicej/rfcs/blob/component-async/accepted/component-model-async.md#wasmtime. Specifically, it adds:
- A new `Promise` type, useful for working with concurrent operations that require access to a `Store` to make progress.
- A new `PromisesUnordered` type for `await`ing multiple promises concurrently
-`TypedFunc::call_concurrent` (which returns a `Promise`), allowing multiple host->guest calls to run concurrently on the same instance.
- Updated `{Stream|Future}{Writer|Reader}` APIs which use `Promise`
The upshot is that the embedder can now ergonomically manage arbitrary numbers
of concurrent operations. Previously, this was a lot more difficult to do
without accidentally starving some of the operations due to another one
monopolizing the `Store`.
Finally, this includes various refactorings and fixes for bugs exposed by the
newer, more versatile APIs.
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
clean up verbosity in component/func.rs
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
snapshot
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
implement stream/future read/write cancellation
This required a somewhat viral addition of `Send` and `Sync` bounds for async
host function closure types, unfortunately.
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
add `Func::call_concurrent` and `LinkerInstance::func_new_concurrent`
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
dynamic API support for streams/futures/error-contexts
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
support callback-less (AKA stackful) async lifts
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
fix `call_host` regression
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
add component model async end-to-end tests
I've ported these over from https://github.com/dicej/component-async-demo
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
fix test regressions and clippy warnings
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
satisfy clippy
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
fix async tests when `component-model-async` enabled
Enabling this feature for all tests revealed various missing pieces in the new
`concurrent.rs` fiber mechanism, which I've addressed.
This adds a bunch of ugly `#[cfg(feature = "component-model-async")]` guards,
but those will all go away once I unify the two async fiber implementations.
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
add and modify tests to cover concurrent APIs
Primarily, this tests and implements cases where parameters and/or results must
be passed via linear memory instead of the stack.
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
`concurrent_{imports|exports}` component macro codegen tests
This enables codegen testing of the `concurrent_imports` and
`concurrent_exports` options to `wasmtime::component::bindgen` and also fixes
code generation for world-level function and resource exports that use the
concurrent call style.
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
`concurrent_{imports|exports}` component macro expanded tests
This enables testing of the `concurrent_imports` and `concurrent_exports`
options in `crates/component-macro/tests/expanded.rs`.
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
add tests/misc_testsuite/component-model-async/*.wast
These only test instantiation of components which use various async options and
built-ins so far. Next, I'll happy and sad path tests which actually execute
code.
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
appease clippy
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
add tests/misc_testsuite/component-model-async/fused.wast
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
add non-panicking bounds checks where appropriate
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
remove post-return bits from async result lift code
...at least until we've determined whether post-return options even make sense
for async-lifted exports.
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
fix component-model-async/fused.wast test failure
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
use `enum` types to represent status and event codes
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
fix component-model-async/fused.wast test failure (2nd try)
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
use `gc_types = true` in component-model-async/fused.wast
We use `Instruction::RefFunc` when generating adapters for async lifts and/or
lowers, which Winch doesn't understand, and apparently `gc_types = true` is what
tells the test infra not to use Winch.
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
trap if async function finishes without calling `task.return`
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
update wit-bindgen and fix rebase damage
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
call post-return function if any for async->sync fused calls
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
fix non-component-model-async build; appease clippy
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
bless bindgen output whitespace changes
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
enforce resource borrow requirements for async calls
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
update `wit-bindgen` and simplify `async_borrowing_callee` test
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
call `InstanceFlags::set_may_enter` where appropriate
There's still more work to do to fully implement (and test) the reentrance rules
for concurrent tasks, but this is a start.
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
finish implementing reentrance checks
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
feat: implement error-context (#1)
* feat: initial error-context implementation
This commit implements error-context related functions inside the VM,
along with tests to ensure that basic error-context.new and
error-context.debug-message functionality works.
Signed-off-by: Victor Adossi <vadossi@cosmonic.com>
* wip: add test for error context callee/caller transfer
Signed-off-by: Victor Adossi <vadossi@cosmonic.com>
* wip: test for async context transfer
Signed-off-by: Victor Adossi <vadossi@cosmonic.com>
---------
Signed-off-by: Victor Adossi <vadossi@cosmonic.com>
run cargo fmt
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
appease clippy
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
pull in Roman's unit stream work; add world-level export test
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
add unit stream tests
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
CI fixes
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
dicej added a commit to dicej/wasmtime that referenced this pull request Jan 29, 2025
This adds support for loading, compiling, linking, and running components which
use the [Async
ABI](https://github.com/WebAssembly/component-model/blob/main/design/mvp/Async.md)
along with the [`stream`, `future`, and
`error-context`](WebAssembly/component-model#405) types.
It also adds support for generating host bindings such that multiple host
functions can be run concurrently with guest tasks -- without monopolizing the
`Store`.
See the [implementation RFC](bytecodealliance/rfcs#38)
for details, as well as [this
repo](https://github.com/dicej/component-async-demo) containing end-to-end smoke
tests.
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
fix clippy warnings and bench/fuzzing errors
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
revert atomic.wit whitespace change
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
fix build when component-model disabled
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
bless component-macro expected output
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
fix no-std build error
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
fix build with --no-default-features --features runtime,component-model
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
partly fix no-std build
It's still broken due to the use of `std::collections::HashMap` in
crates/wasmtime/src/runtime/vm/component.rs. I'll address that as part of the
work to avoid exposing global task/future/stream/error-context handles to
guests.
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
maintain per-instance tables for futures, streams, and error-contexts
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
refactor task/stream/future handle lifting/lowering
This addresses a couple of issues:
- Previously, we were passing task/stream/future/error-context reps directly to
instances while keeping track of which instance had access to which rep. That
worked fine in that there was no way to forge access to inaccessible reps, but
it leaked information about what other instances were doing. Now we maintain
per-instance waitable and error-context tables which map the reps to and from
the handles which the instance sees.
- The `no_std` build was broken due to use of `HashMap` in
`runtime::vm::component`, which is now fixed.
Note that we use one single table per instance for all tasks, streams, and
futures. This is partly necessary because, when async events are delivered to
the guest, it wouldn't have enough context to know which stream or future we're
talking about if each unique stream and future type had its own table. So at
minimum, we need to use the same table for all streams (regardless of payload
type), and likewise for futures. Also, per
WebAssembly/component-model#395 (comment),
the plan is to move towards a shared table for all resource types as well, so
this moves us in that direction.
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
fix wave breakage due to new stream/future/error-context types
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
switch wasm-tools to v1.220.0-based branch
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
check `task.return` type at runtime
We can't statically verify a given call to `task.return` corresponds to the
expected core signature appropriate for the currently running task, so we must
do so at runtime. In order to make that check efficient, we intern the types.
My initial plan was to use `ModuleInternedTypeIndex` and/or `VMSharedTypeIndex`
for interning, but that got hairy with WasmGC considerations, so instead I added
new fields to `ComponentTypes` and `ComponentTypesBuilder`.
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
add `TypedFunc::call_concurrent` and refine stream/future APIs
This implements what I proposed in https://github.com/dicej/rfcs/blob/component-async/accepted/component-model-async.md#wasmtime. Specifically, it adds:
- A new `Promise` type, useful for working with concurrent operations that require access to a `Store` to make progress.
- A new `PromisesUnordered` type for `await`ing multiple promises concurrently
-`TypedFunc::call_concurrent` (which returns a `Promise`), allowing multiple host->guest calls to run concurrently on the same instance.
- Updated `{Stream|Future}{Writer|Reader}` APIs which use `Promise`
The upshot is that the embedder can now ergonomically manage arbitrary numbers
of concurrent operations. Previously, this was a lot more difficult to do
without accidentally starving some of the operations due to another one
monopolizing the `Store`.
Finally, this includes various refactorings and fixes for bugs exposed by the
newer, more versatile APIs.
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
clean up verbosity in component/func.rs
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
snapshot
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
implement stream/future read/write cancellation
This required a somewhat viral addition of `Send` and `Sync` bounds for async
host function closure types, unfortunately.
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
add `Func::call_concurrent` and `LinkerInstance::func_new_concurrent`
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
dynamic API support for streams/futures/error-contexts
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
support callback-less (AKA stackful) async lifts
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
fix `call_host` regression
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
add component model async end-to-end tests
I've ported these over from https://github.com/dicej/component-async-demo
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
fix test regressions and clippy warnings
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
satisfy clippy
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
fix async tests when `component-model-async` enabled
Enabling this feature for all tests revealed various missing pieces in the new
`concurrent.rs` fiber mechanism, which I've addressed.
This adds a bunch of ugly `#[cfg(feature = "component-model-async")]` guards,
but those will all go away once I unify the two async fiber implementations.
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
add and modify tests to cover concurrent APIs
Primarily, this tests and implements cases where parameters and/or results must
be passed via linear memory instead of the stack.
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
`concurrent_{imports|exports}` component macro codegen tests
This enables codegen testing of the `concurrent_imports` and
`concurrent_exports` options to `wasmtime::component::bindgen` and also fixes
code generation for world-level function and resource exports that use the
concurrent call style.
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
`concurrent_{imports|exports}` component macro expanded tests
This enables testing of the `concurrent_imports` and `concurrent_exports`
options in `crates/component-macro/tests/expanded.rs`.
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
add tests/misc_testsuite/component-model-async/*.wast
These only test instantiation of components which use various async options and
built-ins so far. Next, I'll happy and sad path tests which actually execute
code.
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
appease clippy
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
add tests/misc_testsuite/component-model-async/fused.wast
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
add non-panicking bounds checks where appropriate
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
remove post-return bits from async result lift code
...at least until we've determined whether post-return options even make sense
for async-lifted exports.
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
fix component-model-async/fused.wast test failure
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
use `enum` types to represent status and event codes
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
fix component-model-async/fused.wast test failure (2nd try)
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
use `gc_types = true` in component-model-async/fused.wast
We use `Instruction::RefFunc` when generating adapters for async lifts and/or
lowers, which Winch doesn't understand, and apparently `gc_types = true` is what
tells the test infra not to use Winch.
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
trap if async function finishes without calling `task.return`
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
update wit-bindgen and fix rebase damage
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
call post-return function if any for async->sync fused calls
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
fix non-component-model-async build; appease clippy
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
bless bindgen output whitespace changes
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
enforce resource borrow requirements for async calls
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
update `wit-bindgen` and simplify `async_borrowing_callee` test
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
call `InstanceFlags::set_may_enter` where appropriate
There's still more work to do to fully implement (and test) the reentrance rules
for concurrent tasks, but this is a start.
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
finish implementing reentrance checks
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
feat: implement error-context (#1)
* feat: initial error-context implementation
This commit implements error-context related functions inside the VM,
along with tests to ensure that basic error-context.new and
error-context.debug-message functionality works.
Signed-off-by: Victor Adossi <vadossi@cosmonic.com>
* wip: add test for error context callee/caller transfer
Signed-off-by: Victor Adossi <vadossi@cosmonic.com>
* wip: test for async context transfer
Signed-off-by: Victor Adossi <vadossi@cosmonic.com>
---------
Signed-off-by: Victor Adossi <vadossi@cosmonic.com>
run cargo fmt
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
appease clippy
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
pull in Roman's unit stream work; add world-level export test
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
add unit stream tests
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
CI fixes
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
dicej added a commit to dicej/wasmtime that referenced this pull request Jan 29, 2025
This adds support for loading, compiling, linking, and running components which
use the [Async
ABI](https://github.com/WebAssembly/component-model/blob/main/design/mvp/Async.md)
along with the [`stream`, `future`, and
`error-context`](WebAssembly/component-model#405) types.
It also adds support for generating host bindings such that multiple host
functions can be run concurrently with guest tasks -- without monopolizing the
`Store`.
See the [implementation RFC](bytecodealliance/rfcs#38)
for details, as well as [this
repo](https://github.com/dicej/component-async-demo) containing end-to-end smoke
tests.
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
fix clippy warnings and bench/fuzzing errors
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
revert atomic.wit whitespace change
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
fix build when component-model disabled
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
bless component-macro expected output
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
fix no-std build error
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
fix build with --no-default-features --features runtime,component-model
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
partly fix no-std build
It's still broken due to the use of `std::collections::HashMap` in
crates/wasmtime/src/runtime/vm/component.rs. I'll address that as part of the
work to avoid exposing global task/future/stream/error-context handles to
guests.
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
maintain per-instance tables for futures, streams, and error-contexts
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
refactor task/stream/future handle lifting/lowering
This addresses a couple of issues:
- Previously, we were passing task/stream/future/error-context reps directly to
instances while keeping track of which instance had access to which rep. That
worked fine in that there was no way to forge access to inaccessible reps, but
it leaked information about what other instances were doing. Now we maintain
per-instance waitable and error-context tables which map the reps to and from
the handles which the instance sees.
- The `no_std` build was broken due to use of `HashMap` in
`runtime::vm::component`, which is now fixed.
Note that we use one single table per instance for all tasks, streams, and
futures. This is partly necessary because, when async events are delivered to
the guest, it wouldn't have enough context to know which stream or future we're
talking about if each unique stream and future type had its own table. So at
minimum, we need to use the same table for all streams (regardless of payload
type), and likewise for futures. Also, per
WebAssembly/component-model#395 (comment),
the plan is to move towards a shared table for all resource types as well, so
this moves us in that direction.
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
fix wave breakage due to new stream/future/error-context types
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
switch wasm-tools to v1.220.0-based branch
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
check `task.return` type at runtime
We can't statically verify a given call to `task.return` corresponds to the
expected core signature appropriate for the currently running task, so we must
do so at runtime. In order to make that check efficient, we intern the types.
My initial plan was to use `ModuleInternedTypeIndex` and/or `VMSharedTypeIndex`
for interning, but that got hairy with WasmGC considerations, so instead I added
new fields to `ComponentTypes` and `ComponentTypesBuilder`.
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
add `TypedFunc::call_concurrent` and refine stream/future APIs
This implements what I proposed in https://github.com/dicej/rfcs/blob/component-async/accepted/component-model-async.md#wasmtime. Specifically, it adds:
- A new `Promise` type, useful for working with concurrent operations that require access to a `Store` to make progress.
- A new `PromisesUnordered` type for `await`ing multiple promises concurrently
-`TypedFunc::call_concurrent` (which returns a `Promise`), allowing multiple host->guest calls to run concurrently on the same instance.
- Updated `{Stream|Future}{Writer|Reader}` APIs which use `Promise`
The upshot is that the embedder can now ergonomically manage arbitrary numbers
of concurrent operations. Previously, this was a lot more difficult to do
without accidentally starving some of the operations due to another one
monopolizing the `Store`.
Finally, this includes various refactorings and fixes for bugs exposed by the
newer, more versatile APIs.
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
clean up verbosity in component/func.rs
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
snapshot
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
implement stream/future read/write cancellation
This required a somewhat viral addition of `Send` and `Sync` bounds for async
host function closure types, unfortunately.
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
add `Func::call_concurrent` and `LinkerInstance::func_new_concurrent`
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
dynamic API support for streams/futures/error-contexts
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
support callback-less (AKA stackful) async lifts
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
fix `call_host` regression
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
add component model async end-to-end tests
I've ported these over from https://github.com/dicej/component-async-demo
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
fix test regressions and clippy warnings
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
satisfy clippy
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
fix async tests when `component-model-async` enabled
Enabling this feature for all tests revealed various missing pieces in the new
`concurrent.rs` fiber mechanism, which I've addressed.
This adds a bunch of ugly `#[cfg(feature = "component-model-async")]` guards,
but those will all go away once I unify the two async fiber implementations.
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
add and modify tests to cover concurrent APIs
Primarily, this tests and implements cases where parameters and/or results must
be passed via linear memory instead of the stack.
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
`concurrent_{imports|exports}` component macro codegen tests
This enables codegen testing of the `concurrent_imports` and
`concurrent_exports` options to `wasmtime::component::bindgen` and also fixes
code generation for world-level function and resource exports that use the
concurrent call style.
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
`concurrent_{imports|exports}` component macro expanded tests
This enables testing of the `concurrent_imports` and `concurrent_exports`
options in `crates/component-macro/tests/expanded.rs`.
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
add tests/misc_testsuite/component-model-async/*.wast
These only test instantiation of components which use various async options and
built-ins so far. Next, I'll happy and sad path tests which actually execute
code.
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
appease clippy
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
add tests/misc_testsuite/component-model-async/fused.wast
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
add non-panicking bounds checks where appropriate
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
remove post-return bits from async result lift code
...at least until we've determined whether post-return options even make sense
for async-lifted exports.
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
fix component-model-async/fused.wast test failure
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
use `enum` types to represent status and event codes
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
fix component-model-async/fused.wast test failure (2nd try)
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
use `gc_types = true` in component-model-async/fused.wast
We use `Instruction::RefFunc` when generating adapters for async lifts and/or
lowers, which Winch doesn't understand, and apparently `gc_types = true` is what
tells the test infra not to use Winch.
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
trap if async function finishes without calling `task.return`
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
update wit-bindgen and fix rebase damage
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
call post-return function if any for async->sync fused calls
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
fix non-component-model-async build; appease clippy
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
bless bindgen output whitespace changes
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
enforce resource borrow requirements for async calls
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
update `wit-bindgen` and simplify `async_borrowing_callee` test
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
call `InstanceFlags::set_may_enter` where appropriate
There's still more work to do to fully implement (and test) the reentrance rules
for concurrent tasks, but this is a start.
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
finish implementing reentrance checks
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
feat: implement error-context (#1)
* feat: initial error-context implementation
This commit implements error-context related functions inside the VM,
along with tests to ensure that basic error-context.new and
error-context.debug-message functionality works.
Signed-off-by: Victor Adossi <vadossi@cosmonic.com>
* wip: add test for error context callee/caller transfer
Signed-off-by: Victor Adossi <vadossi@cosmonic.com>
* wip: test for async context transfer
Signed-off-by: Victor Adossi <vadossi@cosmonic.com>
---------
Signed-off-by: Victor Adossi <vadossi@cosmonic.com>
run cargo fmt
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
appease clippy
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
pull in Roman's unit stream work; add world-level export test
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
add unit stream tests
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
CI fixes
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
dicej added a commit to dicej/wasmtime that referenced this pull request Jan 30, 2025
This is another piece of bytecodealliance#9582 which I'm splitting out to make review easier.
This test exercises fused adapter generation for various flavors of
intercomponent async->async, async->sync, and sync->async calls.
The remaining changes fill in some TODOs to make the test pass.
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
address review feedback
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
update `task.return` to match spec
This temporarily switches to my fork of `wasm-tools` until
bytecodealliance/wasm-tools#1989 is merged.
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
refactor `component-model-async` cfg attrs per review feedback
Also, switch to upstream `wasm-tools` main branch.
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
add `Compiler::new` constructor
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
add comments covering various lower/lift combos in FACT generator
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
add `Compiler::global_set` helper function
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
add component-model-async/task-builtins.wast test
This is another piece of bytecodealliance#9582 which I'm splitting out to make review easier.
This test includes components which use the `task.backpressure`, `task.return`,
`task.wait`, `task.poll`, `task.yield`, and `subtask.drop` builtins.
The rest of the changes fill in some TODOs to make the test pass.
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
Add support for async/streams/futures
This adds support for loading, compiling, linking, and running components which
use the [Async
ABI](https://github.com/WebAssembly/component-model/blob/main/design/mvp/Async.md)
along with the [`stream`, `future`, and
`error-context`](WebAssembly/component-model#405) types.
It also adds support for generating host bindings such that multiple host
functions can be run concurrently with guest tasks -- without monopolizing the
`Store`.
See the [implementation RFC](bytecodealliance/rfcs#38)
for details, as well as [this
repo](https://github.com/dicej/component-async-demo) containing end-to-end smoke
tests.
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
fix clippy warnings and bench/fuzzing errors
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
revert atomic.wit whitespace change
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
fix build when component-model disabled
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
bless component-macro expected output
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
fix no-std build error
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
fix build with --no-default-features --features runtime,component-model
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
partly fix no-std build
It's still broken due to the use of `std::collections::HashMap` in
crates/wasmtime/src/runtime/vm/component.rs. I'll address that as part of the
work to avoid exposing global task/future/stream/error-context handles to
guests.
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
maintain per-instance tables for futures, streams, and error-contexts
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
refactor task/stream/future handle lifting/lowering
This addresses a couple of issues:
- Previously, we were passing task/stream/future/error-context reps directly to
instances while keeping track of which instance had access to which rep. That
worked fine in that there was no way to forge access to inaccessible reps, but
it leaked information about what other instances were doing. Now we maintain
per-instance waitable and error-context tables which map the reps to and from
the handles which the instance sees.
- The `no_std` build was broken due to use of `HashMap` in
`runtime::vm::component`, which is now fixed.
Note that we use one single table per instance for all tasks, streams, and
futures. This is partly necessary because, when async events are delivered to
the guest, it wouldn't have enough context to know which stream or future we're
talking about if each unique stream and future type had its own table. So at
minimum, we need to use the same table for all streams (regardless of payload
type), and likewise for futures. Also, per
WebAssembly/component-model#395 (comment),
the plan is to move towards a shared table for all resource types as well, so
this moves us in that direction.
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
fix wave breakage due to new stream/future/error-context types
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
switch wasm-tools to v1.220.0-based branch
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
check `task.return` type at runtime
We can't statically verify a given call to `task.return` corresponds to the
expected core signature appropriate for the currently running task, so we must
do so at runtime. In order to make that check efficient, we intern the types.
My initial plan was to use `ModuleInternedTypeIndex` and/or `VMSharedTypeIndex`
for interning, but that got hairy with WasmGC considerations, so instead I added
new fields to `ComponentTypes` and `ComponentTypesBuilder`.
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
add `TypedFunc::call_concurrent` and refine stream/future APIs
This implements what I proposed in https://github.com/dicej/rfcs/blob/component-async/accepted/component-model-async.md#wasmtime. Specifically, it adds:
- A new `Promise` type, useful for working with concurrent operations that require access to a `Store` to make progress.
- A new `PromisesUnordered` type for `await`ing multiple promises concurrently
-`TypedFunc::call_concurrent` (which returns a `Promise`), allowing multiple host->guest calls to run concurrently on the same instance.
- Updated `{Stream|Future}{Writer|Reader}` APIs which use `Promise`
The upshot is that the embedder can now ergonomically manage arbitrary numbers
of concurrent operations. Previously, this was a lot more difficult to do
without accidentally starving some of the operations due to another one
monopolizing the `Store`.
Finally, this includes various refactorings and fixes for bugs exposed by the
newer, more versatile APIs.
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
clean up verbosity in component/func.rs
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
snapshot
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
implement stream/future read/write cancellation
This required a somewhat viral addition of `Send` and `Sync` bounds for async
host function closure types, unfortunately.
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
add `Func::call_concurrent` and `LinkerInstance::func_new_concurrent`
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
dynamic API support for streams/futures/error-contexts
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
support callback-less (AKA stackful) async lifts
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
fix `call_host` regression
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
add component model async end-to-end tests
I've ported these over from https://github.com/dicej/component-async-demo
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
fix test regressions and clippy warnings
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
satisfy clippy
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
fix async tests when `component-model-async` enabled
Enabling this feature for all tests revealed various missing pieces in the new
`concurrent.rs` fiber mechanism, which I've addressed.
This adds a bunch of ugly `#[cfg(feature = "component-model-async")]` guards,
but those will all go away once I unify the two async fiber implementations.
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
add and modify tests to cover concurrent APIs
Primarily, this tests and implements cases where parameters and/or results must
be passed via linear memory instead of the stack.
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
`concurrent_{imports|exports}` component macro codegen tests
This enables codegen testing of the `concurrent_imports` and
`concurrent_exports` options to `wasmtime::component::bindgen` and also fixes
code generation for world-level function and resource exports that use the
concurrent call style.
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
`concurrent_{imports|exports}` component macro expanded tests
This enables testing of the `concurrent_imports` and `concurrent_exports`
options in `crates/component-macro/tests/expanded.rs`.
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
add tests/misc_testsuite/component-model-async/*.wast
These only test instantiation of components which use various async options and
built-ins so far. Next, I'll happy and sad path tests which actually execute
code.
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
appease clippy
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
add tests/misc_testsuite/component-model-async/fused.wast
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
add non-panicking bounds checks where appropriate
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
remove post-return bits from async result lift code
...at least until we've determined whether post-return options even make sense
for async-lifted exports.
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
fix component-model-async/fused.wast test failure
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
use `enum` types to represent status and event codes
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
fix component-model-async/fused.wast test failure (2nd try)
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
use `gc_types = true` in component-model-async/fused.wast
We use `Instruction::RefFunc` when generating adapters for async lifts and/or
lowers, which Winch doesn't understand, and apparently `gc_types = true` is what
tells the test infra not to use Winch.
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
trap if async function finishes without calling `task.return`
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
update wit-bindgen and fix rebase damage
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
call post-return function if any for async->sync fused calls
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
fix non-component-model-async build; appease clippy
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
bless bindgen output whitespace changes
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
enforce resource borrow requirements for async calls
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
update `wit-bindgen` and simplify `async_borrowing_callee` test
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
call `InstanceFlags::set_may_enter` where appropriate
There's still more work to do to fully implement (and test) the reentrance rules
for concurrent tasks, but this is a start.
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
finish implementing reentrance checks
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
feat: implement error-context (#1)
* feat: initial error-context implementation
This commit implements error-context related functions inside the VM,
along with tests to ensure that basic error-context.new and
error-context.debug-message functionality works.
Signed-off-by: Victor Adossi <vadossi@cosmonic.com>
* wip: add test for error context callee/caller transfer
Signed-off-by: Victor Adossi <vadossi@cosmonic.com>
* wip: test for async context transfer
Signed-off-by: Victor Adossi <vadossi@cosmonic.com>
---------
Signed-off-by: Victor Adossi <vadossi@cosmonic.com>
run cargo fmt
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
appease clippy
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
pull in Roman's unit stream work; add world-level export test
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
add unit stream tests
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
CI fixes
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
dicej added a commit to dicej/wasmtime that referenced this pull request Feb 1, 2025
This adds support for loading, compiling, linking, and running components which
use the [Async
ABI](https://github.com/WebAssembly/component-model/blob/main/design/mvp/Async.md)
along with the [`stream`, `future`, and
`error-context`](WebAssembly/component-model#405) types.
It also adds support for generating host bindings such that multiple host
functions can be run concurrently with guest tasks -- without monopolizing the
`Store`.
See the [implementation RFC](bytecodealliance/rfcs#38)
for details, as well as [this
repo](https://github.com/dicej/component-async-demo) containing end-to-end smoke
tests.
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
fix clippy warnings and bench/fuzzing errors
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
revert atomic.wit whitespace change
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
fix build when component-model disabled
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
bless component-macro expected output
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
fix no-std build error
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
fix build with --no-default-features --features runtime,component-model
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
partly fix no-std build
It's still broken due to the use of `std::collections::HashMap` in
crates/wasmtime/src/runtime/vm/component.rs. I'll address that as part of the
work to avoid exposing global task/future/stream/error-context handles to
guests.
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
maintain per-instance tables for futures, streams, and error-contexts
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
refactor task/stream/future handle lifting/lowering
This addresses a couple of issues:
- Previously, we were passing task/stream/future/error-context reps directly to
instances while keeping track of which instance had access to which rep. That
worked fine in that there was no way to forge access to inaccessible reps, but
it leaked information about what other instances were doing. Now we maintain
per-instance waitable and error-context tables which map the reps to and from
the handles which the instance sees.
- The `no_std` build was broken due to use of `HashMap` in
`runtime::vm::component`, which is now fixed.
Note that we use one single table per instance for all tasks, streams, and
futures. This is partly necessary because, when async events are delivered to
the guest, it wouldn't have enough context to know which stream or future we're
talking about if each unique stream and future type had its own table. So at
minimum, we need to use the same table for all streams (regardless of payload
type), and likewise for futures. Also, per
WebAssembly/component-model#395 (comment),
the plan is to move towards a shared table for all resource types as well, so
this moves us in that direction.
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
fix wave breakage due to new stream/future/error-context types
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
switch wasm-tools to v1.220.0-based branch
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
check `task.return` type at runtime
We can't statically verify a given call to `task.return` corresponds to the
expected core signature appropriate for the currently running task, so we must
do so at runtime. In order to make that check efficient, we intern the types.
My initial plan was to use `ModuleInternedTypeIndex` and/or `VMSharedTypeIndex`
for interning, but that got hairy with WasmGC considerations, so instead I added
new fields to `ComponentTypes` and `ComponentTypesBuilder`.
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
add `TypedFunc::call_concurrent` and refine stream/future APIs
This implements what I proposed in https://github.com/dicej/rfcs/blob/component-async/accepted/component-model-async.md#wasmtime. Specifically, it adds:
- A new `Promise` type, useful for working with concurrent operations that require access to a `Store` to make progress.
- A new `PromisesUnordered` type for `await`ing multiple promises concurrently
-`TypedFunc::call_concurrent` (which returns a `Promise`), allowing multiple host->guest calls to run concurrently on the same instance.
- Updated `{Stream|Future}{Writer|Reader}` APIs which use `Promise`
The upshot is that the embedder can now ergonomically manage arbitrary numbers
of concurrent operations. Previously, this was a lot more difficult to do
without accidentally starving some of the operations due to another one
monopolizing the `Store`.
Finally, this includes various refactorings and fixes for bugs exposed by the
newer, more versatile APIs.
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
clean up verbosity in component/func.rs
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
snapshot
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
implement stream/future read/write cancellation
This required a somewhat viral addition of `Send` and `Sync` bounds for async
host function closure types, unfortunately.
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
add `Func::call_concurrent` and `LinkerInstance::func_new_concurrent`
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
dynamic API support for streams/futures/error-contexts
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
support callback-less (AKA stackful) async lifts
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
fix `call_host` regression
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
add component model async end-to-end tests
I've ported these over from https://github.com/dicej/component-async-demo
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
fix test regressions and clippy warnings
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
satisfy clippy
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
fix async tests when `component-model-async` enabled
Enabling this feature for all tests revealed various missing pieces in the new
`concurrent.rs` fiber mechanism, which I've addressed.
This adds a bunch of ugly `#[cfg(feature = "component-model-async")]` guards,
but those will all go away once I unify the two async fiber implementations.
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
add and modify tests to cover concurrent APIs
Primarily, this tests and implements cases where parameters and/or results must
be passed via linear memory instead of the stack.
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
`concurrent_{imports|exports}` component macro codegen tests
This enables codegen testing of the `concurrent_imports` and
`concurrent_exports` options to `wasmtime::component::bindgen` and also fixes
code generation for world-level function and resource exports that use the
concurrent call style.
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
`concurrent_{imports|exports}` component macro expanded tests
This enables testing of the `concurrent_imports` and `concurrent_exports`
options in `crates/component-macro/tests/expanded.rs`.
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
add tests/misc_testsuite/component-model-async/*.wast
These only test instantiation of components which use various async options and
built-ins so far. Next, I'll happy and sad path tests which actually execute
code.
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
appease clippy
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
add tests/misc_testsuite/component-model-async/fused.wast
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
add non-panicking bounds checks where appropriate
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
remove post-return bits from async result lift code
...at least until we've determined whether post-return options even make sense
for async-lifted exports.
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
fix component-model-async/fused.wast test failure
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
use `enum` types to represent status and event codes
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
fix component-model-async/fused.wast test failure (2nd try)
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
use `gc_types = true` in component-model-async/fused.wast
We use `Instruction::RefFunc` when generating adapters for async lifts and/or
lowers, which Winch doesn't understand, and apparently `gc_types = true` is what
tells the test infra not to use Winch.
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
trap if async function finishes without calling `task.return`
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
update wit-bindgen and fix rebase damage
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
call post-return function if any for async->sync fused calls
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
fix non-component-model-async build; appease clippy
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
bless bindgen output whitespace changes
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
enforce resource borrow requirements for async calls
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
update `wit-bindgen` and simplify `async_borrowing_callee` test
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
call `InstanceFlags::set_may_enter` where appropriate
There's still more work to do to fully implement (and test) the reentrance rules
for concurrent tasks, but this is a start.
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
finish implementing reentrance checks
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
feat: implement error-context (#1)
* feat: initial error-context implementation
This commit implements error-context related functions inside the VM,
along with tests to ensure that basic error-context.new and
error-context.debug-message functionality works.
Signed-off-by: Victor Adossi <vadossi@cosmonic.com>
* wip: add test for error context callee/caller transfer
Signed-off-by: Victor Adossi <vadossi@cosmonic.com>
* wip: test for async context transfer
Signed-off-by: Victor Adossi <vadossi@cosmonic.com>
---------
Signed-off-by: Victor Adossi <vadossi@cosmonic.com>
run cargo fmt
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
appease clippy
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
pull in Roman's unit stream work; add world-level export test
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
add unit stream tests
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
CI fixes
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
fix non-component-model-async build
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
add round-trip tests with many parameters and results
This adds tests to cover round-tripping values whose flattened form exceed
`MAX_FLAT_PARAMS`. Although we already had tests to cover this in
tests/all/component_model/func.rs, those tests did not involve any flavor of
composition; these do.
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
test: add multiple send as initial context stream test
Signed-off-by: Victor Adossi <vadossi@cosmonic.com>
fix Victor's test case
Turns out this was the first test case where the host calls a component via an
async-lifted export, which in turn calls another component's async-lifted export
via a sync-lowered import, which didn't work. Now it does!
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
refactor sync->async component call adapters
We no longer use global variables to stash parameters and results due to the
hazard of concurrent calls clobbering them. Instead, we now stash them in the
`GuestTask` object for the task.
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
dicej added a commit to dicej/wasmtime that referenced this pull request Feb 1, 2025
This adds support for loading, compiling, linking, and running components which
use the [Async
ABI](https://github.com/WebAssembly/component-model/blob/main/design/mvp/Async.md)
along with the [`stream`, `future`, and
`error-context`](WebAssembly/component-model#405) types.
It also adds support for generating host bindings such that multiple host
functions can be run concurrently with guest tasks -- without monopolizing the
`Store`.
See the [implementation RFC](bytecodealliance/rfcs#38)
for details, as well as [this
repo](https://github.com/dicej/component-async-demo) containing end-to-end smoke
tests.
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
fix clippy warnings and bench/fuzzing errors
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
revert atomic.wit whitespace change
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
fix build when component-model disabled
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
bless component-macro expected output
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
fix no-std build error
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
fix build with --no-default-features --features runtime,component-model
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
partly fix no-std build
It's still broken due to the use of `std::collections::HashMap` in
crates/wasmtime/src/runtime/vm/component.rs. I'll address that as part of the
work to avoid exposing global task/future/stream/error-context handles to
guests.
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
maintain per-instance tables for futures, streams, and error-contexts
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
refactor task/stream/future handle lifting/lowering
This addresses a couple of issues:
- Previously, we were passing task/stream/future/error-context reps directly to
instances while keeping track of which instance had access to which rep. That
worked fine in that there was no way to forge access to inaccessible reps, but
it leaked information about what other instances were doing. Now we maintain
per-instance waitable and error-context tables which map the reps to and from
the handles which the instance sees.
- The `no_std` build was broken due to use of `HashMap` in
`runtime::vm::component`, which is now fixed.
Note that we use one single table per instance for all tasks, streams, and
futures. This is partly necessary because, when async events are delivered to
the guest, it wouldn't have enough context to know which stream or future we're
talking about if each unique stream and future type had its own table. So at
minimum, we need to use the same table for all streams (regardless of payload
type), and likewise for futures. Also, per
WebAssembly/component-model#395 (comment),
the plan is to move towards a shared table for all resource types as well, so
this moves us in that direction.
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
fix wave breakage due to new stream/future/error-context types
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
switch wasm-tools to v1.220.0-based branch
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
check `task.return` type at runtime
We can't statically verify a given call to `task.return` corresponds to the
expected core signature appropriate for the currently running task, so we must
do so at runtime. In order to make that check efficient, we intern the types.
My initial plan was to use `ModuleInternedTypeIndex` and/or `VMSharedTypeIndex`
for interning, but that got hairy with WasmGC considerations, so instead I added
new fields to `ComponentTypes` and `ComponentTypesBuilder`.
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
add `TypedFunc::call_concurrent` and refine stream/future APIs
This implements what I proposed in https://github.com/dicej/rfcs/blob/component-async/accepted/component-model-async.md#wasmtime. Specifically, it adds:
- A new `Promise` type, useful for working with concurrent operations that require access to a `Store` to make progress.
- A new `PromisesUnordered` type for `await`ing multiple promises concurrently
-`TypedFunc::call_concurrent` (which returns a `Promise`), allowing multiple host->guest calls to run concurrently on the same instance.
- Updated `{Stream|Future}{Writer|Reader}` APIs which use `Promise`
The upshot is that the embedder can now ergonomically manage arbitrary numbers
of concurrent operations. Previously, this was a lot more difficult to do
without accidentally starving some of the operations due to another one
monopolizing the `Store`.
Finally, this includes various refactorings and fixes for bugs exposed by the
newer, more versatile APIs.
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
clean up verbosity in component/func.rs
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
snapshot
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
implement stream/future read/write cancellation
This required a somewhat viral addition of `Send` and `Sync` bounds for async
host function closure types, unfortunately.
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
add `Func::call_concurrent` and `LinkerInstance::func_new_concurrent`
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
dynamic API support for streams/futures/error-contexts
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
support callback-less (AKA stackful) async lifts
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
fix `call_host` regression
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
add component model async end-to-end tests
I've ported these over from https://github.com/dicej/component-async-demo
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
fix test regressions and clippy warnings
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
satisfy clippy
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
fix async tests when `component-model-async` enabled
Enabling this feature for all tests revealed various missing pieces in the new
`concurrent.rs` fiber mechanism, which I've addressed.
This adds a bunch of ugly `#[cfg(feature = "component-model-async")]` guards,
but those will all go away once I unify the two async fiber implementations.
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
add and modify tests to cover concurrent APIs
Primarily, this tests and implements cases where parameters and/or results must
be passed via linear memory instead of the stack.
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
`concurrent_{imports|exports}` component macro codegen tests
This enables codegen testing of the `concurrent_imports` and
`concurrent_exports` options to `wasmtime::component::bindgen` and also fixes
code generation for world-level function and resource exports that use the
concurrent call style.
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
`concurrent_{imports|exports}` component macro expanded tests
This enables testing of the `concurrent_imports` and `concurrent_exports`
options in `crates/component-macro/tests/expanded.rs`.
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
add tests/misc_testsuite/component-model-async/*.wast
These only test instantiation of components which use various async options and
built-ins so far. Next, I'll happy and sad path tests which actually execute
code.
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
appease clippy
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
add tests/misc_testsuite/component-model-async/fused.wast
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
add non-panicking bounds checks where appropriate
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
remove post-return bits from async result lift code
...at least until we've determined whether post-return options even make sense
for async-lifted exports.
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
fix component-model-async/fused.wast test failure
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
use `enum` types to represent status and event codes
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
fix component-model-async/fused.wast test failure (2nd try)
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
use `gc_types = true` in component-model-async/fused.wast
We use `Instruction::RefFunc` when generating adapters for async lifts and/or
lowers, which Winch doesn't understand, and apparently `gc_types = true` is what
tells the test infra not to use Winch.
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
trap if async function finishes without calling `task.return`
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
update wit-bindgen and fix rebase damage
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
call post-return function if any for async->sync fused calls
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
fix non-component-model-async build; appease clippy
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
bless bindgen output whitespace changes
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
enforce resource borrow requirements for async calls
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
update `wit-bindgen` and simplify `async_borrowing_callee` test
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
call `InstanceFlags::set_may_enter` where appropriate
There's still more work to do to fully implement (and test) the reentrance rules
for concurrent tasks, but this is a start.
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
finish implementing reentrance checks
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
feat: implement error-context (#1)
* feat: initial error-context implementation
This commit implements error-context related functions inside the VM,
along with tests to ensure that basic error-context.new and
error-context.debug-message functionality works.
Signed-off-by: Victor Adossi <vadossi@cosmonic.com>
* wip: add test for error context callee/caller transfer
Signed-off-by: Victor Adossi <vadossi@cosmonic.com>
* wip: test for async context transfer
Signed-off-by: Victor Adossi <vadossi@cosmonic.com>
---------
Signed-off-by: Victor Adossi <vadossi@cosmonic.com>
run cargo fmt
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
appease clippy
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
pull in Roman's unit stream work; add world-level export test
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
add unit stream tests
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
CI fixes
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
fix non-component-model-async build
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
add round-trip tests with many parameters and results
This adds tests to cover round-tripping values whose flattened form exceed
`MAX_FLAT_PARAMS`. Although we already had tests to cover this in
tests/all/component_model/func.rs, those tests did not involve any flavor of
composition; these do.
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
test: add multiple send as initial context stream test
Signed-off-by: Victor Adossi <vadossi@cosmonic.com>
fix Victor's test case
Turns out this was the first test case where the host calls a component via an
async-lifted export, which in turn calls another component's async-lifted export
via a sync-lowered import, which didn't work. Now it does!
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
refactor sync->async component call adapters
We no longer use global variables to stash parameters and results due to the
hazard of concurrent calls clobbering them. Instead, we now stash them in the
`GuestTask` object for the task.
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
dicej added a commit to dicej/wasmtime that referenced this pull request Feb 1, 2025
This adds support for loading, compiling, linking, and running components which
use the [Async
ABI](https://github.com/WebAssembly/component-model/blob/main/design/mvp/Async.md)
along with the [`stream`, `future`, and
`error-context`](WebAssembly/component-model#405) types.
It also adds support for generating host bindings such that multiple host
functions can be run concurrently with guest tasks -- without monopolizing the
`Store`.
See the [implementation RFC](bytecodealliance/rfcs#38)
for details, as well as [this
repo](https://github.com/dicej/component-async-demo) containing end-to-end smoke
tests.
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
fix clippy warnings and bench/fuzzing errors
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
revert atomic.wit whitespace change
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
fix build when component-model disabled
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
bless component-macro expected output
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
fix no-std build error
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
fix build with --no-default-features --features runtime,component-model
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
partly fix no-std build
It's still broken due to the use of `std::collections::HashMap` in
crates/wasmtime/src/runtime/vm/component.rs. I'll address that as part of the
work to avoid exposing global task/future/stream/error-context handles to
guests.
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
maintain per-instance tables for futures, streams, and error-contexts
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
refactor task/stream/future handle lifting/lowering
This addresses a couple of issues:
- Previously, we were passing task/stream/future/error-context reps directly to
instances while keeping track of which instance had access to which rep. That
worked fine in that there was no way to forge access to inaccessible reps, but
it leaked information about what other instances were doing. Now we maintain
per-instance waitable and error-context tables which map the reps to and from
the handles which the instance sees.
- The `no_std` build was broken due to use of `HashMap` in
`runtime::vm::component`, which is now fixed.
Note that we use one single table per instance for all tasks, streams, and
futures. This is partly necessary because, when async events are delivered to
the guest, it wouldn't have enough context to know which stream or future we're
talking about if each unique stream and future type had its own table. So at
minimum, we need to use the same table for all streams (regardless of payload
type), and likewise for futures. Also, per
WebAssembly/component-model#395 (comment),
the plan is to move towards a shared table for all resource types as well, so
this moves us in that direction.
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
fix wave breakage due to new stream/future/error-context types
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
switch wasm-tools to v1.220.0-based branch
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
check `task.return` type at runtime
We can't statically verify a given call to `task.return` corresponds to the
expected core signature appropriate for the currently running task, so we must
do so at runtime. In order to make that check efficient, we intern the types.
My initial plan was to use `ModuleInternedTypeIndex` and/or `VMSharedTypeIndex`
for interning, but that got hairy with WasmGC considerations, so instead I added
new fields to `ComponentTypes` and `ComponentTypesBuilder`.
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
add `TypedFunc::call_concurrent` and refine stream/future APIs
This implements what I proposed in https://github.com/dicej/rfcs/blob/component-async/accepted/component-model-async.md#wasmtime. Specifically, it adds:
- A new `Promise` type, useful for working with concurrent operations that require access to a `Store` to make progress.
- A new `PromisesUnordered` type for `await`ing multiple promises concurrently
-`TypedFunc::call_concurrent` (which returns a `Promise`), allowing multiple host->guest calls to run concurrently on the same instance.
- Updated `{Stream|Future}{Writer|Reader}` APIs which use `Promise`
The upshot is that the embedder can now ergonomically manage arbitrary numbers
of concurrent operations. Previously, this was a lot more difficult to do
without accidentally starving some of the operations due to another one
monopolizing the `Store`.
Finally, this includes various refactorings and fixes for bugs exposed by the
newer, more versatile APIs.
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
clean up verbosity in component/func.rs
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
snapshot
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
implement stream/future read/write cancellation
This required a somewhat viral addition of `Send` and `Sync` bounds for async
host function closure types, unfortunately.
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
add `Func::call_concurrent` and `LinkerInstance::func_new_concurrent`
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
dynamic API support for streams/futures/error-contexts
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
support callback-less (AKA stackful) async lifts
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
fix `call_host` regression
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
add component model async end-to-end tests
I've ported these over from https://github.com/dicej/component-async-demo
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
fix test regressions and clippy warnings
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
satisfy clippy
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
fix async tests when `component-model-async` enabled
Enabling this feature for all tests revealed various missing pieces in the new
`concurrent.rs` fiber mechanism, which I've addressed.
This adds a bunch of ugly `#[cfg(feature = "component-model-async")]` guards,
but those will all go away once I unify the two async fiber implementations.
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
add and modify tests to cover concurrent APIs
Primarily, this tests and implements cases where parameters and/or results must
be passed via linear memory instead of the stack.
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
`concurrent_{imports|exports}` component macro codegen tests
This enables codegen testing of the `concurrent_imports` and
`concurrent_exports` options to `wasmtime::component::bindgen` and also fixes
code generation for world-level function and resource exports that use the
concurrent call style.
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
`concurrent_{imports|exports}` component macro expanded tests
This enables testing of the `concurrent_imports` and `concurrent_exports`
options in `crates/component-macro/tests/expanded.rs`.
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
add tests/misc_testsuite/component-model-async/*.wast
These only test instantiation of components which use various async options and
built-ins so far. Next, I'll happy and sad path tests which actually execute
code.
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
appease clippy
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
add tests/misc_testsuite/component-model-async/fused.wast
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
add non-panicking bounds checks where appropriate
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
remove post-return bits from async result lift code
...at least until we've determined whether post-return options even make sense
for async-lifted exports.
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
fix component-model-async/fused.wast test failure
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
use `enum` types to represent status and event codes
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
fix component-model-async/fused.wast test failure (2nd try)
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
use `gc_types = true` in component-model-async/fused.wast
We use `Instruction::RefFunc` when generating adapters for async lifts and/or
lowers, which Winch doesn't understand, and apparently `gc_types = true` is what
tells the test infra not to use Winch.
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
trap if async function finishes without calling `task.return`
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
update wit-bindgen and fix rebase damage
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
call post-return function if any for async->sync fused calls
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
fix non-component-model-async build; appease clippy
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
bless bindgen output whitespace changes
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
enforce resource borrow requirements for async calls
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
update `wit-bindgen` and simplify `async_borrowing_callee` test
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
call `InstanceFlags::set_may_enter` where appropriate
There's still more work to do to fully implement (and test) the reentrance rules
for concurrent tasks, but this is a start.
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
finish implementing reentrance checks
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
feat: implement error-context (#1)
* feat: initial error-context implementation
This commit implements error-context related functions inside the VM,
along with tests to ensure that basic error-context.new and
error-context.debug-message functionality works.
Signed-off-by: Victor Adossi <vadossi@cosmonic.com>
* wip: add test for error context callee/caller transfer
Signed-off-by: Victor Adossi <vadossi@cosmonic.com>
* wip: test for async context transfer
Signed-off-by: Victor Adossi <vadossi@cosmonic.com>
---------
Signed-off-by: Victor Adossi <vadossi@cosmonic.com>
run cargo fmt
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
appease clippy
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
pull in Roman's unit stream work; add world-level export test
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
add unit stream tests
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
CI fixes
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
fix non-component-model-async build
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
add round-trip tests with many parameters and results
This adds tests to cover round-tripping values whose flattened form exceed
`MAX_FLAT_PARAMS`. Although we already had tests to cover this in
tests/all/component_model/func.rs, those tests did not involve any flavor of
composition; these do.
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
test: add multiple send as initial context stream test
Signed-off-by: Victor Adossi <vadossi@cosmonic.com>
fix Victor's test case
Turns out this was the first test case where the host calls a component via an
async-lifted export, which in turn calls another component's async-lifted export
via a sync-lowered import, which didn't work. Now it does!
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
refactor sync->async component call adapters
We no longer use global variables to stash parameters and results due to the
hazard of concurrent calls clobbering them. Instead, we now stash them in the
`GuestTask` object for the task.
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
rvolosatovs pushed a commit to bytecodealliance/wasip3-prototyping that referenced this pull request Feb 3, 2025
This adds support for loading, compiling, linking, and running components which
use the [Async
ABI](https://github.com/WebAssembly/component-model/blob/main/design/mvp/Async.md)
along with the [`stream`, `future`, and
`error-context`](WebAssembly/component-model#405) types.
It also adds support for generating host bindings such that multiple host
functions can be run concurrently with guest tasks -- without monopolizing the
`Store`.
See the [implementation RFC](bytecodealliance/rfcs#38)
for details, as well as [this
repo](https://github.com/dicej/component-async-demo) containing end-to-end smoke
tests.
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
fix clippy warnings and bench/fuzzing errors
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
revert atomic.wit whitespace change
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
fix build when component-model disabled
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
bless component-macro expected output
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
fix no-std build error
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
fix build with --no-default-features --features runtime,component-model
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
partly fix no-std build
It's still broken due to the use of `std::collections::HashMap` in
crates/wasmtime/src/runtime/vm/component.rs. I'll address that as part of the
work to avoid exposing global task/future/stream/error-context handles to
guests.
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
maintain per-instance tables for futures, streams, and error-contexts
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
refactor task/stream/future handle lifting/lowering
This addresses a couple of issues:
- Previously, we were passing task/stream/future/error-context reps directly to
instances while keeping track of which instance had access to which rep. That
worked fine in that there was no way to forge access to inaccessible reps, but
it leaked information about what other instances were doing. Now we maintain
per-instance waitable and error-context tables which map the reps to and from
the handles which the instance sees.
- The `no_std` build was broken due to use of `HashMap` in
`runtime::vm::component`, which is now fixed.
Note that we use one single table per instance for all tasks, streams, and
futures. This is partly necessary because, when async events are delivered to
the guest, it wouldn't have enough context to know which stream or future we're
talking about if each unique stream and future type had its own table. So at
minimum, we need to use the same table for all streams (regardless of payload
type), and likewise for futures. Also, per
WebAssembly/component-model#395 (comment),
the plan is to move towards a shared table for all resource types as well, so
this moves us in that direction.
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
fix wave breakage due to new stream/future/error-context types
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
switch wasm-tools to v1.220.0-based branch
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
check `task.return` type at runtime
We can't statically verify a given call to `task.return` corresponds to the
expected core signature appropriate for the currently running task, so we must
do so at runtime. In order to make that check efficient, we intern the types.
My initial plan was to use `ModuleInternedTypeIndex` and/or `VMSharedTypeIndex`
for interning, but that got hairy with WasmGC considerations, so instead I added
new fields to `ComponentTypes` and `ComponentTypesBuilder`.
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
add `TypedFunc::call_concurrent` and refine stream/future APIs
This implements what I proposed in https://github.com/dicej/rfcs/blob/component-async/accepted/component-model-async.md#wasmtime. Specifically, it adds:
- A new `Promise` type, useful for working with concurrent operations that require access to a `Store` to make progress.
- A new `PromisesUnordered` type for `await`ing multiple promises concurrently
-`TypedFunc::call_concurrent` (which returns a `Promise`), allowing multiple host->guest calls to run concurrently on the same instance.
- Updated `{Stream|Future}{Writer|Reader}` APIs which use `Promise`
The upshot is that the embedder can now ergonomically manage arbitrary numbers
of concurrent operations. Previously, this was a lot more difficult to do
without accidentally starving some of the operations due to another one
monopolizing the `Store`.
Finally, this includes various refactorings and fixes for bugs exposed by the
newer, more versatile APIs.
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
clean up verbosity in component/func.rs
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
snapshot
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
implement stream/future read/write cancellation
This required a somewhat viral addition of `Send` and `Sync` bounds for async
host function closure types, unfortunately.
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
add `Func::call_concurrent` and `LinkerInstance::func_new_concurrent`
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
dynamic API support for streams/futures/error-contexts
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
support callback-less (AKA stackful) async lifts
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
fix `call_host` regression
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
add component model async end-to-end tests
I've ported these over from https://github.com/dicej/component-async-demo
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
fix test regressions and clippy warnings
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
satisfy clippy
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
fix async tests when `component-model-async` enabled
Enabling this feature for all tests revealed various missing pieces in the new
`concurrent.rs` fiber mechanism, which I've addressed.
This adds a bunch of ugly `#[cfg(feature = "component-model-async")]` guards,
but those will all go away once I unify the two async fiber implementations.
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
add and modify tests to cover concurrent APIs
Primarily, this tests and implements cases where parameters and/or results must
be passed via linear memory instead of the stack.
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
`concurrent_{imports|exports}` component macro codegen tests
This enables codegen testing of the `concurrent_imports` and
`concurrent_exports` options to `wasmtime::component::bindgen` and also fixes
code generation for world-level function and resource exports that use the
concurrent call style.
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
`concurrent_{imports|exports}` component macro expanded tests
This enables testing of the `concurrent_imports` and `concurrent_exports`
options in `crates/component-macro/tests/expanded.rs`.
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
add tests/misc_testsuite/component-model-async/*.wast
These only test instantiation of components which use various async options and
built-ins so far. Next, I'll happy and sad path tests which actually execute
code.
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
appease clippy
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
add tests/misc_testsuite/component-model-async/fused.wast
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
add non-panicking bounds checks where appropriate
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
remove post-return bits from async result lift code
...at least until we've determined whether post-return options even make sense
for async-lifted exports.
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
fix component-model-async/fused.wast test failure
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
use `enum` types to represent status and event codes
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
fix component-model-async/fused.wast test failure (2nd try)
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
use `gc_types = true` in component-model-async/fused.wast
We use `Instruction::RefFunc` when generating adapters for async lifts and/or
lowers, which Winch doesn't understand, and apparently `gc_types = true` is what
tells the test infra not to use Winch.
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
trap if async function finishes without calling `task.return`
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
update wit-bindgen and fix rebase damage
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
call post-return function if any for async->sync fused calls
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
fix non-component-model-async build; appease clippy
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
bless bindgen output whitespace changes
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
enforce resource borrow requirements for async calls
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
update `wit-bindgen` and simplify `async_borrowing_callee` test
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
call `InstanceFlags::set_may_enter` where appropriate
There's still more work to do to fully implement (and test) the reentrance rules
for concurrent tasks, but this is a start.
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
finish implementing reentrance checks
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
feat: implement error-context (#1)
* feat: initial error-context implementation
This commit implements error-context related functions inside the VM,
along with tests to ensure that basic error-context.new and
error-context.debug-message functionality works.
Signed-off-by: Victor Adossi <vadossi@cosmonic.com>
* wip: add test for error context callee/caller transfer
Signed-off-by: Victor Adossi <vadossi@cosmonic.com>
* wip: test for async context transfer
Signed-off-by: Victor Adossi <vadossi@cosmonic.com>
---------
Signed-off-by: Victor Adossi <vadossi@cosmonic.com>
run cargo fmt
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
appease clippy
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
pull in Roman's unit stream work; add world-level export test
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
add unit stream tests
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
CI fixes
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
fix non-component-model-async build
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
add round-trip tests with many parameters and results
This adds tests to cover round-tripping values whose flattened form exceed
`MAX_FLAT_PARAMS`. Although we already had tests to cover this in
tests/all/component_model/func.rs, those tests did not involve any flavor of
composition; these do.
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
test: add multiple send as initial context stream test
Signed-off-by: Victor Adossi <vadossi@cosmonic.com>
fix Victor's test case
Turns out this was the first test case where the host calls a component via an
async-lifted export, which in turn calls another component's async-lifted export
via a sync-lowered import, which didn't work. Now it does!
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
refactor sync->async component call adapters
We no longer use global variables to stash parameters and results due to the
hazard of concurrent calls clobbering them. Instead, we now stash them in the
`GuestTask` object for the task.
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
rvolosatovs pushed a commit to bytecodealliance/wasip3-prototyping that referenced this pull request Feb 3, 2025
This adds support for loading, compiling, linking, and running components which
use the [Async
ABI](https://github.com/WebAssembly/component-model/blob/main/design/mvp/Async.md)
along with the [`stream`, `future`, and
`error-context`](WebAssembly/component-model#405) types.
It also adds support for generating host bindings such that multiple host
functions can be run concurrently with guest tasks -- without monopolizing the
`Store`.
See the [implementation RFC](bytecodealliance/rfcs#38)
for details, as well as [this
repo](https://github.com/dicej/component-async-demo) containing end-to-end smoke
tests.
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
fix clippy warnings and bench/fuzzing errors
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
revert atomic.wit whitespace change
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
fix build when component-model disabled
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
bless component-macro expected output
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
fix no-std build error
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
fix build with --no-default-features --features runtime,component-model
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
partly fix no-std build
It's still broken due to the use of `std::collections::HashMap` in
crates/wasmtime/src/runtime/vm/component.rs. I'll address that as part of the
work to avoid exposing global task/future/stream/error-context handles to
guests.
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
maintain per-instance tables for futures, streams, and error-contexts
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
refactor task/stream/future handle lifting/lowering
This addresses a couple of issues:
- Previously, we were passing task/stream/future/error-context reps directly to
instances while keeping track of which instance had access to which rep. That
worked fine in that there was no way to forge access to inaccessible reps, but
it leaked information about what other instances were doing. Now we maintain
per-instance waitable and error-context tables which map the reps to and from
the handles which the instance sees.
- The `no_std` build was broken due to use of `HashMap` in
`runtime::vm::component`, which is now fixed.
Note that we use one single table per instance for all tasks, streams, and
futures. This is partly necessary because, when async events are delivered to
the guest, it wouldn't have enough context to know which stream or future we're
talking about if each unique stream and future type had its own table. So at
minimum, we need to use the same table for all streams (regardless of payload
type), and likewise for futures. Also, per
WebAssembly/component-model#395 (comment),
the plan is to move towards a shared table for all resource types as well, so
this moves us in that direction.
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
fix wave breakage due to new stream/future/error-context types
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
switch wasm-tools to v1.220.0-based branch
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
check `task.return` type at runtime
We can't statically verify a given call to `task.return` corresponds to the
expected core signature appropriate for the currently running task, so we must
do so at runtime. In order to make that check efficient, we intern the types.
My initial plan was to use `ModuleInternedTypeIndex` and/or `VMSharedTypeIndex`
for interning, but that got hairy with WasmGC considerations, so instead I added
new fields to `ComponentTypes` and `ComponentTypesBuilder`.
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
add `TypedFunc::call_concurrent` and refine stream/future APIs
This implements what I proposed in https://github.com/dicej/rfcs/blob/component-async/accepted/component-model-async.md#wasmtime. Specifically, it adds:
- A new `Promise` type, useful for working with concurrent operations that require access to a `Store` to make progress.
- A new `PromisesUnordered` type for `await`ing multiple promises concurrently
-`TypedFunc::call_concurrent` (which returns a `Promise`), allowing multiple host->guest calls to run concurrently on the same instance.
- Updated `{Stream|Future}{Writer|Reader}` APIs which use `Promise`
The upshot is that the embedder can now ergonomically manage arbitrary numbers
of concurrent operations. Previously, this was a lot more difficult to do
without accidentally starving some of the operations due to another one
monopolizing the `Store`.
Finally, this includes various refactorings and fixes for bugs exposed by the
newer, more versatile APIs.
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
clean up verbosity in component/func.rs
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
snapshot
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
implement stream/future read/write cancellation
This required a somewhat viral addition of `Send` and `Sync` bounds for async
host function closure types, unfortunately.
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
add `Func::call_concurrent` and `LinkerInstance::func_new_concurrent`
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
dynamic API support for streams/futures/error-contexts
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
support callback-less (AKA stackful) async lifts
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
fix `call_host` regression
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
add component model async end-to-end tests
I've ported these over from https://github.com/dicej/component-async-demo
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
fix test regressions and clippy warnings
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
satisfy clippy
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
fix async tests when `component-model-async` enabled
Enabling this feature for all tests revealed various missing pieces in the new
`concurrent.rs` fiber mechanism, which I've addressed.
This adds a bunch of ugly `#[cfg(feature = "component-model-async")]` guards,
but those will all go away once I unify the two async fiber implementations.
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
add and modify tests to cover concurrent APIs
Primarily, this tests and implements cases where parameters and/or results must
be passed via linear memory instead of the stack.
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
`concurrent_{imports|exports}` component macro codegen tests
This enables codegen testing of the `concurrent_imports` and
`concurrent_exports` options to `wasmtime::component::bindgen` and also fixes
code generation for world-level function and resource exports that use the
concurrent call style.
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
`concurrent_{imports|exports}` component macro expanded tests
This enables testing of the `concurrent_imports` and `concurrent_exports`
options in `crates/component-macro/tests/expanded.rs`.
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
add tests/misc_testsuite/component-model-async/*.wast
These only test instantiation of components which use various async options and
built-ins so far. Next, I'll happy and sad path tests which actually execute
code.
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
appease clippy
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
add tests/misc_testsuite/component-model-async/fused.wast
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
add non-panicking bounds checks where appropriate
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
remove post-return bits from async result lift code
...at least until we've determined whether post-return options even make sense
for async-lifted exports.
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
fix component-model-async/fused.wast test failure
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
use `enum` types to represent status and event codes
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
fix component-model-async/fused.wast test failure (2nd try)
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
use `gc_types = true` in component-model-async/fused.wast
We use `Instruction::RefFunc` when generating adapters for async lifts and/or
lowers, which Winch doesn't understand, and apparently `gc_types = true` is what
tells the test infra not to use Winch.
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
trap if async function finishes without calling `task.return`
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
update wit-bindgen and fix rebase damage
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
call post-return function if any for async->sync fused calls
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
fix non-component-model-async build; appease clippy
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
bless bindgen output whitespace changes
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
enforce resource borrow requirements for async calls
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
update `wit-bindgen` and simplify `async_borrowing_callee` test
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
call `InstanceFlags::set_may_enter` where appropriate
There's still more work to do to fully implement (and test) the reentrance rules
for concurrent tasks, but this is a start.
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
finish implementing reentrance checks
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
feat: implement error-context (#1)
* feat: initial error-context implementation
This commit implements error-context related functions inside the VM,
along with tests to ensure that basic error-context.new and
error-context.debug-message functionality works.
Signed-off-by: Victor Adossi <vadossi@cosmonic.com>
* wip: add test for error context callee/caller transfer
Signed-off-by: Victor Adossi <vadossi@cosmonic.com>
* wip: test for async context transfer
Signed-off-by: Victor Adossi <vadossi@cosmonic.com>
---------
Signed-off-by: Victor Adossi <vadossi@cosmonic.com>
run cargo fmt
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
appease clippy
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
pull in Roman's unit stream work; add world-level export test
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
add unit stream tests
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
CI fixes
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
fix non-component-model-async build
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
add round-trip tests with many parameters and results
This adds tests to cover round-tripping values whose flattened form exceed
`MAX_FLAT_PARAMS`. Although we already had tests to cover this in
tests/all/component_model/func.rs, those tests did not involve any flavor of
composition; these do.
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
test: add multiple send as initial context stream test
Signed-off-by: Victor Adossi <vadossi@cosmonic.com>
fix Victor's test case
Turns out this was the first test case where the host calls a component via an
async-lifted export, which in turn calls another component's async-lifted export
via a sync-lowered import, which didn't work. Now it does!
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
refactor sync->async component call adapters
We no longer use global variables to stash parameters and results due to the
hazard of concurrent calls clobbering them. Instead, we now stash them in the
`GuestTask` object for the task.
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
dicej added a commit to bytecodealliance/wasip3-prototyping that referenced this pull request Feb 4, 2025
This adds support for loading, compiling, linking, and running components which
use the [Async
ABI](https://github.com/WebAssembly/component-model/blob/main/design/mvp/Async.md)
along with the [`stream`, `future`, and
`error-context`](WebAssembly/component-model#405) types.
It also adds support for generating host bindings such that multiple host
functions can be run concurrently with guest tasks -- without monopolizing the
`Store`.
See the [implementation RFC](bytecodealliance/rfcs#38)
for details, as well as [this
repo](https://github.com/dicej/component-async-demo) containing end-to-end smoke
tests.
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
fix clippy warnings and bench/fuzzing errors
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
revert atomic.wit whitespace change
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
fix build when component-model disabled
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
bless component-macro expected output
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
fix no-std build error
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
fix build with --no-default-features --features runtime,component-model
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
partly fix no-std build
It's still broken due to the use of `std::collections::HashMap` in
crates/wasmtime/src/runtime/vm/component.rs. I'll address that as part of the
work to avoid exposing global task/future/stream/error-context handles to
guests.
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
maintain per-instance tables for futures, streams, and error-contexts
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
refactor task/stream/future handle lifting/lowering
This addresses a couple of issues:
- Previously, we were passing task/stream/future/error-context reps directly to
instances while keeping track of which instance had access to which rep. That
worked fine in that there was no way to forge access to inaccessible reps, but
it leaked information about what other instances were doing. Now we maintain
per-instance waitable and error-context tables which map the reps to and from
the handles which the instance sees.
- The `no_std` build was broken due to use of `HashMap` in
`runtime::vm::component`, which is now fixed.
Note that we use one single table per instance for all tasks, streams, and
futures. This is partly necessary because, when async events are delivered to
the guest, it wouldn't have enough context to know which stream or future we're
talking about if each unique stream and future type had its own table. So at
minimum, we need to use the same table for all streams (regardless of payload
type), and likewise for futures. Also, per
WebAssembly/component-model#395 (comment),
the plan is to move towards a shared table for all resource types as well, so
this moves us in that direction.
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
fix wave breakage due to new stream/future/error-context types
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
switch wasm-tools to v1.220.0-based branch
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
check `task.return` type at runtime
We can't statically verify a given call to `task.return` corresponds to the
expected core signature appropriate for the currently running task, so we must
do so at runtime. In order to make that check efficient, we intern the types.
My initial plan was to use `ModuleInternedTypeIndex` and/or `VMSharedTypeIndex`
for interning, but that got hairy with WasmGC considerations, so instead I added
new fields to `ComponentTypes` and `ComponentTypesBuilder`.
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
add `TypedFunc::call_concurrent` and refine stream/future APIs
This implements what I proposed in https://github.com/dicej/rfcs/blob/component-async/accepted/component-model-async.md#wasmtime. Specifically, it adds:
- A new `Promise` type, useful for working with concurrent operations that require access to a `Store` to make progress.
- A new `PromisesUnordered` type for `await`ing multiple promises concurrently
-`TypedFunc::call_concurrent` (which returns a `Promise`), allowing multiple host->guest calls to run concurrently on the same instance.
- Updated `{Stream|Future}{Writer|Reader}` APIs which use `Promise`
The upshot is that the embedder can now ergonomically manage arbitrary numbers
of concurrent operations. Previously, this was a lot more difficult to do
without accidentally starving some of the operations due to another one
monopolizing the `Store`.
Finally, this includes various refactorings and fixes for bugs exposed by the
newer, more versatile APIs.
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
clean up verbosity in component/func.rs
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
snapshot
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
implement stream/future read/write cancellation
This required a somewhat viral addition of `Send` and `Sync` bounds for async
host function closure types, unfortunately.
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
add `Func::call_concurrent` and `LinkerInstance::func_new_concurrent`
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
dynamic API support for streams/futures/error-contexts
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
support callback-less (AKA stackful) async lifts
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
fix `call_host` regression
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
add component model async end-to-end tests
I've ported these over from https://github.com/dicej/component-async-demo
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
fix test regressions and clippy warnings
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
satisfy clippy
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
fix async tests when `component-model-async` enabled
Enabling this feature for all tests revealed various missing pieces in the new
`concurrent.rs` fiber mechanism, which I've addressed.
This adds a bunch of ugly `#[cfg(feature = "component-model-async")]` guards,
but those will all go away once I unify the two async fiber implementations.
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
add and modify tests to cover concurrent APIs
Primarily, this tests and implements cases where parameters and/or results must
be passed via linear memory instead of the stack.
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
`concurrent_{imports|exports}` component macro codegen tests
This enables codegen testing of the `concurrent_imports` and
`concurrent_exports` options to `wasmtime::component::bindgen` and also fixes
code generation for world-level function and resource exports that use the
concurrent call style.
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
`concurrent_{imports|exports}` component macro expanded tests
This enables testing of the `concurrent_imports` and `concurrent_exports`
options in `crates/component-macro/tests/expanded.rs`.
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
add tests/misc_testsuite/component-model-async/*.wast
These only test instantiation of components which use various async options and
built-ins so far. Next, I'll happy and sad path tests which actually execute
code.
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
appease clippy
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
add tests/misc_testsuite/component-model-async/fused.wast
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
add non-panicking bounds checks where appropriate
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
remove post-return bits from async result lift code
...at least until we've determined whether post-return options even make sense
for async-lifted exports.
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
fix component-model-async/fused.wast test failure
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
use `enum` types to represent status and event codes
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
fix component-model-async/fused.wast test failure (2nd try)
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
use `gc_types = true` in component-model-async/fused.wast
We use `Instruction::RefFunc` when generating adapters for async lifts and/or
lowers, which Winch doesn't understand, and apparently `gc_types = true` is what
tells the test infra not to use Winch.
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
trap if async function finishes without calling `task.return`
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
update wit-bindgen and fix rebase damage
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
call post-return function if any for async->sync fused calls
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
fix non-component-model-async build; appease clippy
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
bless bindgen output whitespace changes
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
enforce resource borrow requirements for async calls
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
update `wit-bindgen` and simplify `async_borrowing_callee` test
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
call `InstanceFlags::set_may_enter` where appropriate
There's still more work to do to fully implement (and test) the reentrance rules
for concurrent tasks, but this is a start.
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
finish implementing reentrance checks
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
feat: implement error-context (#1)
* feat: initial error-context implementation
This commit implements error-context related functions inside the VM,
along with tests to ensure that basic error-context.new and
error-context.debug-message functionality works.
Signed-off-by: Victor Adossi <vadossi@cosmonic.com>
* wip: add test for error context callee/caller transfer
Signed-off-by: Victor Adossi <vadossi@cosmonic.com>
* wip: test for async context transfer
Signed-off-by: Victor Adossi <vadossi@cosmonic.com>
---------
Signed-off-by: Victor Adossi <vadossi@cosmonic.com>
run cargo fmt
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
appease clippy
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
pull in Roman's unit stream work; add world-level export test
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
add unit stream tests
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
CI fixes
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
fix non-component-model-async build
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
add round-trip tests with many parameters and results
This adds tests to cover round-tripping values whose flattened form exceed
`MAX_FLAT_PARAMS`. Although we already had tests to cover this in
tests/all/component_model/func.rs, those tests did not involve any flavor of
composition; these do.
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
test: add multiple send as initial context stream test
Signed-off-by: Victor Adossi <vadossi@cosmonic.com>
fix Victor's test case
Turns out this was the first test case where the host calls a component via an
async-lifted export, which in turn calls another component's async-lifted export
via a sync-lowered import, which didn't work. Now it does!
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
refactor sync->async component call adapters
We no longer use global variables to stash parameters and results due to the
hazard of concurrent calls clobbering them. Instead, we now stash them in the
`GuestTask` object for the task.
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
Sign up for freeto 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.

5 participants

@lukewagner@dicej@pavelsavara@sunfishcode@vados-cosmonic