From fa608b3e538afe62e8458e7b3910cf2143cc970c Mon Sep 17 00:00:00 2001 From: Alex Beregszaszi Date: Thu, 4 Feb 2021 17:42:50 +0000 Subject: [PATCH 1/9] f --- bindings/rust/src/lib.rs | 23 ++++++++++++++++++++--- 1 file changed, 20 insertions(+), 3 deletions(-) diff --git a/bindings/rust/src/lib.rs b/bindings/rust/src/lib.rs index 66465ae5c..5cf419bd2 100644 --- a/bindings/rust/src/lib.rs +++ b/bindings/rust/src/lib.rs @@ -182,6 +182,15 @@ pub fn parse>(input: &T) -> Result { } } +/// A view of a moduel for inspection. +pub struct ModuleInspector(*const sys::FizzyModule); + +impl ModuleInspector { + pub fn has_start_function(&self) -> bool { + unsafe { sys::fizzy_module_has_start_function(self.0) } + } +} + /// An instance of a module. pub struct Instance(NonNull); @@ -219,6 +228,10 @@ impl Module { Ok(Instance(unsafe { NonNull::new_unchecked(ptr) })) } } + + pub fn inspect(&self) -> &ModuleInspector { + &ModuleInspector { 0: self.0 } + } } /// A WebAssembly value of i32/i64/f32/f64. @@ -455,13 +468,17 @@ impl Instance { } /// Get a read-only pointer to the module. - unsafe fn get_module(&self) -> *const sys::FizzyModule { + unsafe fn get_module_ptr(&self) -> *const sys::FizzyModule { sys::fizzy_get_instance_module(self.0.as_ptr()) } + + fn get_module(&self) -> &ModuleInspector { + &ModuleInspector { 0: unsafe { self.get_module_ptr() } } + } /// Find index of exported function by name. pub fn find_exported_function_index(&self, name: &str) -> Option { - let module = unsafe { self.get_module() }; + let module = unsafe { self.get_module_ptr() }; let name = CString::new(name).expect("CString::new failed"); let mut func_idx: u32 = 0; let found = unsafe { @@ -491,7 +508,7 @@ impl Instance { /// Find function type for a given index. Must be a valid index otherwise behaviour is undefined. unsafe fn get_function_type(&self, func_idx: u32) -> sys::FizzyFunctionType { - let module = self.get_module(); + let module = self.get_module_ptr(); sys::fizzy_get_function_type(module, func_idx) } From c55edd3f92593668b8750d5b0124621349f9b681 Mon Sep 17 00:00:00 2001 From: Alex Beregszaszi Date: Thu, 4 Feb 2021 17:55:12 +0000 Subject: [PATCH 2/9] f --- bindings/rust/src/lib.rs | 39 ++++++++++++++++++++++++++++----------- 1 file changed, 28 insertions(+), 11 deletions(-) diff --git a/bindings/rust/src/lib.rs b/bindings/rust/src/lib.rs index 5cf419bd2..50c81aedf 100644 --- a/bindings/rust/src/lib.rs +++ b/bindings/rust/src/lib.rs @@ -146,20 +146,28 @@ pub fn validate>(input: T) -> Result<(), Error> { } /// A parsed and validated WebAssembly 1.0 module. -pub struct Module(ConstNonNull); +pub struct Module { + ptr: ConstNonNull, + owned: bool, +} impl Drop for Module { fn drop(&mut self) { - unsafe { sys::fizzy_free_module(self.0.as_ptr()) } + if self.owned { + unsafe { sys::fizzy_free_module(self.ptr.as_ptr()) } + } } } impl Clone for Module { fn clone(&self) -> Self { - let ptr = unsafe { sys::fizzy_clone_module(self.0.as_ptr()) }; + let ptr = unsafe { sys::fizzy_clone_module(self.ptr.as_ptr()) }; // TODO: this can be zero in case of memory allocation error, should this be gracefully handled? assert!(!ptr.is_null()); - Module(unsafe { ConstNonNull::new_unchecked(ptr) }) + Module { + ptr: unsafe { ConstNonNull::new_unchecked(ptr) }, + owned: true, + } } } @@ -178,7 +186,10 @@ pub fn parse>(input: &T) -> Result { Err(err.error().unwrap()) } else { debug_assert!(err.code() == 0); - Ok(Module(unsafe { ConstNonNull::new_unchecked(ptr) })) + Ok(Module { + ptr: unsafe { ConstNonNull::new_unchecked(ptr) }, + owned: true, + }) } } @@ -204,10 +215,13 @@ impl Module { /// Create an instance of a module. // TODO: support imported functions pub fn instantiate(self) -> Result { + if !self.owned { + return Err("Not owned".into()); + } let mut err = FizzyErrorBox::new(); let ptr = unsafe { sys::fizzy_instantiate( - self.0.as_ptr(), + self.ptr.as_ptr(), std::ptr::null(), 0, std::ptr::null(), @@ -229,8 +243,8 @@ impl Module { } } - pub fn inspect(&self) -> &ModuleInspector { - &ModuleInspector { 0: self.0 } + pub fn has_start_function(&self) -> bool { + unsafe { sys::fizzy_module_has_start_function(self.ptr.as_ptr()) } } } @@ -471,9 +485,12 @@ impl Instance { unsafe fn get_module_ptr(&self) -> *const sys::FizzyModule { sys::fizzy_get_instance_module(self.0.as_ptr()) } - - fn get_module(&self) -> &ModuleInspector { - &ModuleInspector { 0: unsafe { self.get_module_ptr() } } + + pub fn get_module(&self) -> Module { + Module { + ptr: unsafe { ConstNonNull::new_unchecked(self.get_module_ptr()) }, + owned: false, + } } /// Find index of exported function by name. From 6e2803ec7ff22bbd1b1d9df089309e5cd47663bd Mon Sep 17 00:00:00 2001 From: Alex Beregszaszi Date: Fri, 5 Feb 2021 14:08:38 +0000 Subject: [PATCH 3/9] f --- bindings/rust/src/lib.rs | 3 +++ 1 file changed, 3 insertions(+) diff --git a/bindings/rust/src/lib.rs b/bindings/rust/src/lib.rs index 50c81aedf..437a57222 100644 --- a/bindings/rust/src/lib.rs +++ b/bindings/rust/src/lib.rs @@ -243,6 +243,8 @@ impl Module { } } + /// Returns true if the module has a start function defined. + /// This function will be executed automatically as part of instantiation. pub fn has_start_function(&self) -> bool { unsafe { sys::fizzy_module_has_start_function(self.ptr.as_ptr()) } } @@ -486,6 +488,7 @@ impl Instance { sys::fizzy_get_instance_module(self.0.as_ptr()) } + /// Get a non-owned module instance. pub fn get_module(&self) -> Module { Module { ptr: unsafe { ConstNonNull::new_unchecked(self.get_module_ptr()) }, From 33ff96c646700048472275f8baa70d511dc75972 Mon Sep 17 00:00:00 2001 From: Alex Beregszaszi Date: Fri, 5 Feb 2021 14:26:16 +0000 Subject: [PATCH 4/9] f --- bindings/rust/src/lib.rs | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/bindings/rust/src/lib.rs b/bindings/rust/src/lib.rs index 437a57222..c0c1f0668 100644 --- a/bindings/rust/src/lib.rs +++ b/bindings/rust/src/lib.rs @@ -485,7 +485,9 @@ impl Instance { /// Get a read-only pointer to the module. unsafe fn get_module_ptr(&self) -> *const sys::FizzyModule { - sys::fizzy_get_instance_module(self.0.as_ptr()) + let ptr = sys::fizzy_get_instance_module(self.0.as_ptr()); + debug_assert!(!ptr.is_null()); + ptr } /// Get a non-owned module instance. From e8eb1168b45e8aa4696ae788bdc0b4e64bbb33c9 Mon Sep 17 00:00:00 2001 From: Alex Beregszaszi Date: Fri, 5 Feb 2021 18:23:26 +0000 Subject: [PATCH 5/9] Ref type --- bindings/rust/src/lib.rs | 44 +++++++++++++++++++++++----------------- 1 file changed, 25 insertions(+), 19 deletions(-) diff --git a/bindings/rust/src/lib.rs b/bindings/rust/src/lib.rs index c0c1f0668..ba7e30b84 100644 --- a/bindings/rust/src/lib.rs +++ b/bindings/rust/src/lib.rs @@ -203,11 +203,14 @@ impl ModuleInspector { } /// An instance of a module. -pub struct Instance(NonNull); +pub struct Instance { + instance: NonNull, + module: Module, +} impl Drop for Instance { fn drop(&mut self) { - unsafe { sys::fizzy_free_instance(self.0.as_ptr()) } + unsafe { sys::fizzy_free_instance(self.instance.as_ptr()) } } } @@ -235,12 +238,18 @@ impl Module { // Forget Module (and avoid calling drop) because it has been consumed by instantiate (even if it failed). core::mem::forget(self); if ptr.is_null() { - debug_assert!(err.code() != 0); - Err(err.error().unwrap()) - } else { - debug_assert!(err.code() == 0); - Ok(Instance(unsafe { NonNull::new_unchecked(ptr) })) + return Err("Invalid ptr".into()); } + let instance = unsafe { NonNull::new_unchecked(ptr) }; + Ok(Instance { + instance: instance, + module: Module { + ptr: unsafe { + ConstNonNull::new_unchecked(sys::fizzy_get_instance_module(instance.as_ptr())) + }, + owned: false, + }, + }) } /// Returns true if the module has a start function defined. @@ -437,8 +446,8 @@ impl Instance { /// # Safety /// These slices turn invalid if the memory is resized (i.e. via the WebAssembly `memory.grow` instruction) pub unsafe fn checked_memory_slice(&self, offset: u32, size: usize) -> Result<&[u8], Error> { - let memory_data = sys::fizzy_get_instance_memory_data(self.0.as_ptr()); - let memory_size = sys::fizzy_get_instance_memory_size(self.0.as_ptr()); + let memory_data = sys::fizzy_get_instance_memory_data(self.instance.as_ptr()); + let memory_size = sys::fizzy_get_instance_memory_size(self.instance.as_ptr()); let range = Instance::checked_memory_range(memory_data, memory_size, offset, size)?; // Slices allow empty length, but data must be a valid pointer. debug_assert!(!memory_data.is_null()); @@ -455,8 +464,8 @@ impl Instance { offset: u32, size: usize, ) -> Result<&mut [u8], Error> { - let memory_data = sys::fizzy_get_instance_memory_data(self.0.as_ptr()); - let memory_size = sys::fizzy_get_instance_memory_size(self.0.as_ptr()); + let memory_data = sys::fizzy_get_instance_memory_data(self.instance.as_ptr()); + let memory_size = sys::fizzy_get_instance_memory_size(self.instance.as_ptr()); let range = Instance::checked_memory_range(memory_data, memory_size, offset, size)?; // Slices allow empty length, but data must be a valid pointer. debug_assert!(!memory_data.is_null()); @@ -466,7 +475,7 @@ impl Instance { /// Returns the current memory size, in bytes. pub fn memory_size(&self) -> usize { - unsafe { sys::fizzy_get_instance_memory_size(self.0.as_ptr()) } + unsafe { sys::fizzy_get_instance_memory_size(self.instance.as_ptr()) } } /// Copies memory from `offset` to `target`, for the length of `target.len()`. @@ -485,17 +494,14 @@ impl Instance { /// Get a read-only pointer to the module. unsafe fn get_module_ptr(&self) -> *const sys::FizzyModule { - let ptr = sys::fizzy_get_instance_module(self.0.as_ptr()); + let ptr = sys::fizzy_get_instance_module(self.instance.as_ptr()); debug_assert!(!ptr.is_null()); ptr } /// Get a non-owned module instance. - pub fn get_module(&self) -> Module { - Module { - ptr: unsafe { ConstNonNull::new_unchecked(self.get_module_ptr()) }, - owned: false, - } + pub fn get_module(&self) -> &Module { + &self.module } /// Find index of exported function by name. @@ -521,7 +527,7 @@ impl Instance { /// This function expects a valid `func_idx` and appropriate number of `args`. pub unsafe fn unsafe_execute(&mut self, func_idx: u32, args: &[Value]) -> ExecutionResult { ExecutionResult(sys::fizzy_execute( - self.0.as_ptr(), + self.instance.as_ptr(), func_idx, args.as_ptr(), std::ptr::null_mut(), From d57eb016ec267938cb9cfa802156c15a487a1a7b Mon Sep 17 00:00:00 2001 From: Alex Beregszaszi Date: Sat, 21 May 2022 16:20:06 +0200 Subject: [PATCH 6/9] f --- bindings/rust/src/lib.rs | 27 ++++++++++++++++----------- 1 file changed, 16 insertions(+), 11 deletions(-) diff --git a/bindings/rust/src/lib.rs b/bindings/rust/src/lib.rs index ba7e30b84..fe7fd2e11 100644 --- a/bindings/rust/src/lib.rs +++ b/bindings/rust/src/lib.rs @@ -238,18 +238,23 @@ impl Module { // Forget Module (and avoid calling drop) because it has been consumed by instantiate (even if it failed). core::mem::forget(self); if ptr.is_null() { - return Err("Invalid ptr".into()); - } - let instance = unsafe { NonNull::new_unchecked(ptr) }; - Ok(Instance { - instance: instance, - module: Module { - ptr: unsafe { - ConstNonNull::new_unchecked(sys::fizzy_get_instance_module(instance.as_ptr())) + debug_assert!(err.code() != 0); + Err(err.error().unwrap()) + } else { + debug_assert!(err.code() == 0); + let instance = unsafe { NonNull::new_unchecked(ptr) }; + Ok(Instance { + instance: instance, + module: Module { + ptr: unsafe { + ConstNonNull::new_unchecked(sys::fizzy_get_instance_module( + instance.as_ptr(), + )) + }, + owned: false, }, - owned: false, - }, - }) + }) + } } /// Returns true if the module has a start function defined. From ff41a4fadc1718e80f8640299c2e4d0462959f6f Mon Sep 17 00:00:00 2001 From: Alex Beregszaszi Date: Sat, 21 May 2022 17:46:43 +0200 Subject: [PATCH 7/9] f --- bindings/rust/src/lib.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/bindings/rust/src/lib.rs b/bindings/rust/src/lib.rs index fe7fd2e11..67428dcf7 100644 --- a/bindings/rust/src/lib.rs +++ b/bindings/rust/src/lib.rs @@ -506,6 +506,7 @@ impl Instance { /// Get a non-owned module instance. pub fn get_module(&self) -> &Module { + debug_assert!(!self.module.owned); &self.module } From 6fc878736e39806cf33da16c69637407f99512eb Mon Sep 17 00:00:00 2001 From: Alex Beregszaszi Date: Sat, 28 May 2022 19:05:57 +0200 Subject: [PATCH 8/9] f --- bindings/rust/src/lib.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bindings/rust/src/lib.rs b/bindings/rust/src/lib.rs index 67428dcf7..1523a303e 100644 --- a/bindings/rust/src/lib.rs +++ b/bindings/rust/src/lib.rs @@ -193,7 +193,7 @@ pub fn parse>(input: &T) -> Result { } } -/// A view of a moduel for inspection. +/// A view of a module for inspection. pub struct ModuleInspector(*const sys::FizzyModule); impl ModuleInspector { From 4f6b02e65dbbe7e7c3eec95fe8906afab21db0fb Mon Sep 17 00:00:00 2001 From: Alex Beregszaszi Date: Sat, 28 May 2022 19:14:52 +0200 Subject: [PATCH 9/9] f --- bindings/rust/src/lib.rs | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/bindings/rust/src/lib.rs b/bindings/rust/src/lib.rs index 1523a303e..4f42909f3 100644 --- a/bindings/rust/src/lib.rs +++ b/bindings/rust/src/lib.rs @@ -219,7 +219,9 @@ impl Module { // TODO: support imported functions pub fn instantiate(self) -> Result { if !self.owned { - return Err("Not owned".into()); + return Err(Error::InstantiationFailed( + "Trying to instantiate not owned module".into(), + )); } let mut err = FizzyErrorBox::new(); let ptr = unsafe {