Use JS VM store instead of artificially replicate it

This commit is contained in:
Syrus Akbary
2023-01-25 19:41:39 +01:00
parent 1f1ec93f74
commit d59f4c2ffd
14 changed files with 129 additions and 270 deletions

View File

@@ -1,5 +1,5 @@
use crate::js::error::WasmError; 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::js::wasm_bindgen_polyfill::Global;
use crate::MemoryView; use crate::MemoryView;
use js_sys::Function; use js_sys::Function;
@@ -165,38 +165,26 @@ impl fmt::Debug for VMFunction {
#[derive(Debug, Clone)] #[derive(Debug, Clone)]
pub enum Export { pub enum Export {
/// A function export value. /// A function export value.
Function(InternalStoreHandle<VMFunction>), Function(VMFunction),
/// A table export value. /// A table export value.
Table(InternalStoreHandle<VMTable>), Table(VMTable),
/// A memory export value. /// A memory export value.
Memory(InternalStoreHandle<VMMemory>), Memory(VMMemory),
/// A global export value. /// A global export value.
Global(InternalStoreHandle<VMGlobal>), Global(VMGlobal),
} }
impl Export { impl Export {
/// Return the export as a `JSValue`. /// 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 { match self {
Self::Memory(js_wasm_memory) => js_wasm_memory Self::Memory(js_wasm_memory) => js_wasm_memory.memory.clone().into(),
.get(store.as_store_ref().objects()) Self::Function(js_func) => js_func.function.clone().into(),
.memory Self::Table(js_wasm_table) => js_wasm_table.table.clone().into(),
.as_ref(), Self::Global(js_wasm_global) => js_wasm_global.global.clone().into(),
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(),
} }
} }
@@ -209,9 +197,9 @@ impl Export {
match extern_type { match extern_type {
ExternType::Memory(memory_type) => { ExternType::Memory(memory_type) => {
if val.is_instance_of::<Memory>() { if val.is_instance_of::<Memory>() {
Ok(Self::Memory(InternalStoreHandle::new( Ok(Self::Memory(VMMemory::new(
&mut store.objects_mut(), val.unchecked_into::<Memory>(),
VMMemory::new(val.unchecked_into::<Memory>(), memory_type), memory_type,
))) )))
} else { } else {
Err(WasmError::TypeMismatch( Err(WasmError::TypeMismatch(
@@ -225,9 +213,9 @@ impl Export {
} }
ExternType::Global(global_type) => { ExternType::Global(global_type) => {
if val.is_instance_of::<Global>() { if val.is_instance_of::<Global>() {
Ok(Self::Global(InternalStoreHandle::new( Ok(Self::Global(VMGlobal::new(
&mut store.objects_mut(), val.unchecked_into::<Global>(),
VMGlobal::new(val.unchecked_into::<Global>(), global_type), global_type,
))) )))
} else { } else {
panic!("Extern type doesn't match js value type"); panic!("Extern type doesn't match js value type");
@@ -235,9 +223,9 @@ impl Export {
} }
ExternType::Function(function_type) => { ExternType::Function(function_type) => {
if val.is_instance_of::<Function>() { if val.is_instance_of::<Function>() {
Ok(Self::Function(InternalStoreHandle::new( Ok(Self::Function(VMFunction::new(
&mut store.objects_mut(), val.unchecked_into::<Function>(),
VMFunction::new(val.unchecked_into::<Function>(), function_type), function_type,
))) )))
} else { } else {
panic!("Extern type doesn't match js value type"); panic!("Extern type doesn't match js value type");
@@ -245,9 +233,9 @@ impl Export {
} }
ExternType::Table(table_type) => { ExternType::Table(table_type) => {
if val.is_instance_of::<Table>() { if val.is_instance_of::<Table>() {
Ok(Self::Table(InternalStoreHandle::new( Ok(Self::Table(VMTable::new(
&mut store.objects_mut(), val.unchecked_into::<Table>(),
VMTable::new(val.unchecked_into::<Table>(), table_type), table_type,
))) )))
} else { } else {
panic!("Extern type doesn't match js value type"); panic!("Extern type doesn't match js value type");

View File

@@ -2,7 +2,7 @@ pub use self::inner::{FromToNativeWasmType, HostFunction, WasmTypeList, WithEnv,
use crate::js::exports::{ExportError, Exportable}; use crate::js::exports::{ExportError, Exportable};
use crate::js::externals::{Extern, VMExtern}; use crate::js::externals::{Extern, VMExtern};
use crate::js::function_env::FunctionEnvMut; 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::types::{param_from_js, AsJs}; /* ValFuncRef */
use crate::js::RuntimeError; use crate::js::RuntimeError;
use crate::js::TypedFunction; 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) /// [Closures as host functions tracking issue](https://github.com/wasmerio/wasmer/issues/1840)
#[derive(Clone, PartialEq)] #[derive(Clone, PartialEq)]
pub struct Function { pub struct Function {
pub(crate) handle: StoreHandle<VMFunction>, pub(crate) handle: VMFunction,
} }
impl From<StoreHandle<VMFunction>> for Function { impl From<VMFunction> for Function {
fn from(handle: StoreHandle<VMFunction>) -> Self { fn from(handle: VMFunction) -> Self {
Self { handle } Self { handle }
} }
} }
@@ -86,7 +86,7 @@ impl Function {
/// To `VMExtern`. /// To `VMExtern`.
pub fn to_vm_extern(&self) -> 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. /// Creates a new host `Function` (dynamic) with the provided signature.
@@ -232,7 +232,7 @@ impl Function {
let ty = function.ty(); let ty = function.ty();
let vm_function = VMFunction::new(binded_func, ty); let vm_function = VMFunction::new(binded_func, ty);
Self { Self {
handle: StoreHandle::new(store.objects_mut(), vm_function), handle: vm_function,
} }
} }
@@ -300,7 +300,7 @@ impl Function {
let ty = function.ty(); let ty = function.ty();
let vm_function = VMFunction::new(binded_func, ty); let vm_function = VMFunction::new(binded_func, ty);
Self { 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]); /// 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.get(store.as_store_ref().objects()).ty.clone() self.handle.ty.clone()
} }
/// Returns the number of parameters that this function takes. /// 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 // TODO: This loop is needed for asyncify. It will be refactored with https://github.com/wasmerio/wasmer/issues/3451
loop { loop {
r = js_sys::Reflect::apply( r = js_sys::Reflect::apply(
&self.handle.get(store.as_store_ref().objects()).function, &self.handle.function,
&wasm_bindgen::JsValue::NULL, &wasm_bindgen::JsValue::NULL,
&arr, &arr,
); );
@@ -446,7 +446,7 @@ impl Function {
r? 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() { match result_types.len() {
0 => Ok(Box::new([])), 0 => Ok(Box::new([])),
1 => { 1 => {
@@ -467,19 +467,12 @@ impl Function {
pub(crate) fn from_vm_export(store: &mut impl AsStoreMut, vm_function: VMFunction) -> Self { pub(crate) fn from_vm_export(store: &mut impl AsStoreMut, vm_function: VMFunction) -> Self {
Self { Self {
handle: StoreHandle::new(store.objects_mut(), vm_function), handle: vm_function,
} }
} }
pub(crate) fn from_vm_extern( pub(crate) fn from_vm_extern(store: &mut impl AsStoreMut, internal: VMFunction) -> Self {
store: &mut impl AsStoreMut, Self { handle: internal }
internal: InternalStoreHandle<VMFunction>,
) -> Self {
Self {
handle: unsafe {
StoreHandle::from_internal(store.as_store_ref().objects().id(), internal)
},
}
} }
#[deprecated(since = "3.0.0", note = "native() has been renamed to typed().")] #[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. /// 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 {
self.handle.store_id() == store.as_store_ref().objects().id() true
} }
} }

View File

@@ -1,7 +1,7 @@
use crate::js::export::VMGlobal; use crate::js::export::VMGlobal;
use crate::js::exports::{ExportError, Exportable}; use crate::js::exports::{ExportError, Exportable};
use crate::js::externals::{Extern, VMExtern}; 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::value::Value;
use crate::js::wasm_bindgen_polyfill::Global as JSGlobal; use crate::js::wasm_bindgen_polyfill::Global as JSGlobal;
use crate::js::GlobalType; use crate::js::GlobalType;
@@ -17,7 +17,7 @@ use wasm_bindgen::JsValue;
/// Spec: <https://webassembly.github.io/spec/core/exec/runtime.html#global-instances> /// Spec: <https://webassembly.github.io/spec/core/exec/runtime.html#global-instances>
#[derive(Debug, Clone, PartialEq)] #[derive(Debug, Clone, PartialEq)]
pub struct Global { pub struct Global {
pub(crate) handle: StoreHandle<VMGlobal>, pub(crate) handle: VMGlobal,
} }
impl Global { impl Global {
@@ -57,7 +57,7 @@ impl Global {
/// To `VMExtern`. /// To `VMExtern`.
pub(crate) fn to_vm_extern(&self) -> 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`]. /// 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)); /// 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.get(store.as_store_ref().objects()).ty self.handle.ty
} }
/// Retrieves the current value [`Value`] that the Global has. /// Retrieves the current value [`Value`] that the Global has.
@@ -130,14 +130,8 @@ impl Global {
/// ``` /// ```
pub fn get(&self, store: &impl AsStoreRef) -> Value { pub fn get(&self, store: &impl AsStoreRef) -> Value {
unsafe { unsafe {
let raw = self let raw = self.handle.global.value().as_f64().unwrap();
.handle let ty = self.handle.ty;
.get(store.as_store_ref().objects())
.global
.value()
.as_f64()
.unwrap();
let ty = self.handle.get(store.as_store_ref().objects()).ty;
Value::from_raw(store, ty.ty, raw) Value::from_raw(store, ty.ty, raw)
} }
} }
@@ -207,33 +201,23 @@ impl Global {
)) ))
} }
}; };
self.handle self.handle.global.set_value(&new_value);
.get_mut(store.objects_mut())
.global
.set_value(&new_value);
Ok(()) Ok(())
} }
pub(crate) fn from_vm_export(store: &mut impl AsStoreMut, vm_global: VMGlobal) -> Self { pub(crate) fn from_vm_export(store: &mut impl AsStoreMut, vm_global: VMGlobal) -> Self {
Self { use crate::js::store::StoreObject;
handle: StoreHandle::new(store.objects_mut(), vm_global), VMGlobal::list_mut(store.objects_mut()).push(vm_global.clone());
} Self { handle: vm_global }
} }
pub(crate) fn from_vm_extern( pub(crate) fn from_vm_extern(store: &mut impl AsStoreMut, internal: VMGlobal) -> Self {
store: &mut impl AsStoreMut, Self { handle: internal }
internal: InternalStoreHandle<VMGlobal>,
) -> Self {
Self {
handle: unsafe {
StoreHandle::from_internal(store.as_store_ref().objects().id(), internal)
},
}
} }
/// Checks whether this `Global` can be used with the given store. /// 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 {
self.handle.store_id() == store.as_store_ref().objects().id() true
} }
} }

View File

@@ -1,7 +1,7 @@
use crate::js::export::VMMemory; use crate::js::export::VMMemory;
use crate::js::exports::{ExportError, Exportable}; use crate::js::exports::{ExportError, Exportable};
use crate::js::externals::{Extern, VMExtern}; 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 crate::js::{MemoryAccessError, MemoryType};
use std::marker::PhantomData; use std::marker::PhantomData;
use std::mem::MaybeUninit; use std::mem::MaybeUninit;
@@ -65,7 +65,7 @@ extern "C" {
/// Spec: <https://webassembly.github.io/spec/core/exec/runtime.html#memory-instances> /// Spec: <https://webassembly.github.io/spec/core/exec/runtime.html#memory-instances>
#[derive(Debug, Clone)] #[derive(Debug, Clone)]
pub struct Memory { pub struct Memory {
pub(crate) handle: StoreHandle<VMMemory>, pub(crate) handle: VMMemory,
} }
unsafe impl Send for Memory {} unsafe impl Send for Memory {}
@@ -115,19 +115,17 @@ impl Memory {
ty: MemoryType, ty: MemoryType,
) -> Result<Self, MemoryError> { ) -> Result<Self, MemoryError> {
let vm_memory = VMMemory::new(js_memory, ty); let vm_memory = VMMemory::new(js_memory, ty);
let handle = StoreHandle::new(store.objects_mut(), vm_memory); Ok(Self::from_vm_extern(store, vm_memory))
Ok(Self::from_vm_extern(store, handle.internal_handle()))
} }
/// Create a memory object from an existing memory and attaches it to the store /// 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 { 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, memory)
Self::from_vm_extern(new_store, handle.internal_handle())
} }
/// To `VMExtern`. /// To `VMExtern`.
pub(crate) fn to_vm_extern(&self) -> 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`. /// Returns the [`MemoryType`] of the `Memory`.
@@ -144,7 +142,7 @@ impl Memory {
/// assert_eq!(m.ty(), mt); /// assert_eq!(m.ty(), mt);
/// ``` /// ```
pub fn ty(&self, store: &impl AsStoreRef) -> MemoryType { 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 /// Creates a view into the memory that then allows for
@@ -192,7 +190,7 @@ impl Memory {
IntoPages: Into<Pages>, IntoPages: Into<Pages>,
{ {
let pages = delta.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 our_js_memory: &JSMemory = JsCast::unchecked_from_js_ref(js_memory);
let new_pages = our_js_memory.grow(pages.0).map_err(|err| { let new_pages = our_js_memory.grow(pages.0).map_err(|err| {
if err.is_instance_of::<js_sys::RangeError>() { if err.is_instance_of::<js_sys::RangeError>() {
@@ -237,37 +235,26 @@ impl Memory {
} }
pub(crate) fn from_vm_export(store: &mut impl AsStoreMut, vm_memory: VMMemory) -> Self { pub(crate) fn from_vm_export(store: &mut impl AsStoreMut, vm_memory: VMMemory) -> Self {
Self { Self { handle: vm_memory }
handle: StoreHandle::new(store.objects_mut(), vm_memory),
}
} }
pub(crate) fn from_vm_extern( pub(crate) fn from_vm_extern(store: &mut impl AsStoreMut, internal: VMMemory) -> Self {
store: &mut impl AsStoreMut, Self { handle: internal }
internal: InternalStoreHandle<VMMemory>,
) -> Self {
Self {
handle: unsafe {
StoreHandle::from_internal(store.as_store_ref().objects().id(), internal)
},
}
} }
/// Attempts to clone this memory (if its clonable) /// Attempts to clone this memory (if its clonable)
pub fn try_clone(&self, store: &impl AsStoreRef) -> Option<VMMemory> { pub fn try_clone(&self, store: &impl AsStoreRef) -> Option<VMMemory> {
let mem = self.handle.get(store.as_store_ref().objects()); self.handle.try_clone()
mem.try_clone()
} }
/// Checks whether this `Global` can be used with the given context. /// 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 {
self.handle.store_id() == store.as_store_ref().objects().id() true
} }
/// Copies this memory to a new memory /// Copies this memory to a new memory
pub fn duplicate(&mut self, store: &impl AsStoreRef) -> Result<VMMemory, MemoryError> { pub fn duplicate(&mut self, store: &impl AsStoreRef) -> Result<VMMemory, MemoryError> {
let mem = self.handle.get(store.as_store_ref().objects()); self.handle.duplicate()
mem.duplicate()
} }
} }

View File

@@ -27,8 +27,7 @@ pub struct MemoryView<'a> {
impl<'a> 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 {
let memory = memory.handle.get(store.as_store_ref().objects()); Self::new_raw(&memory.handle.memory)
Self::new_raw(&memory.memory)
} }
pub(crate) fn new_raw(memory: &js_sys::WebAssembly::Memory) -> Self { pub(crate) fn new_raw(memory: &js_sys::WebAssembly::Memory) -> Self {

View File

@@ -10,21 +10,12 @@ pub use self::memory::{Memory, MemoryError};
pub use self::memory_view::MemoryView; pub use self::memory_view::MemoryView;
pub use self::table::Table; pub use self::table::Table;
use crate::js::error::WasmError;
use crate::js::export::{Export, VMFunction, VMGlobal, VMMemory, VMTable}; use crate::js::export::{Export, VMFunction, VMGlobal, VMMemory, VMTable};
use crate::js::exports::{ExportError, Exportable}; use crate::js::exports::{ExportError, Exportable};
use crate::js::store::StoreObject; use crate::js::store::StoreObject;
use crate::js::types::AsJs;
/*
use crate::js::store::InternalStoreHandle;
use crate::js::store::{AsStoreMut, AsStoreRef}; use crate::js::store::{AsStoreMut, AsStoreRef};
use crate::js::ExternType; use crate::js::types::AsJs;
use std::fmt;
*/
use crate::js::error::WasmError;
use crate::js::store::{AsStoreMut, AsStoreRef, InternalStoreHandle};
use crate::js::wasm_bindgen_polyfill::Global as JsGlobal; use crate::js::wasm_bindgen_polyfill::Global as JsGlobal;
use js_sys::Function as JsFunction; use js_sys::Function as JsFunction;
use js_sys::WebAssembly::{Memory as JsMemory, Table as JsTable}; 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. /// The value of an export passed from one instance to another.
pub enum VMExtern { pub enum VMExtern {
/// A function export value. /// A function export value.
Function(InternalStoreHandle<VMFunction>), Function(VMFunction),
/// A table export value. /// A table export value.
Table(InternalStoreHandle<VMTable>), Table(VMTable),
/// A memory export value. /// A memory export value.
Memory(InternalStoreHandle<VMMemory>), Memory(VMMemory),
/// A global export value. /// A global export value.
Global(InternalStoreHandle<VMGlobal>), Global(VMGlobal),
} }
impl VMExtern { impl VMExtern {
/// Return the export as a `JSValue`. /// 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 { match self {
Self::Memory(js_wasm_memory) => js_wasm_memory Self::Memory(js_wasm_memory) => js_wasm_memory.memory.clone().into(),
.get(store.as_store_ref().objects()) Self::Function(js_func) => js_func.function.clone().into(),
.memory Self::Table(js_wasm_table) => js_wasm_table.table.clone().into(),
.as_ref(), Self::Global(js_wasm_global) => js_wasm_global.global.clone().into(),
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(),
} }
} }
@@ -79,9 +58,9 @@ impl VMExtern {
match extern_type { match extern_type {
ExternType::Memory(memory_type) => { ExternType::Memory(memory_type) => {
if val.is_instance_of::<JsMemory>() { if val.is_instance_of::<JsMemory>() {
Ok(Self::Memory(InternalStoreHandle::new( Ok(Self::Memory(VMMemory::new(
&mut store.objects_mut(), val.unchecked_into::<JsMemory>(),
VMMemory::new(val.unchecked_into::<JsMemory>(), memory_type), memory_type,
))) )))
} else { } else {
Err(WasmError::TypeMismatch( Err(WasmError::TypeMismatch(
@@ -95,9 +74,9 @@ impl VMExtern {
} }
ExternType::Global(global_type) => { ExternType::Global(global_type) => {
if val.is_instance_of::<JsGlobal>() { if val.is_instance_of::<JsGlobal>() {
Ok(Self::Global(InternalStoreHandle::new( Ok(Self::Global(VMGlobal::new(
&mut store.objects_mut(), val.unchecked_into::<JsGlobal>(),
VMGlobal::new(val.unchecked_into::<JsGlobal>(), global_type), global_type,
))) )))
} else { } else {
panic!("Extern type doesn't match js value type"); panic!("Extern type doesn't match js value type");
@@ -105,9 +84,9 @@ impl VMExtern {
} }
ExternType::Function(function_type) => { ExternType::Function(function_type) => {
if val.is_instance_of::<JsFunction>() { if val.is_instance_of::<JsFunction>() {
Ok(Self::Function(InternalStoreHandle::new( Ok(Self::Function(VMFunction::new(
&mut store.objects_mut(), val.unchecked_into::<JsFunction>(),
VMFunction::new(val.unchecked_into::<JsFunction>(), function_type), function_type,
))) )))
} else { } else {
panic!("Extern type doesn't match js value type"); panic!("Extern type doesn't match js value type");
@@ -115,9 +94,9 @@ impl VMExtern {
} }
ExternType::Table(table_type) => { ExternType::Table(table_type) => {
if val.is_instance_of::<JsTable>() { if val.is_instance_of::<JsTable>() {
Ok(Self::Table(InternalStoreHandle::new( Ok(Self::Table(VMTable::new(
&mut store.objects_mut(), val.unchecked_into::<JsTable>(),
VMTable::new(val.unchecked_into::<JsTable>(), table_type), table_type,
))) )))
} else { } else {
panic!("Extern type doesn't match js value type"); panic!("Extern type doesn't match js value type");
@@ -186,10 +165,10 @@ impl Extern {
fn to_export(&self) -> Export { fn to_export(&self) -> Export {
match self { match self {
Self::Function(val) => Export::Function(val.handle.internal_handle()), Self::Function(val) => Export::Function(val.handle.clone()),
Self::Memory(val) => Export::Memory(val.handle.internal_handle()), Self::Memory(val) => Export::Memory(val.handle.clone()),
Self::Global(val) => Export::Global(val.handle.internal_handle()), Self::Global(val) => Export::Global(val.handle.clone()),
Self::Table(val) => Export::Table(val.handle.internal_handle()), 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 { impl fmt::Debug for Extern {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!( write!(

View File

@@ -1,7 +1,7 @@
use crate::js::export::{VMFunction, VMTable}; use crate::js::export::{VMFunction, VMTable};
use crate::js::exports::{ExportError, Exportable}; use crate::js::exports::{ExportError, Exportable};
use crate::js::externals::{Extern, VMExtern}; 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::value::Value;
use crate::js::RuntimeError; use crate::js::RuntimeError;
use crate::js::{FunctionType, TableType}; use crate::js::{FunctionType, TableType};
@@ -18,7 +18,7 @@ use js_sys::Function;
/// Spec: <https://webassembly.github.io/spec/core/exec/runtime.html#table-instances> /// Spec: <https://webassembly.github.io/spec/core/exec/runtime.html#table-instances>
#[derive(Debug, Clone, PartialEq)] #[derive(Debug, Clone, PartialEq)]
pub struct Table { pub struct Table {
pub(crate) handle: StoreHandle<VMTable>, pub(crate) handle: VMTable,
} }
fn set_table_item(table: &VMTable, item_index: u32, item: &Function) -> Result<(), RuntimeError> { 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<Function, Run
return Err(RuntimeError::new("cannot pass Value across contexts")); return Err(RuntimeError::new("cannot pass Value across contexts"));
} }
match val { match val {
Value::FuncRef(Some(ref func)) => Ok(func Value::FuncRef(Some(ref func)) => Ok(func.handle.function.clone().into()),
.handle
.get(&store.as_store_ref().objects())
.function
.clone()
.into()),
// Only funcrefs is supported by the spec atm // Only funcrefs is supported by the spec atm
_ => unimplemented!(), _ => unimplemented!(),
} }
@@ -70,30 +65,22 @@ impl Table {
set_table_item(&table, i, &func)?; set_table_item(&table, i, &func)?;
} }
Ok(Self { Ok(Self { handle: table })
handle: StoreHandle::new(store.objects_mut(), table),
})
} }
/// To `VMExtern`. /// To `VMExtern`.
pub fn to_vm_extern(&self) -> 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`. /// Returns the [`TableType`] of the `Table`.
pub fn ty(&self, store: &impl AsStoreRef) -> TableType { 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`. /// Retrieves an element of the table at the provided `index`.
pub fn get(&self, store: &mut impl AsStoreMut, index: u32) -> Option<Value> { pub fn get(&self, store: &mut impl AsStoreMut, index: u32) -> Option<Value> {
if let Some(func) = self if let Some(func) = self.handle.table.get(index).ok() {
.handle
.get(store.as_store_ref().objects())
.table
.get(index)
.ok()
{
let ty = FunctionType::new(vec![], vec![]); let ty = FunctionType::new(vec![], vec![]);
let vm_function = VMFunction::new(func, ty); 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_export(store, vm_function);
@@ -111,15 +98,12 @@ impl Table {
val: Value, val: Value,
) -> Result<(), RuntimeError> { ) -> Result<(), RuntimeError> {
let item = get_function(store, val)?; 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) /// 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 self.handle.table.length()
.get(store.as_store_ref().objects())
.table
.length()
} }
/// Grows the size of the `Table` by `delta`, initializating /// Grows the size of the `Table` by `delta`, initializating
@@ -158,20 +142,13 @@ impl Table {
unimplemented!("Table.copy is not natively supported in Javascript"); unimplemented!("Table.copy is not natively supported in Javascript");
} }
pub(crate) fn from_vm_extern( pub(crate) fn from_vm_extern(store: &mut impl AsStoreMut, internal: VMTable) -> Self {
store: &mut impl AsStoreMut, Self { handle: internal }
internal: InternalStoreHandle<VMTable>,
) -> Self {
Self {
handle: unsafe {
StoreHandle::from_internal(store.as_store_ref().objects().id(), internal)
},
}
} }
/// Checks whether this `Table` can be used with the given context. /// 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 {
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 /// 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. /// make breaking changes to it at any time or remove this method.
#[doc(hidden)] #[doc(hidden)]
pub unsafe fn get_vm_table<'context>( pub unsafe fn get_vm_table<'context>(
&self, &'context self,
store: &'context impl AsStoreRef, store: &'context impl AsStoreRef,
) -> &'context VMTable { ) -> &'context VMTable {
self.handle.get(store.as_store_ref().objects()) &self.handle
} }
} }

View File

@@ -3,7 +3,7 @@ use crate::js::exports::Exports;
use crate::js::externals::Extern; use crate::js::externals::Extern;
use crate::js::imports::Imports; use crate::js::imports::Imports;
use crate::js::module::Module; use crate::js::module::Module;
use crate::js::store::{AsStoreMut, AsStoreRef, StoreHandle}; use crate::js::store::{AsStoreMut, AsStoreRef};
use js_sys::WebAssembly; use js_sys::WebAssembly;
use std::fmt; use std::fmt;
@@ -17,7 +17,7 @@ use std::fmt;
/// Spec: <https://webassembly.github.io/spec/core/exec/runtime.html#module-instances> /// Spec: <https://webassembly.github.io/spec/core/exec/runtime.html#module-instances>
#[derive(Clone)] #[derive(Clone)]
pub struct Instance { pub struct Instance {
_handle: StoreHandle<WebAssembly::Instance>, handle: WebAssembly::Instance,
module: Module, module: Module,
/// The exports for an instance. /// The exports for an instance.
pub exports: Exports, pub exports: Exports,
@@ -66,7 +66,6 @@ impl Instance {
.instantiate(&mut store, imports) .instantiate(&mut store, imports)
.map_err(|e| InstantiationError::Start(e))?; .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)?; let mut self_instance = Self::from_module_and_instance(store, module, instance)?;
self_instance.ensure_memory_export(store, externs); self_instance.ensure_memory_export(store, externs);
//self_instance.init_envs(&imports.iter().map(Extern::to_export).collect::<Vec<_>>())?; //self_instance.init_envs(&imports.iter().map(Extern::to_export).collect::<Vec<_>>())?;
@@ -131,9 +130,8 @@ impl Instance {
}) })
.collect::<Result<Exports, InstantiationError>>()?; .collect::<Result<Exports, InstantiationError>>()?;
let handle = StoreHandle::new(store.as_store_mut().objects_mut(), instance);
Ok(Self { Ok(Self {
_handle: handle, handle: instance,
module: module.clone(), module: module.clone(),
exports, exports,
}) })
@@ -162,10 +160,10 @@ impl Instance {
/// Returns the inner WebAssembly Instance /// Returns the inner WebAssembly Instance
#[doc(hidden)] #[doc(hidden)]
pub fn raw<'context>( pub fn raw<'context>(
&self, &'context self,
store: &'context impl AsStoreRef, store: &'context impl AsStoreRef,
) -> &'context WebAssembly::Instance { ) -> &'context WebAssembly::Instance {
&self._handle.get(store.as_store_ref().objects()) &self.handle
} }
} }

View File

@@ -61,7 +61,7 @@ pub use crate::js::ptr::{Memory32, Memory64, MemorySize, WasmPtr, WasmPtr64};
pub use crate::js::trap::RuntimeError; pub use crate::js::trap::RuntimeError;
pub use crate::js::store::{ 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::ValType as Type;
pub use crate::js::types::{ pub use crate::js::types::{

View File

@@ -246,7 +246,7 @@ impl Module {
&self, &self,
store: &mut impl AsStoreMut, store: &mut impl AsStoreMut,
imports: &Imports, imports: &Imports,
) -> Result<(crate::StoreHandle<WebAssembly::Instance>, Vec<Extern>), RuntimeError> { ) -> Result<(WebAssembly::Instance, Vec<Extern>), RuntimeError> {
// Ensure all imports come from the same store. // Ensure all imports come from the same store.
if imports if imports
.into_iter() .into_iter()
@@ -324,11 +324,8 @@ impl Module {
// the error for us, so we don't need to handle it // the error for us, so we don't need to handle it
} }
Ok(( Ok((
crate::StoreHandle::new(
store.as_store_mut().objects_mut(),
WebAssembly::Instance::new(&self.module, &imports_object) WebAssembly::Instance::new(&self.module, &imports_object)
.map_err(|e: JsValue| -> RuntimeError { e.into() })?, .map_err(|e: JsValue| -> RuntimeError { e.into() })?,
),
import_externs, import_externs,
)) ))
} }

View File

@@ -10,7 +10,7 @@
use std::marker::PhantomData; use std::marker::PhantomData;
use crate::js::externals::Function; 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 crate::js::{FromToNativeWasmType, RuntimeError, WasmTypeList};
// use std::panic::{catch_unwind, AssertUnwindSafe}; // use std::panic::{catch_unwind, AssertUnwindSafe};
use crate::js::export::VMFunction; use crate::js::export::VMFunction;
@@ -25,7 +25,7 @@ use wasmer_types::RawValue;
/// (using the Native ABI). /// (using the Native ABI).
#[derive(Clone)] #[derive(Clone)]
pub struct TypedFunction<Args = (), Rets = ()> { pub struct TypedFunction<Args = (), Rets = ()> {
pub(crate) handle: StoreHandle<VMFunction>, pub(crate) handle: VMFunction,
_phantom: PhantomData<(Args, Rets)>, _phantom: PhantomData<(Args, Rets)>,
} }
@@ -40,7 +40,7 @@ where
#[allow(dead_code)] #[allow(dead_code)]
pub(crate) fn new<T>(store: &mut impl AsStoreMut, vm_function: VMFunction) -> Self { pub(crate) fn new<T>(store: &mut impl AsStoreMut, vm_function: VMFunction) -> Self {
Self { Self {
handle: StoreHandle::new(store.as_store_mut().objects_mut(), vm_function), handle: vm_function,
_phantom: PhantomData, _phantom: PhantomData,
} }
} }
@@ -78,7 +78,7 @@ macro_rules! impl_native_traits {
let mut r; let mut r;
// TODO: This loop is needed for asyncify. It will be refactored with https://github.com/wasmerio/wasmer/issues/3451 // TODO: This loop is needed for asyncify. It will be refactored with https://github.com/wasmerio/wasmer/issues/3451
loop { loop {
r = self.handle.get(store.as_store_ref().objects()).function.apply( r = self.handle.function.apply(
&JsValue::UNDEFINED, &JsValue::UNDEFINED,
&Array::from_iter(params_list.iter()) &Array::from_iter(params_list.iter())
); );

View File

@@ -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 { impl AsStoreRef for Store {
fn as_store_ref(&self) -> StoreRef<'_> { fn as_store_ref(&self) -> StoreRef<'_> {
StoreRef { inner: &self.inner } StoreRef { inner: &self.inner }
@@ -207,7 +199,8 @@ impl<T: AsStoreMut> AsStoreMut for &'_ mut T {
} }
} }
pub use objects::*; pub(crate) use objects::{InternalStoreHandle, StoreObject};
pub use objects::{StoreHandle, StoreId, StoreObjects};
mod objects { mod objects {
use wasm_bindgen::JsValue; use wasm_bindgen::JsValue;
@@ -266,11 +259,15 @@ mod objects {
} }
impl_store_object! { impl_store_object! {
functions => VMFunction, // Note: we store the globals in order to be able to access them later via
tables => VMTable, // `StoreObjects::iter_globals`.
globals => VMGlobal, globals => VMGlobal,
memories => VMMemory, // functions => VMFunction,
instances => js_sys::WebAssembly::Instance, // 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, function_environments => VMFunctionEnvironment,
} }
@@ -278,11 +275,7 @@ mod objects {
#[derive(Default)] #[derive(Default)]
pub struct StoreObjects { pub struct StoreObjects {
id: StoreId, id: StoreId,
memories: Vec<VMMemory>,
tables: Vec<VMTable>,
globals: Vec<VMGlobal>, globals: Vec<VMGlobal>,
functions: Vec<VMFunction>,
instances: Vec<js_sys::WebAssembly::Instance>,
function_environments: Vec<VMFunctionEnvironment>, function_environments: Vec<VMFunctionEnvironment>,
} }
@@ -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<T> {
/// The data is owned here.
Host(Box<UnsafeCell<T>>),
/// The data is stored inline in the `VMContext` of an instance.
Instance(NonNull<T>),
}
#[allow(dead_code)]
impl<T> MaybeInstanceOwned<T> {
/// Returns underlying pointer to the VM data.
#[allow(dead_code)]
pub fn as_ptr(&self) -> NonNull<T> {
match self {
MaybeInstanceOwned::Host(p) => unsafe { NonNull::new_unchecked(p.get()) },
MaybeInstanceOwned::Instance(p) => *p,
}
}
}
} }

View File

@@ -44,12 +44,7 @@ impl AsJs for Value {
Self::F32(f) => JsValue::from_f64(*f as f64), Self::F32(f) => JsValue::from_f64(*f as f64),
Self::F64(f) => JsValue::from_f64(*f), Self::F64(f) => JsValue::from_f64(*f),
Self::V128(f) => JsValue::from_f64(*f as f64), Self::V128(f) => JsValue::from_f64(*f as f64),
Self::FuncRef(Some(func)) => func Self::FuncRef(Some(func)) => func.handle.function.clone().into(),
.handle
.get(store.as_store_ref().objects())
.function
.clone()
.into(),
Self::FuncRef(None) => JsValue::null(), Self::FuncRef(None) => JsValue::null(),
} }
} }

View File

@@ -94,12 +94,7 @@ impl Value {
Self::F32(v) => v as f64, Self::F32(v) => v as f64,
Self::F64(v) => v, Self::F64(v) => v,
Self::V128(v) => v as f64, Self::V128(v) => v as f64,
Self::FuncRef(Some(ref f)) => f Self::FuncRef(Some(ref f)) => f.handle.function.as_f64().unwrap_or(0_f64), //TODO is this correct?
.handle
.get(store.as_store_ref().objects())
.function
.as_f64()
.unwrap_or(0_f64), //TODO is this correct?
Self::FuncRef(None) => 0_f64, Self::FuncRef(None) => 0_f64,
//Self::ExternRef(Some(ref e)) => unsafe { *e.address().0 } as .into_raw(), //Self::ExternRef(Some(ref e)) => unsafe { *e.address().0 } as .into_raw(),