I'm using wasm-bindgen
to build a simple Rust struct with constructor that takes a JS closure, and run it in node.js
.
use wasm_bindgen::prelude::*;
#[wasm_bindgen]
pub struct WasmThing {
func: Box<dyn FnMut()>,
}
#[wasm_bindgen]
impl WasmThing {
#[wasm_bindgen(constructor)]
pub fn new(js_func: js_sys::Function) -> WasmThing {
WasmThing {
func: Box::new(move || {
js_func.call0(&wasm_bindgen::JsValue::UNDEFINED).unwrap();
}),
}
}
}
I then run wasm-pack
to create a package I can import with this WASM.
In my node.js
code, I then create many instances of this WasmThing:
while (true) {
const thing = new WasmThing(() => {
console.log("Hello there!");
});
thing.free();
}
This works for some time, but after ~250 loop iterations I always see this crash when trying to instantiate any more:
RuntimeError: Memory Access out of bounds
at wasm://wasm/0168863a:wasm-function[7107]:0x3ffc48
at wasm://wasm/0168863a:wasm-function[137]:0x100fa1
at new WasmThing (/home/ari/src/wasm-fail/index.js:1)
Both the Node profiler (thru Chrome Devtools) and my actual OS task manager don't show a rise in memory usage before or after happens.
I've tried using the new wasm-bindgen
weakref support, in case something didn't get garbage collected, but it didn't help.
It happens on multiple JS engines - in Node, in Chrome, and in WebKit - so it's not just a V8 bug. I haven't managed to reproduce it in Firefox.
My best guess right now is that either the closure's not getting garbage collected, somehow, or that there's some internal WASM memory type that isn't backed by real (virtual) memory that I'm running out of.
Any ideas on how to continue debugging?