Skip to content

Commit

Permalink
Merge pull request #3534 from wasmerio/js-api-simplify-store
Browse files Browse the repository at this point in the history
Use JS VM store instead of artificially replicate it
  • Loading branch information
syrusakbary authored Jan 26, 2023
2 parents 1f1ec93 + 6707e67 commit 59d2d90
Show file tree
Hide file tree
Showing 15 changed files with 160 additions and 574 deletions.
54 changes: 21 additions & 33 deletions lib/api/src/js/externals/function.rs
Original file line number Diff line number Diff line change
@@ -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, InternalStoreHandle, StoreHandle, StoreMut};
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;
Expand All @@ -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)]
Expand Down Expand Up @@ -58,11 +59,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<VMFunction>,
pub(crate) handle: VMFunction,
}

impl From<StoreHandle<VMFunction>> for Function {
fn from(handle: StoreHandle<VMFunction>) -> Self {
impl From<VMFunction> for Function {
fn from(handle: VMFunction) -> Self {
Self { handle }
}
}
Expand All @@ -86,7 +87,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.
Expand Down Expand Up @@ -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(
Expand All @@ -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::<F>() != 0 {
Self::closures_unsupported_panic();
}
Expand All @@ -232,7 +233,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,
}
}

Expand Down Expand Up @@ -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::<F>() != 0 {
Self::closures_unsupported_panic();
}
Expand All @@ -300,7 +301,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,
}
}

Expand All @@ -321,8 +322,8 @@ 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 {
self.handle.get(store.as_store_ref().objects()).ty.clone()
pub fn ty(&self, _store: &impl AsStoreRef) -> FunctionType {
self.handle.ty.clone()
}

/// Returns the number of parameters that this function takes.
Expand Down Expand Up @@ -422,7 +423,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,
);
Expand All @@ -446,7 +447,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 => {
Expand All @@ -465,21 +466,8 @@ 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),
}
}

pub(crate) fn from_vm_extern(
store: &mut impl AsStoreMut,
internal: InternalStoreHandle<VMFunction>,
) -> 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().")]
Expand Down Expand Up @@ -616,8 +604,8 @@ 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()
pub fn is_from_store(&self, _store: &impl AsStoreRef) -> bool {
true
}
}

Expand Down
54 changes: 17 additions & 37 deletions lib/api/src/js/externals/global.rs
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
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::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;
Expand All @@ -17,7 +17,7 @@ use wasm_bindgen::JsValue;
/// Spec: <https://webassembly.github.io/spec/core/exec/runtime.html#global-instances>
#[derive(Debug, Clone, PartialEq)]
pub struct Global {
pub(crate) handle: StoreHandle<VMGlobal>,
pub(crate) handle: VMGlobal,
}

impl Global {
Expand Down Expand Up @@ -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`].
Expand Down Expand Up @@ -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`.
Expand All @@ -112,8 +112,8 @@ 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 {
self.handle.get(store.as_store_ref().objects()).ty
pub fn ty(&self, _store: &impl AsStoreRef) -> GlobalType {
self.handle.ty
}

/// Retrieves the current value [`Value`] that the Global has.
Expand All @@ -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)
}
}
Expand Down Expand Up @@ -207,33 +201,19 @@ 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),
}
}

pub(crate) fn from_vm_extern(
store: &mut impl AsStoreMut,
internal: InternalStoreHandle<VMGlobal>,
) -> Self {
Self {
handle: unsafe {
StoreHandle::from_internal(store.as_store_ref().objects().id(), internal)
},
}
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 }
}

/// 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()
pub fn is_from_store(&self, _store: &impl AsStoreRef) -> bool {
true
}
}

Expand Down
55 changes: 19 additions & 36 deletions lib/api/src/js/externals/memory.rs
Original file line number Diff line number Diff line change
@@ -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::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;
Expand Down Expand Up @@ -65,7 +65,7 @@ extern "C" {
/// Spec: <https://webassembly.github.io/spec/core/exec/runtime.html#memory-instances>
#[derive(Debug, Clone)]
pub struct Memory {
pub(crate) handle: StoreHandle<VMMemory>,
pub(crate) handle: VMMemory,
}

unsafe impl Send for Memory {}
Expand All @@ -87,7 +87,7 @@ impl Memory {
/// ```
pub fn new(store: &mut impl AsStoreMut, ty: MemoryType) -> Result<Self, MemoryError> {
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<js_sys::WebAssembly::Memory, MemoryError> {
Expand Down Expand Up @@ -115,19 +115,17 @@ impl Memory {
ty: MemoryType,
) -> Result<Self, MemoryError> {
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`.
Expand All @@ -143,8 +141,8 @@ impl Memory {
///
/// assert_eq!(m.ty(), mt);
/// ```
pub fn ty(&self, store: &impl AsStoreRef) -> MemoryType {
self.handle.get(store.as_store_ref().objects()).ty
pub fn ty(&self, _store: &impl AsStoreRef) -> MemoryType {
self.handle.ty
}

/// Creates a view into the memory that then allows for
Expand Down Expand Up @@ -192,7 +190,7 @@ impl Memory {
IntoPages: Into<Pages>,
{
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::<js_sys::RangeError>() {
Expand Down Expand Up @@ -236,38 +234,23 @@ impl Memory {
Ok(new_memory)
}

pub(crate) fn from_vm_export(store: &mut impl AsStoreMut, vm_memory: VMMemory) -> Self {
Self {
handle: StoreHandle::new(store.objects_mut(), vm_memory),
}
}

pub(crate) fn from_vm_extern(
store: &mut impl AsStoreMut,
internal: InternalStoreHandle<VMMemory>,
) -> 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<VMMemory> {
let mem = self.handle.get(store.as_store_ref().objects());
mem.try_clone()
pub fn try_clone(&self, _store: &impl AsStoreRef) -> Option<VMMemory> {
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()
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<VMMemory, MemoryError> {
let mem = self.handle.get(store.as_store_ref().objects());
mem.duplicate()
pub fn duplicate(&mut self, _store: &impl AsStoreRef) -> Result<VMMemory, MemoryError> {
self.handle.duplicate()
}
}

Expand Down
5 changes: 2 additions & 3 deletions lib/api/src/js/externals/memory_view.rs
Original file line number Diff line number Diff line change
Expand Up @@ -26,9 +26,8 @@ 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)
pub(crate) fn new(memory: &Memory, _store: &impl AsStoreRef) -> Self {
Self::new_raw(&memory.handle.memory)
}

pub(crate) fn new_raw(memory: &js_sys::WebAssembly::Memory) -> Self {
Expand Down
Loading

0 comments on commit 59d2d90

Please sign in to comment.