silence-coding opened issue #8273:
Can the community provide a sample asynchronous wasm implementation for Rust or tools to help developers implement asynchronous wasm for Rust (e.g. wasm-bindgen-futures). I've looked up a lot of information, but nothing has solved my problem.
I was expecting to compile the following rust code into an asynchronous wasm function and execute it via wasmtime, but I'm getting a type mismatch error.
Example:// wasm function #[no_mangle] pub async fn fetch_add(id: i32) -> i32 { id + 1 } // execute it via wasmtime let mut config = Config::new(); config.async_support(true); let engine = Engine::new(&config).unwrap(); let mut linker: Linker<WasiP1Ctx> = Linker::new(&engine); preview1::add_to_linker_async(&mut linker, |s| s)?; let module = Module::from_file(&engine, "target/wasm32-wasi/debug/async.wasm")?; let wasi = WasiCtxBuilder::new() .inherit_stdout() .inherit_stderr() .build_p1(); let mut store = Store::new(&engine, wasi); let instance = linker.instantiate_async(&mut store, &module).await?; let func = instance.get_typed_func::<i32,i32>(&mut store, "fetch_add")?; let i = func.call_async(&mut store, 1).await?;
ERR:
Error: failed to convert function `fetch_add` to given type Caused by: 0: type mismatch with parameters 1: expected 1 types, found 2
When I converted the wasm to wat, I found that it was strangely typed. How do I properly develop an asynchronous wasm implementation of Rust?
(module (type (;0;) (func (param i32 i32))) (type (;1;) (func)) (func $fetch_add (type 0) (param i32 i32) (local i32 i32 i32 i32) global.get $__stack_pointer local.set 2 i32.const 16 local.set 3 local.get 2 local.get 3 i32.sub local.set 4 local.get 4 local.get 1 i32.store offset=12 local.get 0 local.get 1 i32.store i32.const 0 local.set 5 local.get 0 local.get 5 i32.store8 offset=4 return) (func $dummy (type 1)) (func $__wasm_call_dtors (type 1) call $dummy call $dummy) (func $fetch_add.command_export (type 0) (param i32 i32) local.get 0 local.get 1 call $fetch_add call $__wasm_call_dtors) (table (;0;) 1 1 funcref) (memory (;0;) 16) (global $__stack_pointer (mut i32) (i32.const 1048576)) (export "memory" (memory 0)) (export "fetch_add" (func $fetch_add.command_export)))
bjorn3 commented on issue #8273:
You can't directly export an async function using
#[no_mangle] async fn
. Rust doesn't have a stable ABI, so at least it would need to be#[no_mangle] async extern "C" fn
to use the C abi, which would then result inwarning: `extern` fn uses type `impl Future<Output = i32>`, which is not FFI-safe --> src/lib.rs:1:1 | 1 | async extern "C" fn fetch_add(id: i32) -> i32 { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ not FFI-safe | = note: opaque types have no C equivalent = note: `#[warn(improper_ctypes_definitions)]` on by default
as Rust futures don't have a C abi.
I haven't used it myself, but could maybe try https://github.com/dicej/isyswasfa.
silence-coding commented on issue #8273:
You can't directly export an async function using
#[no_mangle] async fn
. Rust doesn't have a stable ABI, so at least it would need to be#[no_mangle] async extern "C" fn
to use the C abi, which would then result in
warning: `extern` fn uses type `impl Future<Output = i32>`, which is not FFI-safe --> src/lib.rs:1:1 | 1 | async extern "C" fn fetch_add(id: i32) -> i32 { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ not FFI-safe | = note: opaque types have no C equivalent = note: `#[warn(improper_ctypes_definitions)]` on by default
as Rust futures don't have a C abi.
I haven't used it myself, but could maybe try https://github.com/dicej/isyswasfa.
You're right, I was hoping for a solution like wasm-bindgen-futures
bjorn3 commented on issue #8273:
I was hoping for a solution like wasm-bindgen-futures
That would be https://github.com/dicej/isyswasfa from my understanding.
alexcrichton closed issue #8273:
Can the community provide a sample asynchronous wasm implementation for Rust or tools to help developers implement asynchronous wasm for Rust (e.g. wasm-bindgen-futures). I've looked up a lot of information, but nothing has solved my problem.
I was expecting to compile the following rust code into an asynchronous wasm function and execute it via wasmtime, but I'm getting a type mismatch error.
Example:// wasm function #[no_mangle] pub async fn fetch_add(id: i32) -> i32 { id + 1 } // execute it via wasmtime let mut config = Config::new(); config.async_support(true); let engine = Engine::new(&config).unwrap(); let mut linker: Linker<WasiP1Ctx> = Linker::new(&engine); preview1::add_to_linker_async(&mut linker, |s| s)?; let module = Module::from_file(&engine, "target/wasm32-wasi/debug/async.wasm")?; let wasi = WasiCtxBuilder::new() .inherit_stdout() .inherit_stderr() .build_p1(); let mut store = Store::new(&engine, wasi); let instance = linker.instantiate_async(&mut store, &module).await?; let func = instance.get_typed_func::<i32,i32>(&mut store, "fetch_add")?; let i = func.call_async(&mut store, 1).await?;
ERR:
Error: failed to convert function `fetch_add` to given type Caused by: 0: type mismatch with parameters 1: expected 1 types, found 2
When I converted the wasm to wat, I found that it was strangely typed. How do I properly develop an asynchronous wasm implementation of Rust?
(module (type (;0;) (func (param i32 i32))) (type (;1;) (func)) (func $fetch_add (type 0) (param i32 i32) (local i32 i32 i32 i32) global.get $__stack_pointer local.set 2 i32.const 16 local.set 3 local.get 2 local.get 3 i32.sub local.set 4 local.get 4 local.get 1 i32.store offset=12 local.get 0 local.get 1 i32.store i32.const 0 local.set 5 local.get 0 local.get 5 i32.store8 offset=4 return) (func $dummy (type 1)) (func $__wasm_call_dtors (type 1) call $dummy call $dummy) (func $fetch_add.command_export (type 0) (param i32 i32) local.get 0 local.get 1 call $fetch_add call $__wasm_call_dtors) (table (;0;) 1 1 funcref) (memory (;0;) 16) (global $__stack_pointer (mut i32) (i32.const 1048576)) (export "memory" (memory 0)) (export "fetch_add" (func $fetch_add.command_export)))
alexcrichton commented on issue #8273:
I'd recommend reading up on what @bjorn3 linked as well. Otherwise though I'd recommend continuing this discussion on Zulip as this doesn't have much to do with Wasmtime itself.
In general I'll say though that it's early days for async. There is no drop-in replacement for wasm-bindgen-futures and there is no host which runs async wasm like wasm-bindgen-futures works with JS. There's no inherent reason for this per-se, it just hasn't been prioritized yet. Wasmtime as-is, though, is not suitable for the full "power" of wasm-bindgen-futures yet. You can invoke multiple host functions concurrently but Wasmtime cannot invoke multiple guest functions concurrently at this time.
Last updated: Nov 22 2024 at 17:03 UTC