Reputation: 233
I'd like to improve my understanding of memory management and the usage of function free
with wasm-bindgen
.
My understanding is that anything allocated must be freed. In particular this should hold for values passed from JS into Rust.
In the docs, there is an example where a &str
is passed from JS to Rust, and indeed is freed at the end, as expected.
export function greet(arg0) {
const [ptr0, len0] = passStringToWasm(arg0);
try {
const ret = wasm.greet(ptr0, len0);
const ptr = wasm.__wbindgen_boxed_str_ptr(ret);
const len = wasm.__wbindgen_boxed_str_len(ret);
const realRet = getStringFromWasm(ptr, len);
wasm.__wbindgen_boxed_str_free(ret);
return realRet;
} finally {
wasm.__wbindgen_free(ptr0, len0);
}
}
This is generated from the following Rust code.
#[wasm_bindgen]
pub fn greet(a: &str) -> String {
...
}
However, in the following function, which is also generated by wasm-bindgen
, a Uint32Array
is passed to wasm, whereby memory is allocated, but seemingly this memory is not freed at the end of the function.
module.exports.generate_key = function(seed, sid, pid, counterparties, t) {
_assertClass(seed, RngSeed);
var ptr0 = seed.ptr;
seed.ptr = 0;
const ptr1 = passArray32ToWasm0(counterparties, wasm.__wbindgen_malloc);
const len1 = WASM_VECTOR_LEN;
const ret = wasm.generate_key(ptr0, sid, pid, ptr1, len1, t);
return takeObject(ret);
};
This is generated from the following Rust code.
#[wasm_bindgen]
pub async fn generate_key(
seed: RngSeed,
sid: u64,
pid: u32,
counterparties: &[u32],
t: usize,
) -> Result<KeyShare, Error> {
...
}
Why is the memory allocated in passArray32ToWasm0
seemingly not freed here?
Upvotes: 6
Views: 611
Reputation: 49180
When you pass an array from Rust to JavaScript, the memory is still owned by Rust. If you want to free the memory after using it in JavaScript, you need to communicate this back to Rust. One way to achieve this is by using a callback mechanism to inform Rust that the memory is no longer needed in JavaScript, and then Rust can free the memory accordingly.
Basically, for what ever object you are passing to js, you also have to write a clean up function to clean the memory and in js side, you call this callback after you used the object
Upvotes: 0