From d59f4c2ffdc7ad8e44dc21deb2e0b3c2eba30d35 Mon Sep 17 00:00:00 2001 From: Syrus Akbary Date: Wed, 25 Jan 2023 19:41:39 +0100 Subject: [PATCH 1/2] Use JS VM store instead of artificially replicate it --- lib/api/src/js/export.rs | 56 +++++++----------- lib/api/src/js/externals/function.rs | 35 +++++------ lib/api/src/js/externals/global.rs | 42 +++++--------- lib/api/src/js/externals/memory.rs | 39 +++++-------- lib/api/src/js/externals/memory_view.rs | 3 +- lib/api/src/js/externals/mod.rs | 77 +++++++++---------------- lib/api/src/js/externals/table.rs | 51 +++++----------- lib/api/src/js/instance.rs | 12 ++-- lib/api/src/js/mod.rs | 2 +- lib/api/src/js/module.rs | 9 +-- lib/api/src/js/native.rs | 8 +-- lib/api/src/js/store.rs | 51 ++++------------ lib/api/src/js/types.rs | 7 +-- lib/api/src/js/value.rs | 7 +-- 14 files changed, 129 insertions(+), 270 deletions(-) diff --git a/lib/api/src/js/export.rs b/lib/api/src/js/export.rs index 180f1d76213..c31466cb55c 100644 --- a/lib/api/src/js/export.rs +++ b/lib/api/src/js/export.rs @@ -1,5 +1,5 @@ use crate::js::error::WasmError; -use crate::js::store::{AsStoreMut, AsStoreRef, InternalStoreHandle}; +use crate::js::store::{AsStoreMut, AsStoreRef}; use crate::js::wasm_bindgen_polyfill::Global; use crate::MemoryView; use js_sys::Function; @@ -165,38 +165,26 @@ impl fmt::Debug for VMFunction { #[derive(Debug, Clone)] pub enum Export { /// A function export value. - Function(InternalStoreHandle), + Function(VMFunction), /// A table export value. - Table(InternalStoreHandle), + Table(VMTable), /// A memory export value. - Memory(InternalStoreHandle), + Memory(VMMemory), /// A global export value. - Global(InternalStoreHandle), + Global(VMGlobal), } impl Export { /// Return the export as a `JSValue`. - pub fn as_jsvalue<'context>(&self, store: &'context impl AsStoreRef) -> &'context JsValue { + pub fn as_jsvalue(&self, _store: &impl AsStoreRef) -> JsValue { match self { - Self::Memory(js_wasm_memory) => js_wasm_memory - .get(store.as_store_ref().objects()) - .memory - .as_ref(), - Self::Function(js_func) => js_func - .get(store.as_store_ref().objects()) - .function - .as_ref(), - Self::Table(js_wasm_table) => js_wasm_table - .get(store.as_store_ref().objects()) - .table - .as_ref(), - Self::Global(js_wasm_global) => js_wasm_global - .get(store.as_store_ref().objects()) - .global - .as_ref(), + Self::Memory(js_wasm_memory) => js_wasm_memory.memory.clone().into(), + Self::Function(js_func) => js_func.function.clone().into(), + Self::Table(js_wasm_table) => js_wasm_table.table.clone().into(), + Self::Global(js_wasm_global) => js_wasm_global.global.clone().into(), } } @@ -209,9 +197,9 @@ impl Export { match extern_type { ExternType::Memory(memory_type) => { if val.is_instance_of::() { - Ok(Self::Memory(InternalStoreHandle::new( - &mut store.objects_mut(), - VMMemory::new(val.unchecked_into::(), memory_type), + Ok(Self::Memory(VMMemory::new( + val.unchecked_into::(), + memory_type, ))) } else { Err(WasmError::TypeMismatch( @@ -225,9 +213,9 @@ impl Export { } ExternType::Global(global_type) => { if val.is_instance_of::() { - Ok(Self::Global(InternalStoreHandle::new( - &mut store.objects_mut(), - VMGlobal::new(val.unchecked_into::(), global_type), + Ok(Self::Global(VMGlobal::new( + val.unchecked_into::(), + global_type, ))) } else { panic!("Extern type doesn't match js value type"); @@ -235,9 +223,9 @@ impl Export { } ExternType::Function(function_type) => { if val.is_instance_of::() { - Ok(Self::Function(InternalStoreHandle::new( - &mut store.objects_mut(), - VMFunction::new(val.unchecked_into::(), function_type), + Ok(Self::Function(VMFunction::new( + val.unchecked_into::(), + function_type, ))) } else { panic!("Extern type doesn't match js value type"); @@ -245,9 +233,9 @@ impl Export { } ExternType::Table(table_type) => { if val.is_instance_of::() { - Ok(Self::Table(InternalStoreHandle::new( - &mut store.objects_mut(), - VMTable::new(val.unchecked_into::
(), table_type), + Ok(Self::Table(VMTable::new( + val.unchecked_into::
(), + table_type, ))) } else { panic!("Extern type doesn't match js value type"); diff --git a/lib/api/src/js/externals/function.rs b/lib/api/src/js/externals/function.rs index 378e07e0885..d8968d49c39 100644 --- a/lib/api/src/js/externals/function.rs +++ b/lib/api/src/js/externals/function.rs @@ -2,7 +2,7 @@ pub use self::inner::{FromToNativeWasmType, HostFunction, WasmTypeList, WithEnv, use crate::js::exports::{ExportError, Exportable}; use crate::js::externals::{Extern, VMExtern}; use crate::js::function_env::FunctionEnvMut; -use crate::js::store::{AsStoreMut, AsStoreRef, InternalStoreHandle, StoreHandle, StoreMut}; +use crate::js::store::{AsStoreMut, AsStoreRef, StoreMut}; use crate::js::types::{param_from_js, AsJs}; /* ValFuncRef */ use crate::js::RuntimeError; use crate::js::TypedFunction; @@ -58,11 +58,11 @@ fn results_to_js_array(values: &[Value]) -> Array { /// [Closures as host functions tracking issue](https://github.com/wasmerio/wasmer/issues/1840) #[derive(Clone, PartialEq)] pub struct Function { - pub(crate) handle: StoreHandle, + pub(crate) handle: VMFunction, } -impl From> for Function { - fn from(handle: StoreHandle) -> Self { +impl From for Function { + fn from(handle: VMFunction) -> Self { Self { handle } } } @@ -86,7 +86,7 @@ impl Function { /// To `VMExtern`. pub fn to_vm_extern(&self) -> VMExtern { - VMExtern::Function(self.handle.internal_handle()) + VMExtern::Function(self.handle.clone()) } /// Creates a new host `Function` (dynamic) with the provided signature. @@ -232,7 +232,7 @@ impl Function { let ty = function.ty(); let vm_function = VMFunction::new(binded_func, ty); Self { - handle: StoreHandle::new(store.objects_mut(), vm_function), + handle: vm_function, } } @@ -300,7 +300,7 @@ impl Function { let ty = function.ty(); let vm_function = VMFunction::new(binded_func, ty); Self { - handle: StoreHandle::new(store.objects_mut(), vm_function), + handle: vm_function, } } @@ -322,7 +322,7 @@ impl Function { /// assert_eq!(f.ty().results(), vec![Type::I32]); /// ``` pub fn ty(&self, store: &impl AsStoreRef) -> FunctionType { - self.handle.get(store.as_store_ref().objects()).ty.clone() + self.handle.ty.clone() } /// Returns the number of parameters that this function takes. @@ -422,7 +422,7 @@ impl Function { // TODO: This loop is needed for asyncify. It will be refactored with https://github.com/wasmerio/wasmer/issues/3451 loop { r = js_sys::Reflect::apply( - &self.handle.get(store.as_store_ref().objects()).function, + &self.handle.function, &wasm_bindgen::JsValue::NULL, &arr, ); @@ -446,7 +446,7 @@ impl Function { r? }; - let result_types = self.handle.get(store.as_store_ref().objects()).ty.results(); + let result_types = self.handle.ty.results(); match result_types.len() { 0 => Ok(Box::new([])), 1 => { @@ -467,19 +467,12 @@ impl Function { pub(crate) fn from_vm_export(store: &mut impl AsStoreMut, vm_function: VMFunction) -> Self { Self { - handle: StoreHandle::new(store.objects_mut(), vm_function), + handle: vm_function, } } - pub(crate) fn from_vm_extern( - store: &mut impl AsStoreMut, - internal: InternalStoreHandle, - ) -> Self { - Self { - handle: unsafe { - StoreHandle::from_internal(store.as_store_ref().objects().id(), internal) - }, - } + pub(crate) fn from_vm_extern(store: &mut impl AsStoreMut, internal: VMFunction) -> Self { + Self { handle: internal } } #[deprecated(since = "3.0.0", note = "native() has been renamed to typed().")] @@ -617,7 +610,7 @@ impl Function { /// Checks whether this `Function` can be used with the given context. pub fn is_from_store(&self, store: &impl AsStoreRef) -> bool { - self.handle.store_id() == store.as_store_ref().objects().id() + true } } diff --git a/lib/api/src/js/externals/global.rs b/lib/api/src/js/externals/global.rs index 69b9b9595b8..ee363f0773a 100644 --- a/lib/api/src/js/externals/global.rs +++ b/lib/api/src/js/externals/global.rs @@ -1,7 +1,7 @@ use crate::js::export::VMGlobal; use crate::js::exports::{ExportError, Exportable}; use crate::js::externals::{Extern, VMExtern}; -use crate::js::store::{AsStoreMut, AsStoreRef, InternalStoreHandle, StoreHandle}; +use crate::js::store::{AsStoreMut, AsStoreRef}; use crate::js::value::Value; use crate::js::wasm_bindgen_polyfill::Global as JSGlobal; use crate::js::GlobalType; @@ -17,7 +17,7 @@ use wasm_bindgen::JsValue; /// Spec: #[derive(Debug, Clone, PartialEq)] pub struct Global { - pub(crate) handle: StoreHandle, + pub(crate) handle: VMGlobal, } impl Global { @@ -57,7 +57,7 @@ impl Global { /// To `VMExtern`. pub(crate) fn to_vm_extern(&self) -> VMExtern { - VMExtern::Global(self.handle.internal_handle()) + VMExtern::Global(self.handle.clone()) } /// Create a `Global` with the initial value [`Value`] and the provided [`Mutability`]. @@ -113,7 +113,7 @@ impl Global { /// assert_eq!(v.ty(), &GlobalType::new(Type::I64, Mutability::Var)); /// ``` pub fn ty(&self, store: &impl AsStoreRef) -> GlobalType { - self.handle.get(store.as_store_ref().objects()).ty + self.handle.ty } /// Retrieves the current value [`Value`] that the Global has. @@ -130,14 +130,8 @@ impl Global { /// ``` pub fn get(&self, store: &impl AsStoreRef) -> Value { unsafe { - let raw = self - .handle - .get(store.as_store_ref().objects()) - .global - .value() - .as_f64() - .unwrap(); - let ty = self.handle.get(store.as_store_ref().objects()).ty; + let raw = self.handle.global.value().as_f64().unwrap(); + let ty = self.handle.ty; Value::from_raw(store, ty.ty, raw) } } @@ -207,33 +201,23 @@ impl Global { )) } }; - self.handle - .get_mut(store.objects_mut()) - .global - .set_value(&new_value); + self.handle.global.set_value(&new_value); Ok(()) } pub(crate) fn from_vm_export(store: &mut impl AsStoreMut, vm_global: VMGlobal) -> Self { - Self { - handle: StoreHandle::new(store.objects_mut(), vm_global), - } + use crate::js::store::StoreObject; + VMGlobal::list_mut(store.objects_mut()).push(vm_global.clone()); + Self { handle: vm_global } } - pub(crate) fn from_vm_extern( - store: &mut impl AsStoreMut, - internal: InternalStoreHandle, - ) -> Self { - Self { - handle: unsafe { - StoreHandle::from_internal(store.as_store_ref().objects().id(), internal) - }, - } + pub(crate) fn from_vm_extern(store: &mut impl AsStoreMut, internal: VMGlobal) -> Self { + Self { handle: internal } } /// Checks whether this `Global` can be used with the given store. pub fn is_from_store(&self, store: &impl AsStoreRef) -> bool { - self.handle.store_id() == store.as_store_ref().objects().id() + true } } diff --git a/lib/api/src/js/externals/memory.rs b/lib/api/src/js/externals/memory.rs index 58da006b201..e136cb75c8b 100644 --- a/lib/api/src/js/externals/memory.rs +++ b/lib/api/src/js/externals/memory.rs @@ -1,7 +1,7 @@ use crate::js::export::VMMemory; use crate::js::exports::{ExportError, Exportable}; use crate::js::externals::{Extern, VMExtern}; -use crate::js::store::{AsStoreMut, AsStoreRef, InternalStoreHandle, StoreHandle, StoreObjects}; +use crate::js::store::{AsStoreMut, AsStoreRef, StoreObjects}; use crate::js::{MemoryAccessError, MemoryType}; use std::marker::PhantomData; use std::mem::MaybeUninit; @@ -65,7 +65,7 @@ extern "C" { /// Spec: #[derive(Debug, Clone)] pub struct Memory { - pub(crate) handle: StoreHandle, + pub(crate) handle: VMMemory, } unsafe impl Send for Memory {} @@ -115,19 +115,17 @@ impl Memory { ty: MemoryType, ) -> Result { let vm_memory = VMMemory::new(js_memory, ty); - let handle = StoreHandle::new(store.objects_mut(), vm_memory); - Ok(Self::from_vm_extern(store, handle.internal_handle())) + Ok(Self::from_vm_extern(store, vm_memory)) } /// Create a memory object from an existing memory and attaches it to the store pub fn new_from_existing(new_store: &mut impl AsStoreMut, memory: VMMemory) -> Self { - let handle = StoreHandle::new(new_store.objects_mut(), memory); - Self::from_vm_extern(new_store, handle.internal_handle()) + Self::from_vm_extern(new_store, memory) } /// To `VMExtern`. pub(crate) fn to_vm_extern(&self) -> VMExtern { - VMExtern::Memory(self.handle.internal_handle()) + VMExtern::Memory(self.handle.clone()) } /// Returns the [`MemoryType`] of the `Memory`. @@ -144,7 +142,7 @@ impl Memory { /// assert_eq!(m.ty(), mt); /// ``` pub fn ty(&self, store: &impl AsStoreRef) -> MemoryType { - self.handle.get(store.as_store_ref().objects()).ty + self.handle.ty } /// Creates a view into the memory that then allows for @@ -192,7 +190,7 @@ impl Memory { IntoPages: Into, { let pages = delta.into(); - let js_memory = &self.handle.get_mut(store.objects_mut()).memory; + let js_memory = &self.handle.memory; let our_js_memory: &JSMemory = JsCast::unchecked_from_js_ref(js_memory); let new_pages = our_js_memory.grow(pages.0).map_err(|err| { if err.is_instance_of::() { @@ -237,37 +235,26 @@ impl Memory { } pub(crate) fn from_vm_export(store: &mut impl AsStoreMut, vm_memory: VMMemory) -> Self { - Self { - handle: StoreHandle::new(store.objects_mut(), vm_memory), - } + Self { handle: vm_memory } } - pub(crate) fn from_vm_extern( - store: &mut impl AsStoreMut, - internal: InternalStoreHandle, - ) -> Self { - Self { - handle: unsafe { - StoreHandle::from_internal(store.as_store_ref().objects().id(), internal) - }, - } + pub(crate) fn from_vm_extern(store: &mut impl AsStoreMut, internal: VMMemory) -> Self { + Self { handle: internal } } /// Attempts to clone this memory (if its clonable) pub fn try_clone(&self, store: &impl AsStoreRef) -> Option { - let mem = self.handle.get(store.as_store_ref().objects()); - mem.try_clone() + self.handle.try_clone() } /// Checks whether this `Global` can be used with the given context. pub fn is_from_store(&self, store: &impl AsStoreRef) -> bool { - self.handle.store_id() == store.as_store_ref().objects().id() + true } /// Copies this memory to a new memory pub fn duplicate(&mut self, store: &impl AsStoreRef) -> Result { - let mem = self.handle.get(store.as_store_ref().objects()); - mem.duplicate() + self.handle.duplicate() } } diff --git a/lib/api/src/js/externals/memory_view.rs b/lib/api/src/js/externals/memory_view.rs index d4eb10e44f7..dff829affcd 100644 --- a/lib/api/src/js/externals/memory_view.rs +++ b/lib/api/src/js/externals/memory_view.rs @@ -27,8 +27,7 @@ pub struct MemoryView<'a> { impl<'a> MemoryView<'a> { pub(crate) fn new(memory: &Memory, store: &impl AsStoreRef) -> Self { - let memory = memory.handle.get(store.as_store_ref().objects()); - Self::new_raw(&memory.memory) + Self::new_raw(&memory.handle.memory) } pub(crate) fn new_raw(memory: &js_sys::WebAssembly::Memory) -> Self { diff --git a/lib/api/src/js/externals/mod.rs b/lib/api/src/js/externals/mod.rs index 259a8e13c9e..63a77f2b643 100644 --- a/lib/api/src/js/externals/mod.rs +++ b/lib/api/src/js/externals/mod.rs @@ -10,21 +10,12 @@ pub use self::memory::{Memory, MemoryError}; pub use self::memory_view::MemoryView; pub use self::table::Table; +use crate::js::error::WasmError; use crate::js::export::{Export, VMFunction, VMGlobal, VMMemory, VMTable}; use crate::js::exports::{ExportError, Exportable}; use crate::js::store::StoreObject; -use crate::js::types::AsJs; - -/* - - -use crate::js::store::InternalStoreHandle; use crate::js::store::{AsStoreMut, AsStoreRef}; -use crate::js::ExternType; -use std::fmt; -*/ -use crate::js::error::WasmError; -use crate::js::store::{AsStoreMut, AsStoreRef, InternalStoreHandle}; +use crate::js::types::AsJs; use crate::js::wasm_bindgen_polyfill::Global as JsGlobal; use js_sys::Function as JsFunction; use js_sys::WebAssembly::{Memory as JsMemory, Table as JsTable}; @@ -35,38 +26,26 @@ use wasmer_types::ExternType; /// The value of an export passed from one instance to another. pub enum VMExtern { /// A function export value. - Function(InternalStoreHandle), + Function(VMFunction), /// A table export value. - Table(InternalStoreHandle), + Table(VMTable), /// A memory export value. - Memory(InternalStoreHandle), + Memory(VMMemory), /// A global export value. - Global(InternalStoreHandle), + Global(VMGlobal), } impl VMExtern { /// Return the export as a `JSValue`. - pub fn as_jsvalue<'context>(&self, store: &'context impl AsStoreRef) -> &'context JsValue { + pub fn as_jsvalue<'context>(&self, store: &'context impl AsStoreRef) -> JsValue { match self { - Self::Memory(js_wasm_memory) => js_wasm_memory - .get(store.as_store_ref().objects()) - .memory - .as_ref(), - Self::Function(js_func) => js_func - .get(store.as_store_ref().objects()) - .function - .as_ref(), - Self::Table(js_wasm_table) => js_wasm_table - .get(store.as_store_ref().objects()) - .table - .as_ref(), - Self::Global(js_wasm_global) => js_wasm_global - .get(store.as_store_ref().objects()) - .global - .as_ref(), + Self::Memory(js_wasm_memory) => js_wasm_memory.memory.clone().into(), + Self::Function(js_func) => js_func.function.clone().into(), + Self::Table(js_wasm_table) => js_wasm_table.table.clone().into(), + Self::Global(js_wasm_global) => js_wasm_global.global.clone().into(), } } @@ -79,9 +58,9 @@ impl VMExtern { match extern_type { ExternType::Memory(memory_type) => { if val.is_instance_of::() { - Ok(Self::Memory(InternalStoreHandle::new( - &mut store.objects_mut(), - VMMemory::new(val.unchecked_into::(), memory_type), + Ok(Self::Memory(VMMemory::new( + val.unchecked_into::(), + memory_type, ))) } else { Err(WasmError::TypeMismatch( @@ -95,9 +74,9 @@ impl VMExtern { } ExternType::Global(global_type) => { if val.is_instance_of::() { - Ok(Self::Global(InternalStoreHandle::new( - &mut store.objects_mut(), - VMGlobal::new(val.unchecked_into::(), global_type), + Ok(Self::Global(VMGlobal::new( + val.unchecked_into::(), + global_type, ))) } else { panic!("Extern type doesn't match js value type"); @@ -105,9 +84,9 @@ impl VMExtern { } ExternType::Function(function_type) => { if val.is_instance_of::() { - Ok(Self::Function(InternalStoreHandle::new( - &mut store.objects_mut(), - VMFunction::new(val.unchecked_into::(), function_type), + Ok(Self::Function(VMFunction::new( + val.unchecked_into::(), + function_type, ))) } else { panic!("Extern type doesn't match js value type"); @@ -115,9 +94,9 @@ impl VMExtern { } ExternType::Table(table_type) => { if val.is_instance_of::() { - Ok(Self::Table(InternalStoreHandle::new( - &mut store.objects_mut(), - VMTable::new(val.unchecked_into::(), table_type), + Ok(Self::Table(VMTable::new( + val.unchecked_into::(), + table_type, ))) } else { panic!("Extern type doesn't match js value type"); @@ -186,10 +165,10 @@ impl Extern { fn to_export(&self) -> Export { match self { - Self::Function(val) => Export::Function(val.handle.internal_handle()), - Self::Memory(val) => Export::Memory(val.handle.internal_handle()), - Self::Global(val) => Export::Global(val.handle.internal_handle()), - Self::Table(val) => Export::Table(val.handle.internal_handle()), + Self::Function(val) => Export::Function(val.handle.clone()), + Self::Memory(val) => Export::Memory(val.handle.clone()), + Self::Global(val) => Export::Global(val.handle.clone()), + Self::Table(val) => Export::Table(val.handle.clone()), } } } @@ -213,8 +192,6 @@ impl<'a> Exportable<'a> for Extern { } } -impl StoreObject for Extern {} - impl fmt::Debug for Extern { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { write!( diff --git a/lib/api/src/js/externals/table.rs b/lib/api/src/js/externals/table.rs index e81400bb60d..ef09fff9be4 100644 --- a/lib/api/src/js/externals/table.rs +++ b/lib/api/src/js/externals/table.rs @@ -1,7 +1,7 @@ use crate::js::export::{VMFunction, VMTable}; use crate::js::exports::{ExportError, Exportable}; use crate::js::externals::{Extern, VMExtern}; -use crate::js::store::{AsStoreMut, AsStoreRef, InternalStoreHandle, StoreHandle}; +use crate::js::store::{AsStoreMut, AsStoreRef}; use crate::js::value::Value; use crate::js::RuntimeError; use crate::js::{FunctionType, TableType}; @@ -18,7 +18,7 @@ use js_sys::Function; /// Spec: #[derive(Debug, Clone, PartialEq)] pub struct Table { - pub(crate) handle: StoreHandle, + pub(crate) handle: VMTable, } fn set_table_item(table: &VMTable, item_index: u32, item: &Function) -> Result<(), RuntimeError> { @@ -30,12 +30,7 @@ fn get_function(store: &mut impl AsStoreMut, val: Value) -> Result Ok(func - .handle - .get(&store.as_store_ref().objects()) - .function - .clone() - .into()), + Value::FuncRef(Some(ref func)) => Ok(func.handle.function.clone().into()), // Only funcrefs is supported by the spec atm _ => unimplemented!(), } @@ -70,30 +65,22 @@ impl Table { set_table_item(&table, i, &func)?; } - Ok(Self { - handle: StoreHandle::new(store.objects_mut(), table), - }) + Ok(Self { handle: table }) } /// To `VMExtern`. pub fn to_vm_extern(&self) -> VMExtern { - VMExtern::Table(self.handle.internal_handle()) + VMExtern::Table(self.handle.clone()) } /// Returns the [`TableType`] of the `Table`. pub fn ty(&self, store: &impl AsStoreRef) -> TableType { - self.handle.get(store.as_store_ref().objects()).ty + self.handle.ty } /// Retrieves an element of the table at the provided `index`. pub fn get(&self, store: &mut impl AsStoreMut, index: u32) -> Option { - if let Some(func) = self - .handle - .get(store.as_store_ref().objects()) - .table - .get(index) - .ok() - { + if let Some(func) = self.handle.table.get(index).ok() { let ty = FunctionType::new(vec![], vec![]); let vm_function = VMFunction::new(func, ty); let function = crate::js::externals::Function::from_vm_export(store, vm_function); @@ -111,15 +98,12 @@ impl Table { val: Value, ) -> Result<(), RuntimeError> { let item = get_function(store, val)?; - set_table_item(self.handle.get_mut(store.objects_mut()), index, &item) + set_table_item(&self.handle, index, &item) } /// Retrieves the size of the `Table` (in elements) pub fn size(&self, store: &impl AsStoreRef) -> u32 { - self.handle - .get(store.as_store_ref().objects()) - .table - .length() + self.handle.table.length() } /// Grows the size of the `Table` by `delta`, initializating @@ -158,20 +142,13 @@ impl Table { unimplemented!("Table.copy is not natively supported in Javascript"); } - pub(crate) fn from_vm_extern( - store: &mut impl AsStoreMut, - internal: InternalStoreHandle, - ) -> Self { - Self { - handle: unsafe { - StoreHandle::from_internal(store.as_store_ref().objects().id(), internal) - }, - } + pub(crate) fn from_vm_extern(store: &mut impl AsStoreMut, internal: VMTable) -> Self { + Self { handle: internal } } /// Checks whether this `Table` can be used with the given context. pub fn is_from_store(&self, store: &impl AsStoreRef) -> bool { - self.handle.store_id() == store.as_store_ref().objects().id() + true } /// Get access to the backing VM value for this extern. This function is for @@ -183,10 +160,10 @@ impl Table { /// make breaking changes to it at any time or remove this method. #[doc(hidden)] pub unsafe fn get_vm_table<'context>( - &self, + &'context self, store: &'context impl AsStoreRef, ) -> &'context VMTable { - self.handle.get(store.as_store_ref().objects()) + &self.handle } } diff --git a/lib/api/src/js/instance.rs b/lib/api/src/js/instance.rs index 255240c5e82..eea05cdcb58 100644 --- a/lib/api/src/js/instance.rs +++ b/lib/api/src/js/instance.rs @@ -3,7 +3,7 @@ use crate::js::exports::Exports; use crate::js::externals::Extern; use crate::js::imports::Imports; use crate::js::module::Module; -use crate::js::store::{AsStoreMut, AsStoreRef, StoreHandle}; +use crate::js::store::{AsStoreMut, AsStoreRef}; use js_sys::WebAssembly; use std::fmt; @@ -17,7 +17,7 @@ use std::fmt; /// Spec: #[derive(Clone)] pub struct Instance { - _handle: StoreHandle, + handle: WebAssembly::Instance, module: Module, /// The exports for an instance. pub exports: Exports, @@ -66,7 +66,6 @@ impl Instance { .instantiate(&mut store, imports) .map_err(|e| InstantiationError::Start(e))?; - let instance = instance.get(store.objects_mut()).clone(); let mut self_instance = Self::from_module_and_instance(store, module, instance)?; self_instance.ensure_memory_export(store, externs); //self_instance.init_envs(&imports.iter().map(Extern::to_export).collect::>())?; @@ -131,9 +130,8 @@ impl Instance { }) .collect::>()?; - let handle = StoreHandle::new(store.as_store_mut().objects_mut(), instance); Ok(Self { - _handle: handle, + handle: instance, module: module.clone(), exports, }) @@ -162,10 +160,10 @@ impl Instance { /// Returns the inner WebAssembly Instance #[doc(hidden)] pub fn raw<'context>( - &self, + &'context self, store: &'context impl AsStoreRef, ) -> &'context WebAssembly::Instance { - &self._handle.get(store.as_store_ref().objects()) + &self.handle } } diff --git a/lib/api/src/js/mod.rs b/lib/api/src/js/mod.rs index baa41641fbf..c20f15f89e8 100644 --- a/lib/api/src/js/mod.rs +++ b/lib/api/src/js/mod.rs @@ -61,7 +61,7 @@ pub use crate::js::ptr::{Memory32, Memory64, MemorySize, WasmPtr, WasmPtr64}; pub use crate::js::trap::RuntimeError; pub use crate::js::store::{ - AsStoreMut, AsStoreRef, Store, StoreHandle, StoreMut, StoreObject, StoreObjects, StoreRef, + AsStoreMut, AsStoreRef, Store, StoreHandle, StoreMut, StoreObjects, StoreRef, }; pub use crate::js::types::ValType as Type; pub use crate::js::types::{ diff --git a/lib/api/src/js/module.rs b/lib/api/src/js/module.rs index 7b22ffaa0b1..c957dd3e0cb 100644 --- a/lib/api/src/js/module.rs +++ b/lib/api/src/js/module.rs @@ -246,7 +246,7 @@ impl Module { &self, store: &mut impl AsStoreMut, imports: &Imports, - ) -> Result<(crate::StoreHandle, Vec), RuntimeError> { + ) -> Result<(WebAssembly::Instance, Vec), RuntimeError> { // Ensure all imports come from the same store. if imports .into_iter() @@ -324,11 +324,8 @@ impl Module { // the error for us, so we don't need to handle it } Ok(( - crate::StoreHandle::new( - store.as_store_mut().objects_mut(), - WebAssembly::Instance::new(&self.module, &imports_object) - .map_err(|e: JsValue| -> RuntimeError { e.into() })?, - ), + WebAssembly::Instance::new(&self.module, &imports_object) + .map_err(|e: JsValue| -> RuntimeError { e.into() })?, import_externs, )) } diff --git a/lib/api/src/js/native.rs b/lib/api/src/js/native.rs index 661034ac972..ae5a6cd9eda 100644 --- a/lib/api/src/js/native.rs +++ b/lib/api/src/js/native.rs @@ -10,7 +10,7 @@ use std::marker::PhantomData; use crate::js::externals::Function; -use crate::js::store::{AsStoreMut, AsStoreRef, StoreHandle}; +use crate::js::store::{AsStoreMut, AsStoreRef}; use crate::js::{FromToNativeWasmType, RuntimeError, WasmTypeList}; // use std::panic::{catch_unwind, AssertUnwindSafe}; use crate::js::export::VMFunction; @@ -25,7 +25,7 @@ use wasmer_types::RawValue; /// (using the Native ABI). #[derive(Clone)] pub struct TypedFunction { - pub(crate) handle: StoreHandle, + pub(crate) handle: VMFunction, _phantom: PhantomData<(Args, Rets)>, } @@ -40,7 +40,7 @@ where #[allow(dead_code)] pub(crate) fn new(store: &mut impl AsStoreMut, vm_function: VMFunction) -> Self { Self { - handle: StoreHandle::new(store.as_store_mut().objects_mut(), vm_function), + handle: vm_function, _phantom: PhantomData, } } @@ -78,7 +78,7 @@ macro_rules! impl_native_traits { let mut r; // TODO: This loop is needed for asyncify. It will be refactored with https://github.com/wasmerio/wasmer/issues/3451 loop { - r = self.handle.get(store.as_store_ref().objects()).function.apply( + r = self.handle.function.apply( &JsValue::UNDEFINED, &Array::from_iter(params_list.iter()) ); diff --git a/lib/api/src/js/store.rs b/lib/api/src/js/store.rs index 830841d0642..c730aaeec05 100644 --- a/lib/api/src/js/store.rs +++ b/lib/api/src/js/store.rs @@ -78,14 +78,6 @@ impl fmt::Debug for Store { } } -/// A trait represinting any object that lives in the `Store`. -pub trait StoreObject { - /// Return true if the object `Store` is the same as the provided `Store`. - fn comes_from_same_store(&self, _store: &Store) -> bool { - true - } -} - impl AsStoreRef for Store { fn as_store_ref(&self) -> StoreRef<'_> { StoreRef { inner: &self.inner } @@ -207,7 +199,8 @@ impl AsStoreMut for &'_ mut T { } } -pub use objects::*; +pub(crate) use objects::{InternalStoreHandle, StoreObject}; +pub use objects::{StoreHandle, StoreId, StoreObjects}; mod objects { use wasm_bindgen::JsValue; @@ -266,11 +259,15 @@ mod objects { } impl_store_object! { - functions => VMFunction, - tables => VMTable, + // Note: we store the globals in order to be able to access them later via + // `StoreObjects::iter_globals`. globals => VMGlobal, - memories => VMMemory, - instances => js_sys::WebAssembly::Instance, + // functions => VMFunction, + // tables => VMTable, + // memories => VMMemory, + // The function environments are the only things attached to a store, + // since the other JS objects (table, globals, memory and functions) + // live in the JS VM Store by default function_environments => VMFunctionEnvironment, } @@ -278,11 +275,7 @@ mod objects { #[derive(Default)] pub struct StoreObjects { id: StoreId, - memories: Vec, - tables: Vec, globals: Vec, - functions: Vec, - instances: Vec, function_environments: Vec, } @@ -482,28 +475,4 @@ mod objects { }) } } - - /// Data used by the generated code is generally located inline within the - /// `VMContext` for items defined in an instance. Host-defined objects are - /// allocated separately and owned directly by the context. - #[allow(dead_code)] - pub enum MaybeInstanceOwned { - /// The data is owned here. - Host(Box>), - - /// The data is stored inline in the `VMContext` of an instance. - Instance(NonNull), - } - - #[allow(dead_code)] - impl MaybeInstanceOwned { - /// Returns underlying pointer to the VM data. - #[allow(dead_code)] - pub fn as_ptr(&self) -> NonNull { - match self { - MaybeInstanceOwned::Host(p) => unsafe { NonNull::new_unchecked(p.get()) }, - MaybeInstanceOwned::Instance(p) => *p, - } - } - } } diff --git a/lib/api/src/js/types.rs b/lib/api/src/js/types.rs index 6b2da916594..cdd03f7b447 100644 --- a/lib/api/src/js/types.rs +++ b/lib/api/src/js/types.rs @@ -44,12 +44,7 @@ impl AsJs for Value { Self::F32(f) => JsValue::from_f64(*f as f64), Self::F64(f) => JsValue::from_f64(*f), Self::V128(f) => JsValue::from_f64(*f as f64), - Self::FuncRef(Some(func)) => func - .handle - .get(store.as_store_ref().objects()) - .function - .clone() - .into(), + Self::FuncRef(Some(func)) => func.handle.function.clone().into(), Self::FuncRef(None) => JsValue::null(), } } diff --git a/lib/api/src/js/value.rs b/lib/api/src/js/value.rs index 828cdc165f0..a59a1e0796b 100644 --- a/lib/api/src/js/value.rs +++ b/lib/api/src/js/value.rs @@ -94,12 +94,7 @@ impl Value { Self::F32(v) => v as f64, Self::F64(v) => v, Self::V128(v) => v as f64, - Self::FuncRef(Some(ref f)) => f - .handle - .get(store.as_store_ref().objects()) - .function - .as_f64() - .unwrap_or(0_f64), //TODO is this correct? + Self::FuncRef(Some(ref f)) => f.handle.function.as_f64().unwrap_or(0_f64), //TODO is this correct? Self::FuncRef(None) => 0_f64, //Self::ExternRef(Some(ref e)) => unsafe { *e.address().0 } as .into_raw(), From 6707e67d9e7b2832f96905677e8c7d567c635878 Mon Sep 17 00:00:00 2001 From: Syrus Akbary Date: Thu, 26 Jan 2023 13:25:08 +0100 Subject: [PATCH 2/2] Remove deprecated `Export` type. Updated structure to use VMExtern --- lib/api/src/js/externals/function.rs | 23 ++-- lib/api/src/js/externals/global.rs | 16 +-- lib/api/src/js/externals/memory.rs | 20 ++- lib/api/src/js/externals/memory_view.rs | 2 +- lib/api/src/js/externals/mod.rs | 108 +--------------- lib/api/src/js/externals/table.rs | 16 +-- lib/api/src/js/imports.rs | 160 +----------------------- lib/api/src/js/instance.rs | 7 +- lib/api/src/js/mod.rs | 8 +- lib/api/src/js/module.rs | 2 +- lib/api/src/js/native.rs | 4 +- lib/api/src/js/store.rs | 7 +- lib/api/src/js/types.rs | 2 +- lib/api/src/js/value.rs | 2 +- lib/api/src/js/{export.rs => vm.rs} | 34 +++-- 15 files changed, 69 insertions(+), 342 deletions(-) rename lib/api/src/js/{export.rs => vm.rs} (85%) diff --git a/lib/api/src/js/externals/function.rs b/lib/api/src/js/externals/function.rs index d8968d49c39..7b7115f473b 100644 --- a/lib/api/src/js/externals/function.rs +++ b/lib/api/src/js/externals/function.rs @@ -1,9 +1,10 @@ pub use self::inner::{FromToNativeWasmType, HostFunction, WasmTypeList, WithEnv, WithoutEnv}; use crate::js::exports::{ExportError, Exportable}; -use crate::js::externals::{Extern, VMExtern}; +use crate::js::externals::Extern; use crate::js::function_env::FunctionEnvMut; use crate::js::store::{AsStoreMut, AsStoreRef, StoreMut}; use crate::js::types::{param_from_js, AsJs}; /* ValFuncRef */ +use crate::js::vm::VMExtern; use crate::js::RuntimeError; use crate::js::TypedFunction; use crate::js::Value; @@ -13,7 +14,7 @@ use std::iter::FromIterator; use wasm_bindgen::prelude::*; use wasm_bindgen::JsCast; -use crate::js::export::VMFunction; +use crate::js::vm::VMFunction; use std::fmt; #[repr(C)] @@ -190,7 +191,7 @@ impl Function { JSFunction::new_with_args("f", "return f(Array.prototype.slice.call(arguments, 1))"); let binded_func = dyn_func.bind1(&JsValue::UNDEFINED, &wrapped_func); let vm_function = VMFunction::new(binded_func, func_ty); - Self::from_vm_export(&mut store, vm_function) + Self::from_vm_extern(&mut store, vm_function) } #[deprecated( @@ -214,7 +215,7 @@ impl Function { Args: WasmTypeList, Rets: WasmTypeList, { - let mut store = store.as_store_mut(); + let store = store.as_store_mut(); if std::mem::size_of::() != 0 { Self::closures_unsupported_panic(); } @@ -281,7 +282,7 @@ impl Function { Args: WasmTypeList, Rets: WasmTypeList, { - let mut store = store.as_store_mut(); + let store = store.as_store_mut(); if std::mem::size_of::() != 0 { Self::closures_unsupported_panic(); } @@ -321,7 +322,7 @@ impl Function { /// assert_eq!(f.ty().params(), vec![Type::I32, Type::I32]); /// assert_eq!(f.ty().results(), vec![Type::I32]); /// ``` - pub fn ty(&self, store: &impl AsStoreRef) -> FunctionType { + pub fn ty(&self, _store: &impl AsStoreRef) -> FunctionType { self.handle.ty.clone() } @@ -465,13 +466,7 @@ impl Function { } } - pub(crate) fn from_vm_export(store: &mut impl AsStoreMut, vm_function: VMFunction) -> Self { - Self { - handle: vm_function, - } - } - - pub(crate) fn from_vm_extern(store: &mut impl AsStoreMut, internal: VMFunction) -> Self { + pub(crate) fn from_vm_extern(_store: &mut impl AsStoreMut, internal: VMFunction) -> Self { Self { handle: internal } } @@ -609,7 +604,7 @@ impl Function { } /// Checks whether this `Function` can be used with the given context. - pub fn is_from_store(&self, store: &impl AsStoreRef) -> bool { + pub fn is_from_store(&self, _store: &impl AsStoreRef) -> bool { true } } diff --git a/lib/api/src/js/externals/global.rs b/lib/api/src/js/externals/global.rs index ee363f0773a..2572cbb1fbe 100644 --- a/lib/api/src/js/externals/global.rs +++ b/lib/api/src/js/externals/global.rs @@ -1,8 +1,8 @@ -use crate::js::export::VMGlobal; use crate::js::exports::{ExportError, Exportable}; -use crate::js::externals::{Extern, VMExtern}; +use crate::js::externals::Extern; use crate::js::store::{AsStoreMut, AsStoreRef}; use crate::js::value::Value; +use crate::js::vm::{VMExtern, VMGlobal}; use crate::js::wasm_bindgen_polyfill::Global as JSGlobal; use crate::js::GlobalType; use crate::js::Mutability; @@ -95,7 +95,7 @@ impl Global { let js_global = JSGlobal::new(&descriptor, &value).unwrap(); let vm_global = VMGlobal::new(js_global, global_ty); - Ok(Self::from_vm_export(store, vm_global)) + Ok(Self::from_vm_extern(store, vm_global)) } /// Returns the [`GlobalType`] of the `Global`. @@ -112,7 +112,7 @@ impl Global { /// assert_eq!(c.ty(), &GlobalType::new(Type::I32, Mutability::Const)); /// assert_eq!(v.ty(), &GlobalType::new(Type::I64, Mutability::Var)); /// ``` - pub fn ty(&self, store: &impl AsStoreRef) -> GlobalType { + pub fn ty(&self, _store: &impl AsStoreRef) -> GlobalType { self.handle.ty } @@ -205,18 +205,14 @@ impl Global { Ok(()) } - pub(crate) fn from_vm_export(store: &mut impl AsStoreMut, vm_global: VMGlobal) -> Self { + pub(crate) fn from_vm_extern(store: &mut impl AsStoreMut, vm_global: VMGlobal) -> Self { use crate::js::store::StoreObject; VMGlobal::list_mut(store.objects_mut()).push(vm_global.clone()); Self { handle: vm_global } } - pub(crate) fn from_vm_extern(store: &mut impl AsStoreMut, internal: VMGlobal) -> Self { - Self { handle: internal } - } - /// Checks whether this `Global` can be used with the given store. - pub fn is_from_store(&self, store: &impl AsStoreRef) -> bool { + pub fn is_from_store(&self, _store: &impl AsStoreRef) -> bool { true } } diff --git a/lib/api/src/js/externals/memory.rs b/lib/api/src/js/externals/memory.rs index e136cb75c8b..39d5b4732d1 100644 --- a/lib/api/src/js/externals/memory.rs +++ b/lib/api/src/js/externals/memory.rs @@ -1,7 +1,7 @@ -use crate::js::export::VMMemory; use crate::js::exports::{ExportError, Exportable}; -use crate::js::externals::{Extern, VMExtern}; +use crate::js::externals::Extern; use crate::js::store::{AsStoreMut, AsStoreRef, StoreObjects}; +use crate::js::vm::{VMExtern, VMMemory}; use crate::js::{MemoryAccessError, MemoryType}; use std::marker::PhantomData; use std::mem::MaybeUninit; @@ -87,7 +87,7 @@ impl Memory { /// ``` pub fn new(store: &mut impl AsStoreMut, ty: MemoryType) -> Result { let vm_memory = VMMemory::new(Self::new_internal(ty.clone())?, ty); - Ok(Self::from_vm_export(store, vm_memory)) + Ok(Self::from_vm_extern(store, vm_memory)) } pub(crate) fn new_internal(ty: MemoryType) -> Result { @@ -141,7 +141,7 @@ impl Memory { /// /// assert_eq!(m.ty(), mt); /// ``` - pub fn ty(&self, store: &impl AsStoreRef) -> MemoryType { + pub fn ty(&self, _store: &impl AsStoreRef) -> MemoryType { self.handle.ty } @@ -234,26 +234,22 @@ impl Memory { Ok(new_memory) } - pub(crate) fn from_vm_export(store: &mut impl AsStoreMut, vm_memory: VMMemory) -> Self { - Self { handle: vm_memory } - } - - pub(crate) fn from_vm_extern(store: &mut impl AsStoreMut, internal: VMMemory) -> Self { + pub(crate) fn from_vm_extern(_store: &mut impl AsStoreMut, internal: VMMemory) -> Self { Self { handle: internal } } /// Attempts to clone this memory (if its clonable) - pub fn try_clone(&self, store: &impl AsStoreRef) -> Option { + pub fn try_clone(&self, _store: &impl AsStoreRef) -> Option { self.handle.try_clone() } /// Checks whether this `Global` can be used with the given context. - pub fn is_from_store(&self, store: &impl AsStoreRef) -> bool { + pub fn is_from_store(&self, _store: &impl AsStoreRef) -> bool { true } /// Copies this memory to a new memory - pub fn duplicate(&mut self, store: &impl AsStoreRef) -> Result { + pub fn duplicate(&mut self, _store: &impl AsStoreRef) -> Result { self.handle.duplicate() } } diff --git a/lib/api/src/js/externals/memory_view.rs b/lib/api/src/js/externals/memory_view.rs index dff829affcd..347547e8664 100644 --- a/lib/api/src/js/externals/memory_view.rs +++ b/lib/api/src/js/externals/memory_view.rs @@ -26,7 +26,7 @@ pub struct MemoryView<'a> { } impl<'a> MemoryView<'a> { - pub(crate) fn new(memory: &Memory, store: &impl AsStoreRef) -> Self { + pub(crate) fn new(memory: &Memory, _store: &impl AsStoreRef) -> Self { Self::new_raw(&memory.handle.memory) } diff --git a/lib/api/src/js/externals/mod.rs b/lib/api/src/js/externals/mod.rs index 63a77f2b643..6dd72eb6ff7 100644 --- a/lib/api/src/js/externals/mod.rs +++ b/lib/api/src/js/externals/mod.rs @@ -10,102 +10,13 @@ pub use self::memory::{Memory, MemoryError}; pub use self::memory_view::MemoryView; pub use self::table::Table; -use crate::js::error::WasmError; -use crate::js::export::{Export, VMFunction, VMGlobal, VMMemory, VMTable}; use crate::js::exports::{ExportError, Exportable}; -use crate::js::store::StoreObject; use crate::js::store::{AsStoreMut, AsStoreRef}; use crate::js::types::AsJs; -use crate::js::wasm_bindgen_polyfill::Global as JsGlobal; -use js_sys::Function as JsFunction; -use js_sys::WebAssembly::{Memory as JsMemory, Table as JsTable}; +use crate::js::vm::VMExtern; use std::fmt; -use wasm_bindgen::{JsCast, JsValue}; use wasmer_types::ExternType; -/// The value of an export passed from one instance to another. -pub enum VMExtern { - /// A function export value. - Function(VMFunction), - - /// A table export value. - Table(VMTable), - - /// A memory export value. - Memory(VMMemory), - - /// A global export value. - Global(VMGlobal), -} - -impl VMExtern { - /// Return the export as a `JSValue`. - pub fn as_jsvalue<'context>(&self, store: &'context impl AsStoreRef) -> JsValue { - match self { - Self::Memory(js_wasm_memory) => js_wasm_memory.memory.clone().into(), - Self::Function(js_func) => js_func.function.clone().into(), - Self::Table(js_wasm_table) => js_wasm_table.table.clone().into(), - Self::Global(js_wasm_global) => js_wasm_global.global.clone().into(), - } - } - - /// Convert a `JsValue` into an `Export` within a given `Context`. - pub fn from_js_value( - val: JsValue, - store: &mut impl AsStoreMut, - extern_type: ExternType, - ) -> Result { - match extern_type { - ExternType::Memory(memory_type) => { - if val.is_instance_of::() { - Ok(Self::Memory(VMMemory::new( - val.unchecked_into::(), - memory_type, - ))) - } else { - Err(WasmError::TypeMismatch( - val.js_typeof() - .as_string() - .map(Into::into) - .unwrap_or("unknown".into()), - "Memory".into(), - )) - } - } - ExternType::Global(global_type) => { - if val.is_instance_of::() { - Ok(Self::Global(VMGlobal::new( - val.unchecked_into::(), - global_type, - ))) - } else { - panic!("Extern type doesn't match js value type"); - } - } - ExternType::Function(function_type) => { - if val.is_instance_of::() { - Ok(Self::Function(VMFunction::new( - val.unchecked_into::(), - function_type, - ))) - } else { - panic!("Extern type doesn't match js value type"); - } - } - ExternType::Table(table_type) => { - if val.is_instance_of::() { - Ok(Self::Table(VMTable::new( - val.unchecked_into::(), - table_type, - ))) - } else { - panic!("Extern type doesn't match js value type"); - } - } - } - } -} - /// An `Extern` is the runtime representation of an entity that /// can be imported or exported. /// @@ -162,24 +73,15 @@ impl Extern { Self::Table(val) => val.is_from_store(store), } } - - fn to_export(&self) -> Export { - match self { - Self::Function(val) => Export::Function(val.handle.clone()), - Self::Memory(val) => Export::Memory(val.handle.clone()), - Self::Global(val) => Export::Global(val.handle.clone()), - Self::Table(val) => Export::Table(val.handle.clone()), - } - } } impl AsJs for Extern { fn as_jsvalue(&self, store: &impl AsStoreRef) -> wasm_bindgen::JsValue { match self { - Self::Function(_) => self.to_export().as_jsvalue(store), - Self::Global(_) => self.to_export().as_jsvalue(store), - Self::Table(_) => self.to_export().as_jsvalue(store), - Self::Memory(_) => self.to_export().as_jsvalue(store), + Self::Function(_) => self.to_vm_extern().as_jsvalue(store), + Self::Global(_) => self.to_vm_extern().as_jsvalue(store), + Self::Table(_) => self.to_vm_extern().as_jsvalue(store), + Self::Memory(_) => self.to_vm_extern().as_jsvalue(store), } .clone() } diff --git a/lib/api/src/js/externals/table.rs b/lib/api/src/js/externals/table.rs index ef09fff9be4..6e9860042f4 100644 --- a/lib/api/src/js/externals/table.rs +++ b/lib/api/src/js/externals/table.rs @@ -1,8 +1,8 @@ -use crate::js::export::{VMFunction, VMTable}; use crate::js::exports::{ExportError, Exportable}; -use crate::js::externals::{Extern, VMExtern}; +use crate::js::externals::Extern; use crate::js::store::{AsStoreMut, AsStoreRef}; use crate::js::value::Value; +use crate::js::vm::{VMExtern, VMFunction, VMTable}; use crate::js::RuntimeError; use crate::js::{FunctionType, TableType}; use js_sys::Function; @@ -74,7 +74,7 @@ impl Table { } /// Returns the [`TableType`] of the `Table`. - pub fn ty(&self, store: &impl AsStoreRef) -> TableType { + pub fn ty(&self, _store: &impl AsStoreRef) -> TableType { self.handle.ty } @@ -83,7 +83,7 @@ impl Table { if let Some(func) = self.handle.table.get(index).ok() { let ty = FunctionType::new(vec![], vec![]); let vm_function = VMFunction::new(func, ty); - let function = crate::js::externals::Function::from_vm_export(store, vm_function); + let function = crate::js::externals::Function::from_vm_extern(store, vm_function); Some(Value::FuncRef(Some(function))) } else { None @@ -102,7 +102,7 @@ impl Table { } /// Retrieves the size of the `Table` (in elements) - pub fn size(&self, store: &impl AsStoreRef) -> u32 { + pub fn size(&self, _store: &impl AsStoreRef) -> u32 { self.handle.table.length() } @@ -142,12 +142,12 @@ impl Table { unimplemented!("Table.copy is not natively supported in Javascript"); } - pub(crate) fn from_vm_extern(store: &mut impl AsStoreMut, internal: VMTable) -> Self { + pub(crate) fn from_vm_extern(_store: &mut impl AsStoreMut, internal: VMTable) -> Self { Self { handle: internal } } /// Checks whether this `Table` can be used with the given context. - pub fn is_from_store(&self, store: &impl AsStoreRef) -> bool { + pub fn is_from_store(&self, _store: &impl AsStoreRef) -> bool { true } @@ -161,7 +161,7 @@ impl Table { #[doc(hidden)] pub unsafe fn get_vm_table<'context>( &'context self, - store: &'context impl AsStoreRef, + _store: &'context impl AsStoreRef, ) -> &'context VMTable { &self.handle } diff --git a/lib/api/src/js/imports.rs b/lib/api/src/js/imports.rs index de877fe0e57..ae76b7e0ace 100644 --- a/lib/api/src/js/imports.rs +++ b/lib/api/src/js/imports.rs @@ -6,6 +6,7 @@ use crate::js::exports::Exports; use crate::js::module::Module; use crate::js::store::{AsStoreMut, AsStoreRef}; use crate::js::types::AsJs; +use crate::js::vm::VMExtern; use crate::js::ExternType; use crate::Extern; use std::collections::HashMap; @@ -206,7 +207,6 @@ impl Imports { module: &Module, object: js_sys::Object, ) -> Result { - use crate::js::externals::VMExtern; let module_imports: HashMap<(String, String), ExternType> = module .imports() .map(|import| { @@ -457,162 +457,4 @@ mod test { assert!(happy.is_some()); assert!(small.is_some()); } - // fn namespace() { - // let mut store = Store::default(); - // let g1 = Global::new(&store, Val::I32(0)); - // let namespace = namespace! { - // "happy" => g1 - // }; - // let imports1 = imports! { - // "dog" => namespace - // }; - - // let happy_dog_entry = imports1.get_export("dog", "happy").unwrap(); - - // assert!( - // if let Export::Global(happy_dog_global) = happy_dog_entry.to_export() { - // happy_dog_global.ty.ty == Type::I32 - // } else { - // false - // } - // ); - // } - - // fn imports_macro_allows_trailing_comma_and_none() { - // use crate::js::Function; - - // let mut store = Default::default(); - - // fn func(arg: i32) -> i32 { - // arg + 1 - // } - - // let _ = imports! { - // "env" => { - // "func" => Function::new_typed(&store, func), - // }, - // }; - // let _ = imports! { - // "env" => { - // "func" => Function::new_typed(&store, func), - // } - // }; - // let _ = imports! { - // "env" => { - // "func" => Function::new_typed(&store, func), - // }, - // "abc" => { - // "def" => Function::new_typed(&store, func), - // } - // }; - // let _ = imports! { - // "env" => { - // "func" => Function::new_typed(&store, func) - // }, - // }; - // let _ = imports! { - // "env" => { - // "func" => Function::new_typed(&store, func) - // } - // }; - // let _ = imports! { - // "env" => { - // "func1" => Function::new_typed(&store, func), - // "func2" => Function::new_typed(&store, func) - // } - // }; - // let _ = imports! { - // "env" => { - // "func1" => Function::new_typed(&store, func), - // "func2" => Function::new_typed(&store, func), - // } - // }; - // } - - // fn chaining_works() { - // let mut store = Store::default(); - // let g = Global::new(&store, Val::I32(0)); - - // let mut imports1 = imports! { - // "dog" => { - // "happy" => g.clone() - // } - // }; - - // let imports2 = imports! { - // "dog" => { - // "small" => g.clone() - // }, - // "cat" => { - // "small" => g.clone() - // } - // }; - - // imports1.extend(&imports2); - - // let small_cat_export = imports1.get_export("cat", "small"); - // assert!(small_cat_export.is_some()); - - // let happy = imports1.get_export("dog", "happy"); - // let small = imports1.get_export("dog", "small"); - // assert!(happy.is_some()); - // assert!(small.is_some()); - // } - - // fn extending_conflict_overwrites() { - // let mut store = Store::default(); - // let g1 = Global::new(&store, Val::I32(0)); - // let g2 = Global::new(&store, Val::F32(0.)); - - // let mut imports1 = imports! { - // "dog" => { - // "happy" => g1, - // }, - // }; - - // let imports2 = imports! { - // "dog" => { - // "happy" => g2, - // }, - // }; - - // imports1.extend(&imports2); - // let happy_dog_entry = imports1.get_export("dog", "happy").unwrap(); - - // assert!( - // if let Export::Global(happy_dog_global) = happy_dog_entry.to_export() { - // happy_dog_global.ty.ty == Type::F32 - // } else { - // false - // } - // ); - - // // now test it in reverse - // let mut store = Store::default(); - // let g1 = Global::new(&store, Val::I32(0)); - // let g2 = Global::new(&store, Val::F32(0.)); - - // let imports1 = imports! { - // "dog" => { - // "happy" => g1, - // }, - // }; - - // let mut imports2 = imports! { - // "dog" => { - // "happy" => g2, - // }, - // }; - - // imports2.extend(&imports1); - // let happy_dog_entry = imports2.get_export("dog", "happy").unwrap(); - - // assert!( - // if let Export::Global(happy_dog_global) = happy_dog_entry.to_export() { - // happy_dog_global.ty.ty == Type::I32 - // } else { - // false - // } - // ); - // } } diff --git a/lib/api/src/js/instance.rs b/lib/api/src/js/instance.rs index eea05cdcb58..584867d40a8 100644 --- a/lib/api/src/js/instance.rs +++ b/lib/api/src/js/instance.rs @@ -4,6 +4,7 @@ use crate::js::externals::Extern; use crate::js::imports::Imports; use crate::js::module::Module; use crate::js::store::{AsStoreMut, AsStoreRef}; +use crate::js::vm::VMExtern; use js_sys::WebAssembly; use std::fmt; @@ -68,7 +69,6 @@ impl Instance { let mut self_instance = Self::from_module_and_instance(store, module, instance)?; self_instance.ensure_memory_export(store, externs); - //self_instance.init_envs(&imports.iter().map(Extern::to_export).collect::>())?; Ok(self_instance) } @@ -108,8 +108,6 @@ impl Instance { module: &Module, instance: WebAssembly::Instance, ) -> Result { - use crate::js::externals::VMExtern; - let instance_exports = instance.exports(); let exports = module @@ -140,6 +138,7 @@ impl Instance { /// This will check the memory is correctly setup /// If the memory is imported then also export it for backwards compatibility reasons /// (many will assume the memory is always exported) - later we can remove this + /// TODO: This is trialing from WASIX, we should remove this or move it to the wasmer-wasi crate pub fn ensure_memory_export(&mut self, store: &mut impl AsStoreMut, externs: Vec) { if self.exports.get_memory("memory").is_err() { if let Some(memory) = externs @@ -161,7 +160,7 @@ impl Instance { #[doc(hidden)] pub fn raw<'context>( &'context self, - store: &'context impl AsStoreRef, + _store: &'context impl AsStoreRef, ) -> &'context WebAssembly::Instance { &self.handle } diff --git a/lib/api/src/js/mod.rs b/lib/api/src/js/mod.rs index c20f15f89e8..9d62313be65 100644 --- a/lib/api/src/js/mod.rs +++ b/lib/api/src/js/mod.rs @@ -24,7 +24,6 @@ mod lib { } pub(crate) mod error; -mod export; mod exports; mod externals; mod function_env; @@ -41,10 +40,10 @@ mod store; mod trap; mod types; mod value; +mod vm; mod wasm_bindgen_polyfill; pub use crate::js::error::{DeserializeError, InstantiationError, SerializeError}; -pub use crate::js::export::Export; pub use crate::js::exports::{ExportError, Exportable, Exports, ExportsIterator}; pub use crate::js::externals::{ Extern, FromToNativeWasmType, Function, Global, HostFunction, Memory, MemoryError, MemoryView, @@ -71,11 +70,6 @@ pub use crate::js::types::{ pub use crate::js::value::Value; pub use crate::js::value::Value as Val; -pub mod vm { - //! The `vm` module re-exports wasmer-vm types. - pub use crate::js::export::VMMemory; -} - pub use wasmer_types::is_wasm; // TODO: OnCalledAction is needed for asyncify. It will be refactored with https://github.com/wasmerio/wasmer/issues/3451 pub use wasmer_types::{ diff --git a/lib/api/src/js/module.rs b/lib/api/src/js/module.rs index c957dd3e0cb..77bd82c519b 100644 --- a/lib/api/src/js/module.rs +++ b/lib/api/src/js/module.rs @@ -645,7 +645,7 @@ impl Module { pub fn custom_sections<'a>(&'a self, name: &'a str) -> impl Iterator> + 'a { WebAssembly::Module::custom_sections(&self.module, name) .iter() - .map(move |(buf_val)| { + .map(move |buf_val| { let typebuf: js_sys::Uint8Array = js_sys::Uint8Array::new(&buf_val); typebuf.to_vec().into_boxed_slice() }) diff --git a/lib/api/src/js/native.rs b/lib/api/src/js/native.rs index ae5a6cd9eda..436eff84d2e 100644 --- a/lib/api/src/js/native.rs +++ b/lib/api/src/js/native.rs @@ -13,9 +13,9 @@ use crate::js::externals::Function; use crate::js::store::{AsStoreMut, AsStoreRef}; use crate::js::{FromToNativeWasmType, RuntimeError, WasmTypeList}; // use std::panic::{catch_unwind, AssertUnwindSafe}; -use crate::js::export::VMFunction; use crate::js::types::param_from_js; use crate::js::types::AsJs; +use crate::js::vm::VMFunction; use js_sys::Array; use std::iter::FromIterator; use wasm_bindgen::JsValue; @@ -38,7 +38,7 @@ where Rets: WasmTypeList, { #[allow(dead_code)] - pub(crate) fn new(store: &mut impl AsStoreMut, vm_function: VMFunction) -> Self { + pub(crate) fn new(_store: &mut impl AsStoreMut, vm_function: VMFunction) -> Self { Self { handle: vm_function, _phantom: PhantomData, diff --git a/lib/api/src/js/store.rs b/lib/api/src/js/store.rs index c730aaeec05..7fa22cfa855 100644 --- a/lib/api/src/js/store.rs +++ b/lib/api/src/js/store.rs @@ -205,16 +205,11 @@ pub use objects::{StoreHandle, StoreId, StoreObjects}; mod objects { use wasm_bindgen::JsValue; - use crate::js::{ - export::{VMFunction, VMGlobal, VMMemory, VMTable}, - function_env::VMFunctionEnvironment, - }; + use crate::js::{function_env::VMFunctionEnvironment, vm::VMGlobal}; use std::{ - cell::UnsafeCell, fmt, marker::PhantomData, num::{NonZeroU64, NonZeroUsize}, - ptr::NonNull, sync::atomic::{AtomicU64, Ordering}, }; diff --git a/lib/api/src/js/types.rs b/lib/api/src/js/types.rs index cdd03f7b447..4dd2133f523 100644 --- a/lib/api/src/js/types.rs +++ b/lib/api/src/js/types.rs @@ -37,7 +37,7 @@ pub fn param_from_js(ty: &ValType, js_val: &JsValue) -> Value { } impl AsJs for Value { - fn as_jsvalue(&self, store: &impl AsStoreRef) -> JsValue { + fn as_jsvalue(&self, _store: &impl AsStoreRef) -> JsValue { match self { Self::I32(i) => JsValue::from_f64(*i as f64), Self::I64(i) => JsValue::from_f64(*i as f64), diff --git a/lib/api/src/js/value.rs b/lib/api/src/js/value.rs index a59a1e0796b..4a432c9ce2e 100644 --- a/lib/api/src/js/value.rs +++ b/lib/api/src/js/value.rs @@ -87,7 +87,7 @@ impl Value { } /// Converts the `Value` into a `f64`. - pub fn as_raw(&self, store: &impl AsStoreRef) -> f64 { + pub fn as_raw(&self, _store: &impl AsStoreRef) -> f64 { match *self { Self::I32(v) => v as f64, Self::I64(v) => v as f64, diff --git a/lib/api/src/js/export.rs b/lib/api/src/js/vm.rs similarity index 85% rename from lib/api/src/js/export.rs rename to lib/api/src/js/vm.rs index c31466cb55c..67e82cd3178 100644 --- a/lib/api/src/js/export.rs +++ b/lib/api/src/js/vm.rs @@ -1,9 +1,18 @@ +/// This module is mainly used to create the `VM` types that will hold both +/// the JS values of the `Memory`, `Table`, `Global` and `Function` and also +/// it's types. +/// This module should not be needed any longer (with the exception of the memory) +/// once the type reflection is added to the WebAssembly JS API. +/// https://github.com/WebAssembly/js-types/ use crate::js::error::WasmError; use crate::js::store::{AsStoreMut, AsStoreRef}; use crate::js::wasm_bindgen_polyfill::Global; +use crate::js::wasm_bindgen_polyfill::Global as JsGlobal; use crate::MemoryView; use js_sys::Function; +use js_sys::Function as JsFunction; use js_sys::WebAssembly::{Memory, Table}; +use js_sys::WebAssembly::{Memory as JsMemory, Table as JsTable}; use serde::{Deserialize, Serialize}; use std::fmt; #[cfg(feature = "tracing")] @@ -162,8 +171,7 @@ impl fmt::Debug for VMFunction { } /// The value of an export passed from one instance to another. -#[derive(Debug, Clone)] -pub enum Export { +pub enum VMExtern { /// A function export value. Function(VMFunction), @@ -177,9 +185,9 @@ pub enum Export { Global(VMGlobal), } -impl Export { +impl VMExtern { /// Return the export as a `JSValue`. - pub fn as_jsvalue(&self, _store: &impl AsStoreRef) -> JsValue { + pub fn as_jsvalue<'context>(&self, _store: &'context impl AsStoreRef) -> JsValue { match self { Self::Memory(js_wasm_memory) => js_wasm_memory.memory.clone().into(), Self::Function(js_func) => js_func.function.clone().into(), @@ -191,14 +199,14 @@ impl Export { /// Convert a `JsValue` into an `Export` within a given `Context`. pub fn from_js_value( val: JsValue, - store: &mut impl AsStoreMut, + _store: &mut impl AsStoreMut, extern_type: ExternType, ) -> Result { match extern_type { ExternType::Memory(memory_type) => { - if val.is_instance_of::() { + if val.is_instance_of::() { Ok(Self::Memory(VMMemory::new( - val.unchecked_into::(), + val.unchecked_into::(), memory_type, ))) } else { @@ -212,9 +220,9 @@ impl Export { } } ExternType::Global(global_type) => { - if val.is_instance_of::() { + if val.is_instance_of::() { Ok(Self::Global(VMGlobal::new( - val.unchecked_into::(), + val.unchecked_into::(), global_type, ))) } else { @@ -222,9 +230,9 @@ impl Export { } } ExternType::Function(function_type) => { - if val.is_instance_of::() { + if val.is_instance_of::() { Ok(Self::Function(VMFunction::new( - val.unchecked_into::(), + val.unchecked_into::(), function_type, ))) } else { @@ -232,9 +240,9 @@ impl Export { } } ExternType::Table(table_type) => { - if val.is_instance_of::
() { + if val.is_instance_of::() { Ok(Self::Table(VMTable::new( - val.unchecked_into::
(), + val.unchecked_into::(), table_type, ))) } else {