Skip to content
New issue

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

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

Already on GitHub? Sign in to your account

Add support for async/streams/futures #9582

Draft
wants to merge 3 commits into
base: main
Choose a base branch
from

Commits on Nov 21, 2024

  1. 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.
    
    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 <[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]>
    dicej committed Nov 21, 2024
    Configuration menu
    Copy the full SHA
    71897f2 View commit details
    Browse the repository at this point in the history
  2. switch wasm-tools to v1.220.0-based branch

    Signed-off-by: Joel Dice <[email protected]>
    dicej committed Nov 21, 2024
    Configuration menu
    Copy the full SHA
    f747135 View commit details
    Browse the repository at this point in the history

Commits on Nov 22, 2024

  1. 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]>
    dicej committed Nov 22, 2024
    Configuration menu
    Copy the full SHA
    fe242b4 View commit details
    Browse the repository at this point in the history