* vm.rs - calling Ctx data_finalizer upon destruction

This commit is contained in:
Yaron Wittenstein 2019-07-15 15:14:09 +03:00
parent 8a471cc235
commit ad10152982

View File

@ -58,6 +58,20 @@ pub struct Ctx {
pub data_finalizer: Option<fn(data: *mut c_void)>,
}
/// When an instance context is destructed, we're calling its `data_finalizer`
/// In order avoid leaking resources.
///
/// Implementing the `data_finalizer` function is the responsibility of the `wasmer` end-user.
///
/// See test: `test_data_finalizer` as an example
impl Drop for Ctx {
fn drop(&mut self) {
if let Some(ref finalizer) = self.data_finalizer {
finalizer(self.data);
}
}
}
/// The internal context of the currently running WebAssembly instance.
///
///
@ -749,14 +763,24 @@ mod vm_ctx_tests {
x: u32,
y: bool,
str: String,
finalizer: Box<FnMut()>,
}
impl Drop for TestData {
fn drop(&mut self) {
(*self.finalizer)();
}
}
fn test_data_finalizer(data: *mut c_void) {
let test_data: &mut TestData = unsafe { &mut *(data as *mut TestData) };
assert_eq!(test_data.x, 10);
assert_eq!(test_data.y, true);
assert_eq!(test_data.str, "Test".to_string());
assert_eq!(10, test_data.x);
assert_eq!(true, test_data.y);
assert_eq!("Test".to_string(), test_data.str,);
println!("hello from finalizer");
drop(test_data);
}
@ -766,7 +790,9 @@ mod vm_ctx_tests {
x: 10,
y: true,
str: "Test".to_string(),
finalizer: Box::new(move || {}),
};
let mut local_backing = LocalBacking {
memories: Map::new().into_boxed_map(),
tables: Map::new().into_boxed_map(),
@ -781,6 +807,7 @@ mod vm_ctx_tests {
internals: crate::backing::Internals([0; crate::backing::INTERNALS_SIZE]),
};
let mut import_backing = ImportBacking {
memories: Map::new().into_boxed_map(),
tables: Map::new().into_boxed_map(),
@ -791,21 +818,24 @@ mod vm_ctx_tests {
vm_tables: Map::new().into_boxed_map(),
vm_globals: Map::new().into_boxed_map(),
};
let module = generate_module();
let data = &mut data as *mut _ as *mut c_void;
let data_ptr = &mut data as *mut _ as *mut c_void;
let ctx = unsafe {
Ctx::new_with_data(
&mut local_backing,
&mut import_backing,
&module,
data,
data_ptr,
test_data_finalizer,
)
};
let ctx_test_data = cast_test_data(ctx.data);
assert_eq!(ctx_test_data.x, 10);
assert_eq!(ctx_test_data.y, true);
assert_eq!(ctx_test_data.str, "Test".to_string());
assert_eq!(10, ctx_test_data.x);
assert_eq!(true, ctx_test_data.y);
assert_eq!("Test".to_string(), ctx_test_data.str);
drop(ctx);
}