Good evening, folks - Is it possible to export a rust fn and consume it through wasmtime? I tried doing so through with wasm-bindgen? I tried doing so but I am getting an error. Ultimately, I'd like to export a functions from wasm modules and link them together - similar to the linking
example but using rust instead of the text format.
Thanks!
@Adam Carter you likely won't want to use wasm-bindgen with wasmtime since wasm-bindgen is targeted at web environments, for exporting a Rust function you should be able to use #[no_mangle]
to get an exported function which you can call
Thanks, @Alex Crichton. So, I have an error returning a string from a rust function. My steps are:
given the following
#[no_mangle]
pub extern "C" fn greet() -> String {
format!("Hello, world!")
}
When I run cargo wasi build and wasmtime --invoke greet target/wasm32-wasi/debug/wasi_example.wasi.wasm I get the following output
**Error: failed to run main module target/wasm32-wasi/debug/wasi_example.wasi.wasm
Caused by:
multiple tables: tables count must be at most 1 (at offset 376)**
Removed duplicate message (this UI is confusing lol)
@Adam Carter hm do you still have wasm-bindgen in your dependency graph? You may need to remove that because if that runs it uses anyref
Thanks @Alex Crichton. That was indeed the issue. I still wasn't able to get --invoke
. The generated wat shows that greet
takes two arguments (instead of none).
(module
(type $t0 (func (param i32)))
(func $greet (type $t0) (param $p0 i32)
(local $l1 i32) (local $l2 i32)
(local.set $l1
(i32.const 12))
(i32.store offset=4
(local.get $p0)
(local.get $l1))
(local.set $l2
(i32.const 1048576))
(i32.store
(local.get $p0)
(local.get $l2))
(return))
(table $T0 1 1 funcref)
(memory $memory 17)
(global $g0 (mut i32) (i32.const 1048576))
(global $__data_end i32 (i32.const 1048588))
(global $__heap_base i32 (i32.const 1048588))
(export "memory" (memory 0))
(export "greet" (func $greet))
(export "__data_end" (global 1))
(export "__heap_base" (global 2))
(data $d0 (i32.const 1048576) "Hello, World"))
Do you know why this is? What would the correct parameters be when calling this function from either --invoke
or from rust?
Did you mean to say one: (func $greet (type $t0) (param $p0 i32)
It is an output param-reference to "String" which gets assigned by (i32.store (local.get $p0) (local.get $l2))
at the end
you have to --invoke
with offset/reference into wasm memory
yes String
in Rust doesn't have a stable ABI, so it does "whatever is necessary". In this case the first parameter is a pointer of where to write the string
that's probably not what you want but unfortunately returning a string isn't easy right now. Interface types should improve the situation!
Ok, that makes sense! Thank you all!
Last updated: Dec 23 2024 at 13:07 UTC