I am going through wasm-bindgen
guide and i came across the glue code it generates for interacting between js
and rust
. A reference to a value is passed from js to rust. Rust has to wrap it in ManuallyDrop
so that it wont call the Drop
implemented on JsValue
.
pub fn foo(a: &JsValue) {
// ...
}
#[export_name = "foo"]
pub extern "C" fn __wasm_bindgen_generated_foo(arg0: u32) {
let arg0 = unsafe {
ManuallyDrop::new(JsValue::__from_idx(arg0))
};
let arg0 = &*arg0;
foo(arg0);
}
But I do not see a ManuallyDrop::drop
being called on arg0
. So would the JsValue
wrapped in ManuallyDrop
be dropped unless the ManuallyDrop::drop(arg0)
function is called? Wouldnt it cause a memory leak?
ManuallyDrop
does not stop the inner value from being destroyed. It only stops drop
from being called. Consider a Vec
:
pub struct Vec<T> {
ptr: *mut T,
cap: usize,
len: usize,
}
The fields ptr
, cap
, and len
will still be destroyed even when wrapped by ManuallyDrop
. However, any dynamic resources managed (in this case the data referenced by ptr
) will not be released since drop
is not called.
Since JsValue
simply holds a u32
, no leak will occur on the Rust-side. And since the glue code ensures proper cleanup for &JsValue
arguments, no memory is leaked on the Javascript-side.