Skip to content

Commit

Permalink
Merge pull request #3129 from wasmerio/fix-sync-js-sys-api
Browse files Browse the repository at this point in the history
Fix differences between -sys and -js API
  • Loading branch information
syrusakbary authored Sep 2, 2022
2 parents e259738 + 3dc2e26 commit fd9113a
Show file tree
Hide file tree
Showing 21 changed files with 387 additions and 86 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ Looking for changes that affect our C API? See the [C API Changelog](lib/c-api/C

### Changed
- #[3131](https://github.com/wasmerio/wasmer/pull/3131) Update migration docs for MemoryView changes
- #[3129](https://github.com/wasmerio/wasmer/pull/3129) Fix differences between -sys and -js API

### Fixed
- #[3130](https://github.com/wasmerio/wasmer/pull/3130) Remove panics from Artifact::deserialize
Expand Down
36 changes: 34 additions & 2 deletions lib/api/src/js/error.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ use crate::js::trap::RuntimeError;
use std::borrow::Cow;
#[cfg(feature = "std")]
use thiserror::Error;
use wasmer_types::ImportError;

// Compilation Errors
//
Expand Down Expand Up @@ -144,6 +145,28 @@ pub enum DeserializeError {
Compiler(CompileError),
}

/// The WebAssembly.LinkError object indicates an error during
/// module instantiation (besides traps from the start function).
///
/// This is based on the [link error][link-error] API.
///
/// [link-error]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/WebAssembly/LinkError
#[derive(Error, Debug)]
#[error("Link error: {0}")]
pub enum LinkError {
/// An error occurred when checking the import types.
#[error("Error while importing {0:?}.{1:?}: {2}")]
Import(String, String, ImportError),

#[cfg(not(target_arch = "wasm32"))]
/// A trap ocurred during linking.
#[error("RuntimeError occurred during linking: {0}")]
Trap(#[source] RuntimeError),
/// Insufficient resources available for linking.
#[error("Insufficient resources: {0}")]
Resource(String),
}

/// An error while instantiating a module.
///
/// This is not a common WebAssembly error, however
Expand All @@ -156,13 +179,18 @@ pub enum DeserializeError {
#[cfg_attr(feature = "std", derive(Error))]
pub enum InstantiationError {
/// A linking ocurred during instantiation.
#[cfg_attr(feature = "std", error("Link error: {0}"))]
Link(String),
#[cfg_attr(feature = "std", error(transparent))]
Link(LinkError),

/// A runtime error occured while invoking the start function
#[cfg_attr(feature = "std", error(transparent))]
Start(RuntimeError),

/// The module was compiled with a CPU feature that is not available on
/// the current host.
#[cfg_attr(feature = "std", error("missing required CPU features: {0:?}"))]
CpuFeature(String),

/// Import from a different [`Store`].
/// This error occurs when an import from a different store is used.
#[cfg_attr(feature = "std", error("cannot mix imports from different stores"))]
Expand All @@ -171,6 +199,10 @@ pub enum InstantiationError {
/// A generic error occured while invoking API functions
#[cfg_attr(feature = "std", error(transparent))]
Wasm(WasmError),

/// Insufficient resources available for execution.
#[cfg_attr(feature = "std", error("Can't get {0} from the instance exports"))]
NotInExports(String),
}

impl From<WasmError> for InstantiationError {
Expand Down
42 changes: 31 additions & 11 deletions lib/api/src/js/externals/function.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
pub use self::inner::{FromToNativeWasmType, HostFunction, WasmTypeList, WithEnv, WithoutEnv};
use crate::js::exports::{ExportError, Exportable};
use crate::js::externals::Extern;
use crate::js::externals::{Extern, VMExtern};
use crate::js::function_env::FunctionEnvMut;
use crate::js::store::{AsStoreMut, AsStoreRef, InternalStoreHandle, StoreHandle, StoreMut};
use crate::js::types::{param_from_js, AsJs}; /* ValFuncRef */
Expand All @@ -26,6 +26,7 @@ fn result_to_js(val: &Value) -> JsValue {
Value::I64(i) => JsValue::from_f64(*i as _),
Value::F32(f) => JsValue::from_f64(*f as _),
Value::F64(f) => JsValue::from_f64(*f),
Value::V128(f) => JsValue::from_f64(*f as _),
val => unimplemented!(
"The value `{:?}` is not yet supported in the JS Function API",
val
Expand Down Expand Up @@ -77,6 +78,11 @@ impl Function {
Self::new_with_env(store, &env, ty, wrapped_func)
}

/// To `VMExtern`.
pub fn to_vm_extern(&self) -> VMExtern {
VMExtern::Function(self.handle.internal_handle())
}

/// Creates a new host `Function` (dynamic) with the provided signature.
///
/// If you know the signature of the host function at compile time,
Expand Down Expand Up @@ -229,13 +235,13 @@ impl Function {
note = "new_native_with_env() has been renamed to new_typed_with_env()."
)]
/// Creates a new host `Function` with an environment from a typed function.
pub fn new_native_with_env<T, F, Args, Rets>(
pub fn new_native_with_env<T: Send + 'static, F, Args, Rets>(
store: &mut impl AsStoreMut,
env: &FunctionEnv<T>,
func: F,
) -> Self
where
F: HostFunction<T, Args, Rets, WithEnv>,
F: HostFunction<T, Args, Rets, WithEnv> + 'static + Send + Sync,
Args: WasmTypeList,
Rets: WasmTypeList,
{
Expand Down Expand Up @@ -309,8 +315,8 @@ impl Function {
/// assert_eq!(f.ty().params(), vec![Type::I32, Type::I32]);
/// assert_eq!(f.ty().results(), vec![Type::I32]);
/// ```
pub fn ty<'context>(&self, store: &'context impl AsStoreRef) -> &'context FunctionType {
&self.handle.get(store.as_store_ref().objects()).ty
pub fn ty(&self, store: &impl AsStoreRef) -> FunctionType {
self.handle.get(store.as_store_ref().objects()).ty.clone()
}

/// Returns the number of parameters that this function takes.
Expand Down Expand Up @@ -598,7 +604,7 @@ mod inner {
use super::RuntimeError;
use super::VMFunctionBody;
use crate::js::function_env::{FunctionEnvMut, VMFunctionEnvironment};
use crate::js::store::{AsStoreMut, InternalStoreHandle, StoreHandle, StoreMut};
use crate::js::store::{AsStoreMut, AsStoreRef, InternalStoreHandle, StoreHandle, StoreMut};
use crate::js::FunctionEnv;
use crate::js::NativeWasmTypeInto;
use std::array::TryFromSliceError;
Expand Down Expand Up @@ -639,6 +645,9 @@ mod inner {
/// This method panics if `self` cannot fit in the
/// `Self::Native` type.
fn to_native(self) -> Self::Native;

/// Returns whether this native type belongs to the given store
fn is_from_store(&self, _store: &impl AsStoreRef) -> bool;
}

macro_rules! from_to_native_wasm_type {
Expand All @@ -657,6 +666,11 @@ mod inner {
fn to_native(self) -> Self::Native {
self as Self::Native
}

#[inline]
fn is_from_store(&self, _store: &impl AsStoreRef) -> bool {
true // Javascript only has one store
}
}
)*
};
Expand All @@ -678,6 +692,11 @@ mod inner {
fn to_native(self) -> Self::Native {
Self::Native::from_ne_bytes(Self::to_ne_bytes(self))
}

#[inline]
fn is_from_store(&self, _store: &impl AsStoreRef) -> bool {
true // Javascript only has one store
}
}
)*
};
Expand Down Expand Up @@ -887,11 +906,12 @@ mod inner {
Args: WasmTypeList,
Rets: WasmTypeList,
Kind: HostFunctionKind,
T: Sized,
Self: Sized,
{
/// Get the pointer to the function body.
fn function_body_ptr(self) -> *const VMFunctionBody;
fn function_body_ptr(&self) -> *const VMFunctionBody;

// /// Get the pointer to the function call trampoline.
// fn call_trampoline_address() -> VMTrampoline;
}

/// Empty trait to specify the kind of `HostFunction`: With or
Expand Down Expand Up @@ -1102,7 +1122,7 @@ mod inner {
Func: Fn(FunctionEnvMut<'_, T>, $( $x , )*) -> RetsAsResult + 'static,
{
#[allow(non_snake_case)]
fn function_body_ptr(self) -> *const VMFunctionBody {
fn function_body_ptr(&self) -> *const VMFunctionBody {
/// This is a function that wraps the real host
/// function. Its address will be used inside the
/// runtime.
Expand Down Expand Up @@ -1150,7 +1170,7 @@ mod inner {
Func: Fn($( $x , )*) -> RetsAsResult + 'static,
{
#[allow(non_snake_case)]
fn function_body_ptr(self) -> *const VMFunctionBody {
fn function_body_ptr(&self) -> *const VMFunctionBody {
/// This is a function that wraps the real host
/// function. Its address will be used inside the
/// runtime.
Expand Down
16 changes: 6 additions & 10 deletions lib/api/src/js/externals/global.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
use crate::js::export::VMGlobal;
use crate::js::exports::{ExportError, Exportable};
use crate::js::externals::Extern;
use crate::js::externals::{Extern, VMExtern};
use crate::js::store::{AsStoreMut, AsStoreRef, InternalStoreHandle, StoreHandle};
use crate::js::value::Value;
use crate::js::wasm_bindgen_polyfill::Global as JSGlobal;
Expand Down Expand Up @@ -55,6 +55,11 @@ impl Global {
Self::from_value(store, val, Mutability::Var).unwrap()
}

/// To `VMExtern`.
pub(crate) fn to_vm_extern(&self) -> VMExtern {
VMExtern::Global(self.handle.internal_handle())
}

/// Create a `Global` with the initial value [`Value`] and the provided [`Mutability`].
fn from_value(
store: &mut impl AsStoreMut,
Expand Down Expand Up @@ -135,15 +140,6 @@ impl Global {
let ty = self.handle.get(store.as_store_ref().objects()).ty;
Value::from_raw(store, ty.ty, raw)
}
/*
match self.vm_global.ty.ty {
ValType::I32 => Value::I32(self.vm_global.global.value().as_f64().unwrap() as _),
ValType::I64 => Value::I64(self.vm_global.global.value().as_f64().unwrap() as _),
ValType::F32 => Value::F32(self.vm_global.global.value().as_f64().unwrap() as _),
ValType::F64 => Value::F64(self.vm_global.global.value().as_f64().unwrap()),
_ => unimplemented!("The type is not yet supported in the JS Global API"),
}
*/
}

/// Sets a custom value [`Value`] to the runtime Global.
Expand Down
13 changes: 12 additions & 1 deletion lib/api/src/js/externals/memory.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
use crate::js::export::VMMemory;
use crate::js::exports::{ExportError, Exportable};
use crate::js::externals::Extern;
use crate::js::externals::{Extern, VMExtern};
use crate::js::store::{AsStoreMut, AsStoreRef, InternalStoreHandle, StoreHandle, StoreObjects};
use crate::js::{MemoryAccessError, MemoryType};
use std::marker::PhantomData;
Expand Down Expand Up @@ -118,6 +118,11 @@ impl Memory {
Self::from_vm_extern(new_store, handle.internal_handle())
}

/// To `VMExtern`.
pub(crate) fn to_vm_extern(&self) -> VMExtern {
VMExtern::Memory(self.handle.internal_handle())
}

/// Returns the [`MemoryType`] of the `Memory`.
///
/// # Example
Expand Down Expand Up @@ -218,6 +223,12 @@ impl Memory {
}
}

impl std::cmp::PartialEq for Memory {
fn eq(&self, other: &Self) -> bool {
self.handle == other.handle
}
}

impl<'a> Exportable<'a> for Memory {
fn get_self_from_extern(_extern: &'a Extern) -> Result<&'a Self, ExportError> {
match _extern {
Expand Down
Loading

0 comments on commit fd9113a

Please sign in to comment.