diff --git a/bindings/rust/src/lib.rs b/bindings/rust/src/lib.rs index 5052c94f3..3e9ae3cb6 100644 --- a/bindings/rust/src/lib.rs +++ b/bindings/rust/src/lib.rs @@ -52,10 +52,21 @@ pub struct Module(*const sys::FizzyModule); impl Drop for Module { fn drop(&mut self) { + debug_assert!(!self.0.is_null()); unsafe { sys::fizzy_free_module(self.0) } } } +impl Clone for Module { + fn clone(&self) -> Self { + debug_assert!(!self.0.is_null()); + let ptr = unsafe { sys::fizzy_clone_module(self.0) }; + // TODO: this can be zero in case of memory allocation error, should this be gracefully handled? + assert!(!ptr.is_null()); + Module { 0: ptr } + } +} + /// Parse and validate the input according to WebAssembly 1.0 rules. pub fn parse>(input: &T) -> Result { let ptr = unsafe { sys::fizzy_parse(input.as_ref().as_ptr(), input.as_ref().len()) }; @@ -78,7 +89,7 @@ impl Module { /// Create an instance of a module. // TODO: support imported functions pub fn instantiate(self) -> Result { - assert!(!self.0.is_null()); + debug_assert!(!self.0.is_null()); let ptr = unsafe { sys::fizzy_instantiate( self.0, @@ -582,6 +593,18 @@ mod tests { assert!(instance.is_err()); } + #[test] + fn clone_module() { + let module = parse(&[0x00, 0x61, 0x73, 0x6d, 0x01, 0x00, 0x00, 0x00]); + assert!(module.is_ok()); + let module = module.unwrap(); + let module2 = module.clone(); + let instance = module.instantiate(); + assert!(instance.is_ok()); + let instance = module2.instantiate(); + assert!(instance.is_ok()); + } + #[test] fn find_exported_function_index() { /* wat2wasm