changed 4 months ago
Linked with GitHub

Component Model Async Implementation Overview

Current status

  • (mostly) feature-complete wrt current spec
    • debug-context.{new|debug-string} not yet implemented, but should be easy
    • does not yet support recently-proposed spec changes
  • PRs
    • RFC: ready for review
    • wasm-tools: ready for review
    • wit-bindgen: ready for review
    • wasmtime: needs more tests, comments, bounds checks, etc.
      • aiming to make this ready-for-review by EOY

Implementation details: wasm-tools

  • Added feature-gated support for new canon options and intrinsics
  • Made up name mangling scheme for wit-component

Implementation details: wit-bindgen

  • Rust language support only to start with
    • Supports async imports and (stackless) async exports
    • Generated code uses wit_bindgen_rt::async_support module
      • async_support::spawn for spawning futures to run post-return
      • async_support::block_on for running futures from sync-lifted exports
    • stream<T> -> StreamReader<T> and StreamWriter<T> where T: StreamPayload
      • impl<T> futures::Stream for StreamReader<T>
      • impl<T> futures::Sink for StreamWriter<T>
    • future<T> -> FutureReader<T> and FutureWriter<T> where T: FuturePayload
      • impl<T> IntoFuture for FutureReader<T> (means you can .await it)
    • StreamPayload and FuturePayload implementations generated automatically based on target world
      • These handle reading/lifting, writing/lowering, cancelling, dropping, etc.
  • Added wit-bindgen-core support for async lifts and lowers
    • This will probably need to evolve as we support other languages

Implementation details: wasmtime

  • See RFC for details
  • New APIs
    • Promise: like Future, but requires a StoreContextMut<T> to make progress
    • LinkerInstance::func_wrap_concurrent and func_new_concurrent
      • => host-defined functions which may execute concurrently wrt both guest and host
    • {Typed}Func::call_concurrent
      • => call guest exports concurrently
    • StreamReader<T> and StreamWriter<T>
    • FutureReader<T> and FutureWriter<T>
  • New wasmtime::component::bindgen options
    • concurrent_imports: generate code using func_wrap_concurrent instead of func_wrap_async
    • concurrent_exports: generate code using call_concurrent instead of call_async
  • Canon built-in implementations for task.return, task.wait, stream.new, etc.
  • Fused adapter support for inter-component async->async, async->sync, and sync->async calls

Implementation headaches: wasmtime

  • The T in Store<T> might not be 'static
    • but we need to defer lowering params and lifting results indefinitely
    • and that means storing closures which take StoreContextMut<T>
    • and rustc gets confused about lifetimes
    • so I use *mut dyn VMStore and unsafe cast to StoreContextMut<T>
      Image Not Showing Possible Reasons
      • The image file may be corrupted
      • The server hosting the image is unavailable
      • The image path is incorrect
      • The image format is not supported
      Learn More →
  • Safely multiplexing access to Store is tricky
    • Must avoid &mut aliasing
    • Functions which convert from &mut to *mut must also return &mut
      • and callers must not use the original &mut again
      • I think?
Select a repo