Hi, I'm wondering if it's possible to get Rust to emit a wasm function that takes a funcref
as a parameter. This was my best guess, but alas the type in the generated wasm is i32
. Which I guess makes some sense since pointers are emitted as i32
.
extern "C" {
fn register_series(
series: u64,
extract_key: extern fn(buffer: *const u8, len: u32) -> (*const u8, u32),
);
}
const FOO: u64 = 0;
pub extern "C" fn foo_key(buffer: *const u8, len: u32) -> (*const u8, u32) {
(buffer, 8)
}
#[no_mangle]
pub extern "C" fn register_all_series() {
unsafe {
register_series(FOO, foo_key);
}
}
See "register_series" import and it's type, "type (;0;) ..." (at line 2 below). I was hoping to get this instead for the function type:
(type (;0;) (func (param i64 funcref)))
But ended up with this:
(module
(type (;0;) (func (param i64 i32)))
(type (;1;) (func (param i32 i32 i32)))
(type (;2;) (func))
(import "env" "register_series" (func $register_series (type 0)))
(func $_ZN10test_query7foo_key17hac4e0a3afbd67308E (type 1) (param i32 i32 i32)
local.get 0
i32.const 8
i32.store offset=4
local.get 0
local.get 1
i32.store)
(func $register_all_series (type 2)
i64.const 0
i32.const 1
call $register_series)
(table (;0;) 2 2 funcref)
(memory (;0;) 16)
(global (;0;) (mut i32) (i32.const 1048576))
(global (;1;) i32 (i32.const 1048576))
(global (;2;) i32 (i32.const 1048576))
(export "memory" (memory 0))
(export "register_all_series" (func $register_all_series))
(export "__data_end" (global 1))
(export "__heap_base" (global 2))
(elem (;0;) (i32.const 1) func $_ZN10test_query7foo_key17hac4e0a3afbd67308E))
I googled around a bit and couldn't find much info at all about funcref actually... But this test file in wasmtime
makes me think WebAssembly supports funcref
s as parameters: https://github.com/bytecodealliance/wasmtime/blob/c9a3f05afd45961b0b397f97c4ad79cd7a7c807d/tests/all/funcref.rs#L9