Compile async functions with wasm32-wasi target

Hi guys, I coded a simple async function (below) and compiled it to wasm with cargo build --target wasm32-wasi --release command.

// lib.rs
#[no_mangle]
pub async fn plus_one(num: i32) -> i32 {
    num + 1
}

// Cargo.toml
[lib]
crate-type = ["cdylib"]

The generated wasm file are shown below:

My questions are

  1. As shown in line 4, why does it have two params, but no result?
  2. Is there any document or spec about the support for async in WebAssembly?

Thanks!

It's "returning" the state of the new future by writing it to a memory address that's passed to the function.

There's no support for async of any kind built into standard wasm right now, though there are crates like wasm_bindgen_futures that plug Rust futures into the JS Promise system, and you can run a Rust async executor normally as long as it supports wasm.

wasm-bindgen doesn't work with wasi, only with the web. I believe tokio now supports wasm32-wasi, so you could use that. Do note that exporting async functions is not possible, the async runtime has to be run within the wasm module itself. If you are using wasmtime, it has support for async, but in that case the wasm module is programmed as if it is sync. Wasmtime just yields execution in a way transparent to the wasm module.

2 Likes

I believe the wit-bindgen project has support for exposing async functions from WebAssembly, but they do that by generating glue code on both the host and guest to make it all work.

As far as I know, WASI still doesn't support WASM interface types (WASI still only uses an opaque handle type, which is just an index into a table of objects on the other side).

If we had interface types Rust could return an object that exposes the Future trait methods in theory, but it's not clear to me it would make sense for JS to call Future::poll. You would probably still need some bindgen to wrap the Future in a JS Promise interop type.

At the moment Rust gets stumped by the generated Future type and fails to complain about the non ffi safe type, which would probably make this less confusing?