I would like to pass a shared array buffer into a small Rust processing kernel in a web worker. Since it is simple and numeric, I would like to avoid the complexity of wasm-bindgen.
I have defined a function in sim.rs
, as follows:
#![no_main]
#[no_mangle]
pub unsafe extern fn run(world: *mut i32) -> i32 {
//Note: world.offset_from(ptr::null()) is always 0 here.
world.add(1).write(255);
world.read_volatile()
}
It is compiled without error using rustc --target=wasm32-unknown-unknown sim.rs
to sim.wasm
.
The wasm is loaded and called using the following code in a web worker.
const wasm = await WebAssembly.instantiateStreaming(...)
const calls = wasm.instance.exports
const mem = new Int32Array(5)
mem[0] = 7
console.log('test', calls.run(mem.buffer)) //prints 0, not 7
console.log(mem) //prints Int32Array(5) [7, 0, 0, 0, 0], not [7, 255, 0, 0, 0].
The real buffer I'd like to use is a bit under 4gb, vs the 20b used above, so I'd like to avoid copying it every frame I need to do processing. I know this should be possible, since from what I gather it's been a pretty core issue of WASM from the start.
Another solution I tried was to set the memory as a global when I create the wasm module, but then I can't read the array from Rust because it is not in linear memory reachable with a pointer.
Another solution I was looking at was, since my needs are fairly simple (read from and write to an array), to write that functionality up using WAT. However, I couldn't find any documentation for doing that, especially since I think I had to inject a thing at the module level to import the global.