-
Notifications
You must be signed in to change notification settings - Fork 1.4k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add support for async/streams/futures #9582
Closed
Closed
Conversation
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
191b9f4
to
f747135
Compare
35135f5
to
22cb051
Compare
345b43d
to
d35d87c
Compare
9b2ed85
to
41753f4
Compare
7cf1ed3
to
742e18f
Compare
6552439
to
499aade
Compare
dicej
added a commit
to dicej/wasmtime
that referenced
this pull request
Jan 17, 2025
I've split this out of bytecodealliance#9582 to make review easier. This patch adds async/stream/future/error-context support to the host binding generator, along with placeholder type and function definitions in the `wasmtime` crate which the generated bindings can refer to. See https://github.com/dicej/rfcs/blob/component-async/accepted/component-model-async.md#componentbindgen-updates for the design and rationale. Note that I've added temporary `[patch.crates-io]` overrides in Cargo.toml until bytecodealliance/wit-bindgen#1130 and bytecodealliance/wasm-tools#1978 have been released. Also note that we emit a `T: 'static` bound for `AsContextMut<Data = T>` when generating bindings with `concurrent_imports: true`. This is only because `rustc` insists that the closure we're passing to `LinkerInstance::func_wrap_concurrent` captures the lifetime of `T` despite my best efforts to convince it otherwise. Alex and I suspect this is a limitation in the compiler, and I asked about it on the rust-lang Zulip, but we haven't been able to determine a workaround so far. Signed-off-by: Joel Dice <[email protected]>
dicej
added a commit
to dicej/wasmtime
that referenced
this pull request
Jan 18, 2025
I've split this out of bytecodealliance#9582 to make review easier. This patch includes the plumbing needed to route async/stream/future/error-context data from `wit-parser`, through the various layers of `wasmtime-environ`, and on to `wasmtime-cranelift` and `wasmtime`. The `wasmtime::runtime`, `wasmtime_environ::fact`, and `wasmtime_cranelift::compiler::component` modules only contain `todo!()` stubs to begin with; I'll flesh those out in later PRs. Signed-off-by: Joel Dice <[email protected]>
dicej
added a commit
to dicej/wasmtime
that referenced
this pull request
Jan 22, 2025
I've split this out of bytecodealliance#9582 to make review easier. This patch adds async/stream/future/error-context support to the host binding generator, along with placeholder type and function definitions in the `wasmtime` crate which the generated bindings can refer to. See https://github.com/dicej/rfcs/blob/component-async/accepted/component-model-async.md#componentbindgen-updates for the design and rationale. Note that I've added temporary `[patch.crates-io]` overrides in Cargo.toml until bytecodealliance/wit-bindgen#1130 and bytecodealliance/wasm-tools#1978 have been released. Also note that we emit a `T: 'static` bound for `AsContextMut<Data = T>` when generating bindings with `concurrent_imports: true`. This is only because `rustc` insists that the closure we're passing to `LinkerInstance::func_wrap_concurrent` captures the lifetime of `T` despite my best efforts to convince it otherwise. Alex and I suspect this is a limitation in the compiler, and I asked about it on the rust-lang Zulip, but we haven't been able to determine a workaround so far. Signed-off-by: Joel Dice <[email protected]> remove obsolete TODO comment Signed-off-by: Joel Dice <[email protected]> make `futures` dep optional Signed-off-by: Joel Dice <[email protected]> update `wasm-tools` and `wit-bindgen` Signed-off-by: Joel Dice <[email protected]>
github-merge-queue bot
pushed a commit
that referenced
this pull request
Jan 22, 2025
* async/stream/future support for wasmtime-wit-bindgen I've split this out of #9582 to make review easier. This patch adds async/stream/future/error-context support to the host binding generator, along with placeholder type and function definitions in the `wasmtime` crate which the generated bindings can refer to. See https://github.com/dicej/rfcs/blob/component-async/accepted/component-model-async.md#componentbindgen-updates for the design and rationale. Note that I've added temporary `[patch.crates-io]` overrides in Cargo.toml until bytecodealliance/wit-bindgen#1130 and bytecodealliance/wasm-tools#1978 have been released. Also note that we emit a `T: 'static` bound for `AsContextMut<Data = T>` when generating bindings with `concurrent_imports: true`. This is only because `rustc` insists that the closure we're passing to `LinkerInstance::func_wrap_concurrent` captures the lifetime of `T` despite my best efforts to convince it otherwise. Alex and I suspect this is a limitation in the compiler, and I asked about it on the rust-lang Zulip, but we haven't been able to determine a workaround so far. Signed-off-by: Joel Dice <[email protected]> remove obsolete TODO comment Signed-off-by: Joel Dice <[email protected]> make `futures` dep optional Signed-off-by: Joel Dice <[email protected]> update `wasm-tools` and `wit-bindgen` Signed-off-by: Joel Dice <[email protected]> * run cargo vet Signed-off-by: Joel Dice <[email protected]> --------- Signed-off-by: Joel Dice <[email protected]>
dicej
added a commit
to dicej/wasmtime
that referenced
this pull request
Jan 22, 2025
I've split this out of bytecodealliance#9582 to make review easier. This patch includes the plumbing needed to route async/stream/future/error-context data from `wit-parser`, through the various layers of `wasmtime-environ`, and on to `wasmtime-cranelift` and `wasmtime`. The `wasmtime::runtime`, `wasmtime_environ::fact`, and `wasmtime_cranelift::compiler::component` modules only contain `todo!()` stubs to begin with; I'll flesh those out in later PRs. Signed-off-by: Joel Dice <[email protected]> remove debugging code Signed-off-by: Joel Dice <[email protected]> revert comment formatting change in trap_encoding.rs Signed-off-by: Joel Dice <[email protected]> deduplicate code in inline.rs Signed-off-by: Joel Dice <[email protected]> remove `ComponentTypesBuilder::error_context_type` This was just an alias for `error_context_table_type`, which I've made public. Signed-off-by: Joel Dice <[email protected]> defer `VMComponentOffsets` changes to a future PR Signed-off-by: Joel Dice <[email protected]>
dicej
added a commit
to dicej/wasmtime
that referenced
this pull request
Jan 24, 2025
This is another piece of bytecodealliance#9582 which I'm splitting out to make review easier. This test includes a minimal component which lowers an import with the `async` option. The rest of the changes fill in some TODOs to make the test pass. Signed-off-by: Joel Dice <[email protected]>
dicej
added a commit
to dicej/wasmtime
that referenced
this pull request
Jan 24, 2025
This is another piece of bytecodealliance#9582 which I'm splitting out to make review easier. This test includes a minimal component which lowers an import with the `async` option. The rest of the changes fill in some TODOs to make the test pass. Signed-off-by: Joel Dice <[email protected]>
github-merge-queue bot
pushed a commit
that referenced
this pull request
Jan 24, 2025
This is another piece of #9582 which I'm splitting out to make review easier. This test includes two components: one which exports a function using the async-with-callback ABI, and another which uses the async-without-callback ABI. It doesn't actually instantiate or run either component yet. The rest of the changes fill in some TODOs to make the test pass. Signed-off-by: Joel Dice <[email protected]>
dicej
added a commit
to dicej/wasmtime
that referenced
this pull request
Jan 24, 2025
This is another piece of bytecodealliance#9582 which I'm splitting out to make review easier. This test includes two components: one which exports a function using the async-with-callback ABI, and another which uses the async-without-callback ABI. It doesn't actually instantiate or run either component yet. The rest of the changes fill in some TODOs to make the test pass. Signed-off-by: Joel Dice <[email protected]>
dicej
added a commit
to dicej/wasmtime
that referenced
this pull request
Jan 24, 2025
This is another piece of bytecodealliance#9582 which I'm splitting out to make review easier. This test includes a minimal component which lowers an import with the `async` option. The rest of the changes fill in some TODOs to make the test pass. Signed-off-by: Joel Dice <[email protected]>
dicej
added a commit
to dicej/wasmtime
that referenced
this pull request
Jan 24, 2025
This is another piece of bytecodealliance#9582 which I'm splitting out to make review easier. This test includes a minimal component which lowers an import with the `async` option. The rest of the changes fill in some TODOs to make the test pass. Signed-off-by: Joel Dice <[email protected]>
github-merge-queue bot
pushed a commit
that referenced
this pull request
Jan 24, 2025
This is another piece of #9582 which I'm splitting out to make review easier. This test includes a minimal component which lowers an import with the `async` option. The rest of the changes fill in some TODOs to make the test pass. Signed-off-by: Joel Dice <[email protected]>
dicej
added a commit
to dicej/wasmtime
that referenced
this pull request
Jan 24, 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 <[email protected]>
dicej
added a commit
to dicej/wasmtime
that referenced
this pull request
Jan 24, 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 <[email protected]>
dicej
added a commit
to dicej/wasmtime
that referenced
this pull request
Jan 24, 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 <[email protected]>
dicej
added a commit
to dicej/wasmtime
that referenced
this pull request
Jan 24, 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 <[email protected]>
dicej
added a commit
to dicej/wasmtime
that referenced
this pull request
Jan 24, 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 <[email protected]>
dicej
added a commit
to dicej/wasmtime
that referenced
this pull request
Jan 24, 2025
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 <[email protected]>
dicej
added a commit
to dicej/wasmtime
that referenced
this pull request
Jan 29, 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 <[email protected]> address review feedback Signed-off-by: Joel Dice <[email protected]> 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 <[email protected]> refactor `component-model-async` cfg attrs per review feedback Also, switch to upstream `wasm-tools` main branch. Signed-off-by: Joel Dice <[email protected]> add `Compiler::new` constructor Signed-off-by: Joel Dice <[email protected]> add comments covering various lower/lift combos in FACT generator Signed-off-by: Joel Dice <[email protected]> add `Compiler::global_set` helper function Signed-off-by: Joel Dice <[email protected]>
dicej
added a commit
to dicej/wasmtime
that referenced
this pull request
Jan 29, 2025
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 <[email protected]>
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 <[email protected]> address review feedback Signed-off-by: Joel Dice <[email protected]> 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 <[email protected]> refactor `component-model-async` cfg attrs per review feedback Also, switch to upstream `wasm-tools` main branch. Signed-off-by: Joel Dice <[email protected]> add `Compiler::new` constructor Signed-off-by: Joel Dice <[email protected]> add comments covering various lower/lift combos in FACT generator Signed-off-by: Joel Dice <[email protected]> add `Compiler::global_set` helper function Signed-off-by: Joel Dice <[email protected]> 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 <[email protected]> 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 <[email protected]> fix clippy warnings and bench/fuzzing errors Signed-off-by: Joel Dice <[email protected]> revert atomic.wit whitespace change Signed-off-by: Joel Dice <[email protected]> fix build when component-model disabled Signed-off-by: Joel Dice <[email protected]> bless component-macro expected output Signed-off-by: Joel Dice <[email protected]> fix no-std build error Signed-off-by: Joel Dice <[email protected]> fix build with --no-default-features --features runtime,component-model Signed-off-by: Joel Dice <[email protected]> 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 <[email protected]> maintain per-instance tables for futures, streams, and error-contexts Signed-off-by: Joel Dice <[email protected]> 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 <[email protected]> fix wave breakage due to new stream/future/error-context types Signed-off-by: Joel Dice <[email protected]> switch wasm-tools to v1.220.0-based branch Signed-off-by: Joel Dice <[email protected]> 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 <[email protected]> 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 <[email protected]> clean up verbosity in component/func.rs Signed-off-by: Joel Dice <[email protected]> snapshot Signed-off-by: Joel Dice <[email protected]> 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 <[email protected]> add `Func::call_concurrent` and `LinkerInstance::func_new_concurrent` Signed-off-by: Joel Dice <[email protected]> dynamic API support for streams/futures/error-contexts Signed-off-by: Joel Dice <[email protected]> support callback-less (AKA stackful) async lifts Signed-off-by: Joel Dice <[email protected]> fix `call_host` regression Signed-off-by: Joel Dice <[email protected]> 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 <[email protected]> fix test regressions and clippy warnings Signed-off-by: Joel Dice <[email protected]> satisfy clippy Signed-off-by: Joel Dice <[email protected]> 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 <[email protected]> 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 <[email protected]> `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 <[email protected]> `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 <[email protected]> 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 <[email protected]> appease clippy Signed-off-by: Joel Dice <[email protected]> add tests/misc_testsuite/component-model-async/fused.wast Signed-off-by: Joel Dice <[email protected]> add non-panicking bounds checks where appropriate Signed-off-by: Joel Dice <[email protected]> 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 <[email protected]> fix component-model-async/fused.wast test failure Signed-off-by: Joel Dice <[email protected]> use `enum` types to represent status and event codes Signed-off-by: Joel Dice <[email protected]> fix component-model-async/fused.wast test failure (2nd try) Signed-off-by: Joel Dice <[email protected]> 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 <[email protected]> trap if async function finishes without calling `task.return` Signed-off-by: Joel Dice <[email protected]> update wit-bindgen and fix rebase damage Signed-off-by: Joel Dice <[email protected]> call post-return function if any for async->sync fused calls Signed-off-by: Joel Dice <[email protected]> fix non-component-model-async build; appease clippy Signed-off-by: Joel Dice <[email protected]> bless bindgen output whitespace changes Signed-off-by: Joel Dice <[email protected]> enforce resource borrow requirements for async calls Signed-off-by: Joel Dice <[email protected]> update `wit-bindgen` and simplify `async_borrowing_callee` test Signed-off-by: Joel Dice <[email protected]> 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 <[email protected]> finish implementing reentrance checks Signed-off-by: Joel Dice <[email protected]> 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 <[email protected]> * wip: add test for error context callee/caller transfer Signed-off-by: Victor Adossi <[email protected]> * wip: test for async context transfer Signed-off-by: Victor Adossi <[email protected]> --------- Signed-off-by: Victor Adossi <[email protected]> run cargo fmt Signed-off-by: Joel Dice <[email protected]> appease clippy Signed-off-by: Joel Dice <[email protected]> pull in Roman's unit stream work; add world-level export test Signed-off-by: Joel Dice <[email protected]> add unit stream tests Signed-off-by: Joel Dice <[email protected]> CI fixes Signed-off-by: Joel Dice <[email protected]>
522ad61
to
bcdcc5a
Compare
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 <[email protected]> fix clippy warnings and bench/fuzzing errors Signed-off-by: Joel Dice <[email protected]> revert atomic.wit whitespace change Signed-off-by: Joel Dice <[email protected]> fix build when component-model disabled Signed-off-by: Joel Dice <[email protected]> bless component-macro expected output Signed-off-by: Joel Dice <[email protected]> fix no-std build error Signed-off-by: Joel Dice <[email protected]> fix build with --no-default-features --features runtime,component-model Signed-off-by: Joel Dice <[email protected]> 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 <[email protected]> maintain per-instance tables for futures, streams, and error-contexts Signed-off-by: Joel Dice <[email protected]> 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 <[email protected]> fix wave breakage due to new stream/future/error-context types Signed-off-by: Joel Dice <[email protected]> switch wasm-tools to v1.220.0-based branch Signed-off-by: Joel Dice <[email protected]> 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 <[email protected]> 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 <[email protected]> clean up verbosity in component/func.rs Signed-off-by: Joel Dice <[email protected]> snapshot Signed-off-by: Joel Dice <[email protected]> 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 <[email protected]> add `Func::call_concurrent` and `LinkerInstance::func_new_concurrent` Signed-off-by: Joel Dice <[email protected]> dynamic API support for streams/futures/error-contexts Signed-off-by: Joel Dice <[email protected]> support callback-less (AKA stackful) async lifts Signed-off-by: Joel Dice <[email protected]> fix `call_host` regression Signed-off-by: Joel Dice <[email protected]> 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 <[email protected]> fix test regressions and clippy warnings Signed-off-by: Joel Dice <[email protected]> satisfy clippy Signed-off-by: Joel Dice <[email protected]> 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 <[email protected]> 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 <[email protected]> `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 <[email protected]> `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 <[email protected]> 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 <[email protected]> appease clippy Signed-off-by: Joel Dice <[email protected]> add tests/misc_testsuite/component-model-async/fused.wast Signed-off-by: Joel Dice <[email protected]> add non-panicking bounds checks where appropriate Signed-off-by: Joel Dice <[email protected]> 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 <[email protected]> fix component-model-async/fused.wast test failure Signed-off-by: Joel Dice <[email protected]> use `enum` types to represent status and event codes Signed-off-by: Joel Dice <[email protected]> fix component-model-async/fused.wast test failure (2nd try) Signed-off-by: Joel Dice <[email protected]> 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 <[email protected]> trap if async function finishes without calling `task.return` Signed-off-by: Joel Dice <[email protected]> update wit-bindgen and fix rebase damage Signed-off-by: Joel Dice <[email protected]> call post-return function if any for async->sync fused calls Signed-off-by: Joel Dice <[email protected]> fix non-component-model-async build; appease clippy Signed-off-by: Joel Dice <[email protected]> bless bindgen output whitespace changes Signed-off-by: Joel Dice <[email protected]> enforce resource borrow requirements for async calls Signed-off-by: Joel Dice <[email protected]> update `wit-bindgen` and simplify `async_borrowing_callee` test Signed-off-by: Joel Dice <[email protected]> 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 <[email protected]> finish implementing reentrance checks Signed-off-by: Joel Dice <[email protected]> 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 <[email protected]> * wip: add test for error context callee/caller transfer Signed-off-by: Victor Adossi <[email protected]> * wip: test for async context transfer Signed-off-by: Victor Adossi <[email protected]> --------- Signed-off-by: Victor Adossi <[email protected]> run cargo fmt Signed-off-by: Joel Dice <[email protected]> appease clippy Signed-off-by: Joel Dice <[email protected]> pull in Roman's unit stream work; add world-level export test Signed-off-by: Joel Dice <[email protected]> add unit stream tests Signed-off-by: Joel Dice <[email protected]> CI fixes Signed-off-by: Joel Dice <[email protected]> fix non-component-model-async build Signed-off-by: Joel Dice <[email protected]> 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 <[email protected]> test: add multiple send as initial context stream test Signed-off-by: Victor Adossi <[email protected]> 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 <[email protected]> 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 <[email protected]>
dicej
added a commit
to dicej/wasmtime
that referenced
this pull request
Mar 4, 2025
This is another piece of bytecodealliance#9582 which I'm splitting out to make review easier. The fused.wast test exercises fused adapter generation for various flavors of intercomponent async->async, async->sync, and sync->async calls. The futures.wast and streams.wast tests exercise the various intrinsics (e.g. `stream.read`, `future.close_writable`, etc.) involving `future`s and `stream`s. The remaining changes fill in some TODOs to make the tests pass, plus plumbing for a few intrinsics which aren't needed for these tests but which set the foundation for future tests. Signed-off-by: Joel Dice <[email protected]>
github-merge-queue bot
pushed a commit
that referenced
this pull request
Mar 5, 2025
* add component-model-async/{fused|futures|streams}.wast tests This is another piece of #9582 which I'm splitting out to make review easier. The fused.wast test exercises fused adapter generation for various flavors of intercomponent async->async, async->sync, and sync->async calls. The futures.wast and streams.wast tests exercise the various intrinsics (e.g. `stream.read`, `future.close_writable`, etc.) involving `future`s and `stream`s. The remaining changes fill in some TODOs to make the tests pass, plus plumbing for a few intrinsics which aren't needed for these tests but which set the foundation for future tests. Signed-off-by: Joel Dice <[email protected]> * address review feedback Signed-off-by: Joel Dice <[email protected]> --------- Signed-off-by: Joel Dice <[email protected]>
dicej
added a commit
to dicej/wasmtime
that referenced
this pull request
Mar 14, 2025
* Do proper subtype checking for imported globals during instantiation (bytecodealliance#10304) * pulley: Fix a panic compiling with debug info (bytecodealliance#10305) Debug into doesn't work on Pulley anyway but it's better to return a first-class error rather than a panic. This commit fills out a simple missing instruction in the Pulley backend to ensure that compilation gets far enough to the DWARF transform where there's no pulley support and an error is returned. * Improve rebuild detection of test-programs (bytecodealliance#10303) This commit improves the logic of detecting when to rebuild the `test-programs` artifacts used during test by parsing the `*.d` files that Cargo emits as part of its compilation and using that as the `cargo:rerun-if-changed` directive. This not only includes what was previously depended on but additionally includes features such as `path` dependencies which might temporarily be used during development. * Add a missing `apt-get update` before install (bytecodealliance#10310) I always forget this and it always bites us within a few months. Alas. * wasmtime-wit-bindgen: gen is a reserved keyword in the lexer starting in 2024 edition (bytecodealliance#10308) * Test natively on AArch64, not emulated (bytecodealliance#10306) This commit updates the aarch64 tests to use the new `*-arm` images from GitHub instead of running through QEMU emulation. This should be a bit faster but primarily helps build confidence that it runs on real hardware. I'll note that release builds aren't updated at this time to run on native hardware since that's moreso about glibc compatibility and it's a bit easier to keep the setup we currently have for that. If `*-arm` machines are noticably faster than the default x64 machines then we could in theory move everything over to an aarch64-based machine as opposed to just the aarch64 build. * chore: fix some typos in comments (bytecodealliance#10309) Signed-off-by: shenpengfeng <[email protected]> * Rename `VMRuntimeLimits` to `VMStoreContext` (bytecodealliance#10307) Way back in time, this struct originally contained the stack and fuel limits. Then it also got the epoch deadline. Then it also got the exit FP/PC and entry FP. Now it is just the place where we put per-store mutable data that is accessed by JIT code and must be shared between all `VMContext`s. So it is time to rename it. This commit is purely mechanical and just renames the type and various methods and variables that use/access it. * wasmtime-wit-bindgen: emit a definition for all types in a wit interface (bytecodealliance#10311) * wasmtime-wit-bindgen: emit a definition for all types in a wit The calculation of TypeInfo only reaches types which are passed to or from a function. For types which are not reachable, default to the defining them according to the ownership setting given to bindgen. I have my doubts that `with`-reuse of bindgen types actually works properly when bindgen is set to Ownership::Borrowing but thats out of scope for this PR, which is to fix bytecodealliance#10090 * component-macro: bless bindgen test output * asm: sse orpd implementation (bytecodealliance#10273) * sse orpd implementation assembler integration with isle format add clippy reason, reorder avx priority in isle bless tests for orpd create separate xmm module validate function rewrite sse condition add quote from manual for sse prefix format changes move Xmm bits under Reg * use new isle constructors for sse * remove unused function * minor changes * Winch: Fix consts and multivalue returns (bytecodealliance#10315) * fixed broken link (bytecodealliance#10318) * chore: fix parenthesis balance (bytecodealliance#10317) parentheses are not balanced here * winch(aarch64): ABI integration (bytecodealliance#10312) * winch(aarch64): ABI integration This commit finalizes the ABI integration between Winch and Cranelift, notably: * Updates the Cranelift ABI to ensure that all the Winch register clobbers are taken into account. * Updates the Winch ABI to treat x28 as callee-saved, since it's used as the shadow stack pointer. The alternative to treating x28 as callee-saved is to treat it as caller-saved and save it when required e.g., at call-sites, even though this approach works, it's probably more efficient to perform a store/pop once per function, to minimize the number of move instructions required. There are still some changes needed in order to fully enable running spec tests for aarch64, however, this change is one step further. If interested, you can run the call.wast test via: cargo run -- wast -Ccompiler=winch tests/spec_testsuite/call_indirect.wast * Update disas tests * Use `alloc_zeroed` to allocate dynamic table elements (bytecodealliance#10313) * Use `alloc_zeroed` to allocate dynamic table elements This allows us to get pre-zeroed memory from the global allocator, rather than needing to manually zero-initialize the elements. * Don't ask the global allocator to allocate a block of size zero * x64: use Rust types for assembler immediates (bytecodealliance#10302) Previously we used `AssemblerImm*` and `AssemblerSimm*` throughout the x64 ISLE to indicate the type of immediate an instruction would receive. Alex has noted previously that this is unnecessary; it does after all create more ties between the `cranelift-codegen` ISLE and `cranelift-assembler-x64` that could possibly break in the future. This change removes those ties by using Rust types in ISLE (e.g., `u8`, `i8`, `u16`, etc.) and converting to the expected assembler type in the ISLE glue layer. * Update ir.md (bytecodealliance#10319) Hello, A possible typo in this text: "Forward" Should be "Foreword" "Forward" means to move ahead, but the correct term for an introduction is "Foreword". Thanks. * Expose GC refs to Wasm in `gc_alloc_raw` libcall (bytecodealliance#10322) * Expose GC refs to Wasm in `gc_alloc_raw` libcall As we are returning a GC reference to Wasm, we need to mark that GC reference as exposed to Wasm. Fixes bytecodealliance#9669 * miri ignore test that calls wasm and therefore can't run in miri * Bump Wasmtime to 32.0.0 (bytecodealliance#10330) Co-authored-by: Wasmtime Publish <[email protected]> * add component-model-async/{fused|futures|streams}.wast tests (bytecodealliance#10106) * add component-model-async/{fused|futures|streams}.wast tests This is another piece of bytecodealliance#9582 which I'm splitting out to make review easier. The fused.wast test exercises fused adapter generation for various flavors of intercomponent async->async, async->sync, and sync->async calls. The futures.wast and streams.wast tests exercise the various intrinsics (e.g. `stream.read`, `future.close_writable`, etc.) involving `future`s and `stream`s. The remaining changes fill in some TODOs to make the tests pass, plus plumbing for a few intrinsics which aren't needed for these tests but which set the foundation for future tests. Signed-off-by: Joel Dice <[email protected]> * address review feedback Signed-off-by: Joel Dice <[email protected]> --------- Signed-off-by: Joel Dice <[email protected]> * Update wasm-tools to the latest revision (bytecodealliance#10314) * Update wasm-tools to the latest revision * Update component async bits for new intrinsics * Ignore options for now * I truly, and fundamentally, do not understand `cargo vet` * Fix a test * Ignore fuzzing `testcase0.wasm` et al in `.gitignore` (bytecodealliance#10341) * remove temporary patch from Cargo.toml Signed-off-by: Joel Dice <[email protected]> * Fix building artifacts alone in isolation Few more crate features needed * Rename backpressure intrinsic * Patch to work-in-progress branches * temporarily stub-out waitable-set.wait calls in tests Signed-off-by: Joel Dice <[email protected]> * fix WAT/WAST test regressions Signed-off-by: Joel Dice <[email protected]> * Switch to published wasm-tools deps * bless bindgen test output Signed-off-by: Joel Dice <[email protected]> * remove realloc from `task.return` in WAT tests This is no longer allowed by wasmparser. Signed-off-by: Joel Dice <[email protected]> * Switch to wit-bindgen upstream --------- Signed-off-by: shenpengfeng <[email protected]> Signed-off-by: Joel Dice <[email protected]> Co-authored-by: Nick Fitzgerald <[email protected]> Co-authored-by: Alex Crichton <[email protected]> Co-authored-by: Pat Hickey <[email protected]> Co-authored-by: shenpengfeng <[email protected]> Co-authored-by: Rahul <[email protected]> Co-authored-by: Jeffrey Charles <[email protected]> Co-authored-by: ifsheldon <[email protected]> Co-authored-by: Bongjun Jang <[email protected]> Co-authored-by: Saúl Cabrera <[email protected]> Co-authored-by: Andrew Brown <[email protected]> Co-authored-by: owen <[email protected]> Co-authored-by: wasmtime-publish <[email protected]> Co-authored-by: Wasmtime Publish <[email protected]>
I'm going to go ahead and close this since development has shifted to the wasip3-prototyping repo, and the code in this PR is quite out-of-date by now. I'll continue opening incremental upstream PRs as the prototyping code matures. |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
This adds support for loading, compiling, linking, and running components which use the Async ABI along with the
stream
,future
, anderror-context
types. It also adds support for generating host bindings such that multiple host functions can be run concurrently with guest tasks -- without monopolizing theStore
.See the implementation RFC for details, as well as this repo containing end-to-end smoke tests.
This is very much a work-in progress, with a number of tasks remaining:
task.return
type during compilation and assert the actual and expected types match at runtime{stream|future}.cancel-{read|write}
(Typed)Func::call_concurrent
per the RFCerror-context.{new|debug-string}
wasmtime_cranelift::compiler::component
StoreContextMut::on_fiber
andconcurrent::on_fiber
wasm-tools
once Add support for async ABI, futures, streams, and errors wasm-tools#1895 has been merged and releasedwit-bindgen
once Add support for async/streams/futures to Rust generator wit-bindgen#1082 has been merged and released