From 1fb3fbe25cdedaf0e4e0684895c708b653047a4d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Felix=20Sch=C3=BCtt?= Date: Tue, 23 Aug 2022 12:24:00 +0200 Subject: [PATCH 01/45] Start fixing diff between -sys and -js API --- lib/api/src/js/externals/memory.rs | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/lib/api/src/js/externals/memory.rs b/lib/api/src/js/externals/memory.rs index 015769b89..bfddab87f 100644 --- a/lib/api/src/js/externals/memory.rs +++ b/lib/api/src/js/externals/memory.rs @@ -218,6 +218,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 { From fd80f77bb6d69e063de697a0990ba7b1b2a03926 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Felix=20Sch=C3=BCtt?= Date: Tue, 23 Aug 2022 12:36:16 +0200 Subject: [PATCH 02/45] Add u128 support to js/Value --- lib/api/src/js/value.rs | 26 +++++++++++++++++++++++++- 1 file changed, 25 insertions(+), 1 deletion(-) diff --git a/lib/api/src/js/value.rs b/lib/api/src/js/value.rs index a285abe3f..3cf1df337 100644 --- a/lib/api/src/js/value.rs +++ b/lib/api/src/js/value.rs @@ -37,6 +37,9 @@ pub enum Value { /// A first-class reference to a WebAssembly function. FuncRef(Option), + + /// A 128-bit number + V128(u128), } macro_rules! accessors { @@ -76,6 +79,7 @@ impl Value { Self::I64(_) => Type::I64, Self::F32(_) => Type::F32, Self::F64(_) => Type::F64, + Self::V128(_) => Type::V128, //Self::ExternRef(_) => Type::ExternRef, Self::FuncRef(_) => Type::FuncRef, } @@ -88,6 +92,7 @@ impl Value { Self::I64(v) => v as f64, 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()) @@ -112,7 +117,7 @@ impl Value { Type::F32 => Self::F32(raw as f32), Type::F64 => Self::F64(raw), Type::FuncRef => todo!(), - Type::V128 => todo!(), + Type::V128 => Self::V128(raw as u128), Type::ExternRef => todo!(), //Self::ExternRef( //{ @@ -134,6 +139,7 @@ impl Value { | Self::I64(_) | Self::F32(_) | Self::F64(_) + | Self::V128(_) //| Self::ExternRef(None) | Self::FuncRef(None) => true, //Self::ExternRef(Some(e)) => e.is_from_store(store), @@ -147,6 +153,7 @@ impl Value { (I64(i64) i64 unwrap_i64 *e) (F32(f32) f32 unwrap_f32 *e) (F64(f64) f64 unwrap_f64 *e) + (V128(u128) v128 unwrap_v128 *e) //(ExternRef(&Option) externref unwrap_externref e) (FuncRef(&Option) funcref unwrap_funcref e) } @@ -159,6 +166,7 @@ impl fmt::Debug for Value { Self::I64(v) => write!(f, "I64({:?})", v), Self::F32(v) => write!(f, "F32({:?})", v), Self::F64(v) => write!(f, "F64({:?})", v), + Self::V128(v) => write!(f, "V128({:?})", v), //Self::ExternRef(None) => write!(f, "Null ExternRef"), //Self::ExternRef(Some(v)) => write!(f, "ExternRef({:?})", v), Self::FuncRef(None) => write!(f, "Null FuncRef"), @@ -174,12 +182,19 @@ impl ToString for Value { Self::I64(v) => v.to_string(), Self::F32(v) => v.to_string(), Self::F64(v) => v.to_string(), + Self::V128(v) => v.to_string(), //Self::ExternRef(_) => "externref".to_string(), Self::FuncRef(_) => "funcref".to_string(), } } } +impl From for Value { + fn from(val: u128) -> Self { + Self::V128(val) + } +} + impl From for Value { fn from(val: i32) -> Self { Self::I32(val) @@ -246,9 +261,18 @@ const NOT_I32: &str = "Value is not of Wasm type i32"; const NOT_I64: &str = "Value is not of Wasm type i64"; const NOT_F32: &str = "Value is not of Wasm type f32"; const NOT_F64: &str = "Value is not of Wasm type f64"; +const NOT_V128: &str = "Value is not of Wasm type u128"; const NOT_FUNCREF: &str = "Value is not of Wasm type funcref"; //const NOT_EXTERNREF: &str = "Value is not of Wasm type externref"; +impl TryFrom for u128 { + type Error = &'static str; + + fn try_from(value: Value) -> Result { + value.v128().ok_or(NOT_V128) + } +} + impl TryFrom for i32 { type Error = &'static str; From b1fac30b3cfc05e75e29b936c51aff592887b8a9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Felix=20Sch=C3=BCtt?= Date: Tue, 23 Aug 2022 12:59:21 +0200 Subject: [PATCH 03/45] Fix f64 -> RawValue in JS API --- lib/api/src/js/externals/function.rs | 12 +++++++----- lib/api/src/js/module.rs | 27 +++++++++++++++++++++++++++ 2 files changed, 34 insertions(+), 5 deletions(-) diff --git a/lib/api/src/js/externals/function.rs b/lib/api/src/js/externals/function.rs index a74a3fa22..d89c2ae0a 100644 --- a/lib/api/src/js/externals/function.rs +++ b/lib/api/src/js/externals/function.rs @@ -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 @@ -607,7 +608,7 @@ mod inner { use std::marker::PhantomData; use std::panic::{self, AssertUnwindSafe}; - use wasmer_types::{FunctionType, NativeWasmType, Type}; + use wasmer_types::{FunctionType, RawValue, NativeWasmType, Type}; // use wasmer::{raise_user_trap, resume_panic}; /// A trait to convert a Rust value to a `WasmNativeType` value, @@ -783,10 +784,10 @@ mod inner { /// # Safety unsafe fn into_c_struct(self, store: &mut impl AsStoreMut) -> Self::CStruct; - /// Writes the contents of a C struct to an array of `f64`. + /// Writes the contents of a C struct to an array of `RawValue`. /// /// # Safety - unsafe fn write_c_struct_to_ptr(c_struct: Self::CStruct, ptr: *mut f64); + unsafe fn write_c_struct_to_ptr(c_struct: Self::CStruct, ptr: *mut RawValue); /// Get the Wasm types for the tuple (list) of currently /// represented values. @@ -838,6 +839,7 @@ mod inner { mod test_into_result { use super::*; use std::convert::Infallible; + use wasmer_types::RawValue; #[test] fn test_into_result_over_t() { @@ -1067,7 +1069,7 @@ mod inner { } #[allow(non_snake_case)] - unsafe fn write_c_struct_to_ptr(c_struct: Self::CStruct, _ptr: *mut f64) { + unsafe fn write_c_struct_to_ptr(c_struct: Self::CStruct, _ptr: *mut RawValue) { // Unpack items of the tuple. let $c_struct_name( $( $x ),* ) = c_struct; @@ -1264,7 +1266,7 @@ mod inner { self } - unsafe fn write_c_struct_to_ptr(_: Self::CStruct, _: *mut f64) {} + unsafe fn write_c_struct_to_ptr(_: Self::CStruct, _: *mut RawValue) {} fn wasm_types() -> &'static [Type] { &[] diff --git a/lib/api/src/js/module.rs b/lib/api/src/js/module.rs index 975d1bee5..1431a16a8 100644 --- a/lib/api/src/js/module.rs +++ b/lib/api/src/js/module.rs @@ -318,6 +318,33 @@ impl Module { Self::new(_store, bytes).map_err(|e| DeserializeError::Compiler(e)) } + + #[cfg(feature = "compiler")] + /// Deserializes a a serialized Module located in a `Path` into a `Module`. + /// > Note: the module has to be serialized before with the `serialize` method. + /// + /// # Safety + /// + /// Please check [`Module::deserialize`]. + /// + /// # Usage + /// + /// ```ignore + /// # use wasmer::*; + /// # let mut store = Store::default(); + /// # fn main() -> anyhow::Result<()> { + /// let module = Module::deserialize_from_file(&store, path)?; + /// # Ok(()) + /// # } + /// ``` + pub unsafe fn deserialize_from_file( + store: &impl AsStoreRef, + path: impl AsRef, + ) -> Result { + let artifact = std::fs::read(path.as_ref())?; + Ok(Self::new(store, bytes).map_err(|e| DeserializeError::Compiler(e))) + } + /// Sets the name of the current module. /// This is normally useful for stacktraces and debugging. /// From 161aa626facb4763e127d5708d7ab2012f5c9a86 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Felix=20Sch=C3=BCtt?= Date: Tue, 23 Aug 2022 13:02:30 +0200 Subject: [PATCH 04/45] More f64 -> RawValue conversion --- lib/api/src/js/externals/function.rs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/lib/api/src/js/externals/function.rs b/lib/api/src/js/externals/function.rs index d89c2ae0a..a432eb35d 100644 --- a/lib/api/src/js/externals/function.rs +++ b/lib/api/src/js/externals/function.rs @@ -758,7 +758,7 @@ mod inner { /// # Safety unsafe fn from_slice( store: &mut impl AsStoreMut, - slice: &[f64], + slice: &[RawValue], ) -> Result; /// Builds and returns an array of type `Array` from a tuple @@ -1015,7 +1015,7 @@ mod inner { } #[allow(clippy::missing_safety_doc)] - unsafe fn from_slice(store: &mut impl AsStoreMut, slice: &[f64]) -> Result { + unsafe fn from_slice(store: &mut impl AsStoreMut, slice: &[RawValue]) -> Result { Ok(Self::from_array(store, slice.try_into()?)) } @@ -1245,7 +1245,7 @@ mod inner { unsafe fn from_slice( _: &mut impl AsStoreMut, - _: &[f64], + _: &[RawValue], ) -> Result { unreachable!() } From 34ddd282f9fe2c5c693f4d71324c310ae60ec586 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Felix=20Sch=C3=BCtt?= Date: Tue, 23 Aug 2022 13:05:48 +0200 Subject: [PATCH 05/45] Fix js::Value::from_raw --- lib/api/src/js/value.rs | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/lib/api/src/js/value.rs b/lib/api/src/js/value.rs index 3cf1df337..6d9343bcd 100644 --- a/lib/api/src/js/value.rs +++ b/lib/api/src/js/value.rs @@ -2,12 +2,12 @@ use std::convert::TryFrom; use std::fmt; use std::string::{String, ToString}; -use wasmer_types::Type; +use wasmer_types::{Type, RawValue}; //use crate::ExternRef; use crate::js::externals::function::Function; -use super::store::AsStoreRef; +use super::store::{AsStoreRef, AsStoreMut}; /// WebAssembly computations manipulate values of basic value types: /// * Integers (32 or 64 bit width) @@ -110,14 +110,14 @@ impl Value { /// /// # Safety /// - pub unsafe fn from_raw(_store: &impl AsStoreRef, ty: Type, raw: f64) -> Self { + pub unsafe fn from_raw(store: &mut impl AsStoreMut, ty: Type, raw: RawValue) -> Self { match ty { - Type::I32 => Self::I32(raw as i32), - Type::I64 => Self::I64(raw as i64), - Type::F32 => Self::F32(raw as f32), - Type::F64 => Self::F64(raw), + Type::I32 => Self::I32(raw.i32), + Type::I64 => Self::I64(raw.i64), + Type::F32 => Self::F32(raw.f32), + Type::F64 => Self::F64(raw.f64), + Type::V128 => Self::V128(raw.u128), Type::FuncRef => todo!(), - Type::V128 => Self::V128(raw as u128), Type::ExternRef => todo!(), //Self::ExternRef( //{ From e09e70657bfcdc1c00778db1e44998b531dcfe94 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Felix=20Sch=C3=BCtt?= Date: Tue, 23 Aug 2022 13:10:53 +0200 Subject: [PATCH 06/45] Fix NativeWasmTypeInto::from_raw --- lib/api/src/js/native_type.rs | 42 ++++++++++++++++++++++++++--------- 1 file changed, 32 insertions(+), 10 deletions(-) diff --git a/lib/api/src/js/native_type.rs b/lib/api/src/js/native_type.rs index 814abf4c1..b4715dc7b 100644 --- a/lib/api/src/js/native_type.rs +++ b/lib/api/src/js/native_type.rs @@ -1,7 +1,7 @@ //! This module permits to create native functions //! easily in Rust, thanks to its advanced typing system. -use wasmer_types::{NativeWasmType, Type}; +use wasmer_types::{NativeWasmType, RawValue, Type}; use crate::js::Function; @@ -23,7 +23,7 @@ pub trait NativeWasmTypeInto: NativeWasmType + Sized { /// /// # Safety /// - unsafe fn from_raw(store: &mut impl AsStoreMut, raw: f64) -> Self; + unsafe fn from_raw(store: &mut impl AsStoreMut, raw: RawValue) -> Self; } impl NativeWasmTypeInto for i32 { @@ -43,8 +43,8 @@ impl NativeWasmTypeInto for i32 { } #[inline] - unsafe fn from_raw(_store: &mut impl AsStoreMut, raw: f64) -> Self { - raw as _ + unsafe fn from_raw(_store: &mut impl AsStoreMut, raw: RawValue) -> Self { + raw.i32 } } @@ -65,8 +65,8 @@ impl NativeWasmTypeInto for i64 { } #[inline] - unsafe fn from_raw(_store: &mut impl AsStoreMut, raw: f64) -> Self { - raw as _ + unsafe fn from_raw(_store: &mut impl AsStoreMut, raw: RawValue) -> Self { + raw.i64 } } @@ -87,8 +87,8 @@ impl NativeWasmTypeInto for f32 { } #[inline] - unsafe fn from_raw(_store: &mut impl AsStoreMut, raw: f64) -> Self { - raw as _ + unsafe fn from_raw(_store: &mut impl AsStoreMut, raw: RawValue) -> Self { + raw.f32 } } @@ -109,8 +109,30 @@ impl NativeWasmTypeInto for f64 { } #[inline] - unsafe fn from_raw(_store: &mut impl AsStoreMut, raw: f64) -> Self { - raw + unsafe fn from_raw(_store: &mut impl AsStoreMut, raw: RawValue) -> Self { + raw.f64 + } +} + +impl NativeWasmTypeInto for u128 { + #[inline] + unsafe fn from_abi(_store: &mut impl AsStoreMut, abi: Self::Abi) -> Self { + abi + } + + #[inline] + fn into_abi(self, _store: &mut impl AsStoreMut) -> Self::Abi { + self + } + + #[inline] + fn into_raw(self, _store: &mut impl AsStoreMut) -> f64 { + self.into() + } + + #[inline] + unsafe fn from_raw(_store: &mut impl AsStoreMut, raw: RawValue) -> Self { + raw.u128 } } From e026812134330db6e0af68124279cf6c65a6aa33 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Felix=20Sch=C3=BCtt?= Date: Tue, 23 Aug 2022 17:17:17 +0200 Subject: [PATCH 07/45] Fix Function::new to not take self argument --- lib/api/src/js/externals/function.rs | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/lib/api/src/js/externals/function.rs b/lib/api/src/js/externals/function.rs index a432eb35d..91ce9d30e 100644 --- a/lib/api/src/js/externals/function.rs +++ b/lib/api/src/js/externals/function.rs @@ -893,7 +893,7 @@ mod inner { Self: Sized, { /// Get the pointer to the function body. - fn function_body_ptr(self) -> *const VMFunctionBody; + fn function_body_ptr() -> *const VMFunctionBody; } /// Empty trait to specify the kind of `HostFunction`: With or @@ -951,7 +951,7 @@ mod inner { T: Sized, { Self { - address: function.function_body_ptr(), + address: >::function_body_ptr(), _phantom: PhantomData, } } @@ -1104,7 +1104,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() -> *const VMFunctionBody { /// This is a function that wraps the real host /// function. Its address will be used inside the /// runtime. @@ -1152,7 +1152,7 @@ mod inner { Func: Fn($( $x , )*) -> RetsAsResult + 'static, { #[allow(non_snake_case)] - fn function_body_ptr(self) -> *const VMFunctionBody { + fn function_body_ptr() -> *const VMFunctionBody { /// This is a function that wraps the real host /// function. Its address will be used inside the /// runtime. From 59bc9a70961ca29559323528e02dd9b449705149 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Felix=20Sch=C3=BCtt?= Date: Tue, 23 Aug 2022 17:23:49 +0200 Subject: [PATCH 08/45] Revert f64 -> RawValue --- lib/api/src/js/externals/function.rs | 17 ++++++++--------- lib/api/src/js/module.rs | 1 - lib/api/src/js/native_type.rs | 24 ++++++++++++------------ lib/api/src/js/value.rs | 16 ++++++++-------- 4 files changed, 28 insertions(+), 30 deletions(-) diff --git a/lib/api/src/js/externals/function.rs b/lib/api/src/js/externals/function.rs index 91ce9d30e..2d625ca7f 100644 --- a/lib/api/src/js/externals/function.rs +++ b/lib/api/src/js/externals/function.rs @@ -608,7 +608,7 @@ mod inner { use std::marker::PhantomData; use std::panic::{self, AssertUnwindSafe}; - use wasmer_types::{FunctionType, RawValue, NativeWasmType, Type}; + use wasmer_types::{FunctionType, NativeWasmType, Type}; // use wasmer::{raise_user_trap, resume_panic}; /// A trait to convert a Rust value to a `WasmNativeType` value, @@ -758,7 +758,7 @@ mod inner { /// # Safety unsafe fn from_slice( store: &mut impl AsStoreMut, - slice: &[RawValue], + slice: &[f64], ) -> Result; /// Builds and returns an array of type `Array` from a tuple @@ -784,10 +784,10 @@ mod inner { /// # Safety unsafe fn into_c_struct(self, store: &mut impl AsStoreMut) -> Self::CStruct; - /// Writes the contents of a C struct to an array of `RawValue`. + /// Writes the contents of a C struct to an array of `f64`. /// /// # Safety - unsafe fn write_c_struct_to_ptr(c_struct: Self::CStruct, ptr: *mut RawValue); + unsafe fn write_c_struct_to_ptr(c_struct: Self::CStruct, ptr: *mut f64); /// Get the Wasm types for the tuple (list) of currently /// represented values. @@ -839,7 +839,6 @@ mod inner { mod test_into_result { use super::*; use std::convert::Infallible; - use wasmer_types::RawValue; #[test] fn test_into_result_over_t() { @@ -1015,7 +1014,7 @@ mod inner { } #[allow(clippy::missing_safety_doc)] - unsafe fn from_slice(store: &mut impl AsStoreMut, slice: &[RawValue]) -> Result { + unsafe fn from_slice(store: &mut impl AsStoreMut, slice: &[f64]) -> Result { Ok(Self::from_array(store, slice.try_into()?)) } @@ -1069,7 +1068,7 @@ mod inner { } #[allow(non_snake_case)] - unsafe fn write_c_struct_to_ptr(c_struct: Self::CStruct, _ptr: *mut RawValue) { + unsafe fn write_c_struct_to_ptr(c_struct: Self::CStruct, _ptr: *mut f64) { // Unpack items of the tuple. let $c_struct_name( $( $x ),* ) = c_struct; @@ -1245,7 +1244,7 @@ mod inner { unsafe fn from_slice( _: &mut impl AsStoreMut, - _: &[RawValue], + _: &[f64], ) -> Result { unreachable!() } @@ -1266,7 +1265,7 @@ mod inner { self } - unsafe fn write_c_struct_to_ptr(_: Self::CStruct, _: *mut RawValue) {} + unsafe fn write_c_struct_to_ptr(_: Self::CStruct, _: *mut f64) {} fn wasm_types() -> &'static [Type] { &[] diff --git a/lib/api/src/js/module.rs b/lib/api/src/js/module.rs index 1431a16a8..9ad68a7f8 100644 --- a/lib/api/src/js/module.rs +++ b/lib/api/src/js/module.rs @@ -318,7 +318,6 @@ impl Module { Self::new(_store, bytes).map_err(|e| DeserializeError::Compiler(e)) } - #[cfg(feature = "compiler")] /// Deserializes a a serialized Module located in a `Path` into a `Module`. /// > Note: the module has to be serialized before with the `serialize` method. diff --git a/lib/api/src/js/native_type.rs b/lib/api/src/js/native_type.rs index b4715dc7b..23e37c24e 100644 --- a/lib/api/src/js/native_type.rs +++ b/lib/api/src/js/native_type.rs @@ -1,7 +1,7 @@ //! This module permits to create native functions //! easily in Rust, thanks to its advanced typing system. -use wasmer_types::{NativeWasmType, RawValue, Type}; +use wasmer_types::{NativeWasmType, Type}; use crate::js::Function; @@ -23,7 +23,7 @@ pub trait NativeWasmTypeInto: NativeWasmType + Sized { /// /// # Safety /// - unsafe fn from_raw(store: &mut impl AsStoreMut, raw: RawValue) -> Self; + unsafe fn from_raw(store: &mut impl AsStoreMut, raw: f64) -> Self; } impl NativeWasmTypeInto for i32 { @@ -43,8 +43,8 @@ impl NativeWasmTypeInto for i32 { } #[inline] - unsafe fn from_raw(_store: &mut impl AsStoreMut, raw: RawValue) -> Self { - raw.i32 + unsafe fn from_raw(_store: &mut impl AsStoreMut, raw: f64) -> Self { + raw as _ } } @@ -65,8 +65,8 @@ impl NativeWasmTypeInto for i64 { } #[inline] - unsafe fn from_raw(_store: &mut impl AsStoreMut, raw: RawValue) -> Self { - raw.i64 + unsafe fn from_raw(_store: &mut impl AsStoreMut, raw: f64) -> Self { + raw as _ } } @@ -87,8 +87,8 @@ impl NativeWasmTypeInto for f32 { } #[inline] - unsafe fn from_raw(_store: &mut impl AsStoreMut, raw: RawValue) -> Self { - raw.f32 + unsafe fn from_raw(_store: &mut impl AsStoreMut, raw: f64) -> Self { + raw as _ } } @@ -109,8 +109,8 @@ impl NativeWasmTypeInto for f64 { } #[inline] - unsafe fn from_raw(_store: &mut impl AsStoreMut, raw: RawValue) -> Self { - raw.f64 + unsafe fn from_raw(_store: &mut impl AsStoreMut, raw: f64) -> Self { + raw } } @@ -131,8 +131,8 @@ impl NativeWasmTypeInto for u128 { } #[inline] - unsafe fn from_raw(_store: &mut impl AsStoreMut, raw: RawValue) -> Self { - raw.u128 + unsafe fn from_raw(_store: &mut impl AsStoreMut, raw: f64) -> Self { + raw as _ } } diff --git a/lib/api/src/js/value.rs b/lib/api/src/js/value.rs index 6d9343bcd..a1def4de9 100644 --- a/lib/api/src/js/value.rs +++ b/lib/api/src/js/value.rs @@ -2,12 +2,12 @@ use std::convert::TryFrom; use std::fmt; use std::string::{String, ToString}; -use wasmer_types::{Type, RawValue}; +use wasmer_types::Type; //use crate::ExternRef; use crate::js::externals::function::Function; -use super::store::{AsStoreRef, AsStoreMut}; +use super::store::{AsStoreMut, AsStoreRef}; /// WebAssembly computations manipulate values of basic value types: /// * Integers (32 or 64 bit width) @@ -110,13 +110,13 @@ impl Value { /// /// # Safety /// - pub unsafe fn from_raw(store: &mut impl AsStoreMut, ty: Type, raw: RawValue) -> Self { + pub unsafe fn from_raw(store: &mut impl AsStoreMut, ty: Type, raw: f64) -> Self { match ty { - Type::I32 => Self::I32(raw.i32), - Type::I64 => Self::I64(raw.i64), - Type::F32 => Self::F32(raw.f32), - Type::F64 => Self::F64(raw.f64), - Type::V128 => Self::V128(raw.u128), + Type::I32 => Self::I32(raw as _), + Type::I64 => Self::I64(raw as _), + Type::F32 => Self::F32(raw as _), + Type::F64 => Self::F64(raw), + Type::V128 => Self::V128(raw as _), Type::FuncRef => todo!(), Type::ExternRef => todo!(), //Self::ExternRef( From c410d79c371ff266af0363c1054f82f27c97a519 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Felix=20Sch=C3=BCtt?= Date: Tue, 23 Aug 2022 17:31:25 +0200 Subject: [PATCH 09/45] Add WasmSlice::is_empty --- lib/api/src/js/mem_access.rs | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/lib/api/src/js/mem_access.rs b/lib/api/src/js/mem_access.rs index 1e697d4cb..ac0a54343 100644 --- a/lib/api/src/js/mem_access.rs +++ b/lib/api/src/js/mem_access.rs @@ -197,6 +197,12 @@ impl<'a, T: ValueType> WasmSlice<'a, T> { self.len } + /// Return if the slice is empty. + #[inline] + pub fn is_empty(&self) -> bool { + self.len == 0 + } + /// Get a `WasmRef` to an element in the slice. #[inline] pub fn index(self, idx: u64) -> WasmRef<'a, T> { From 4540e3ba8fb5c8be0f5673bf6239c03dd4f54577 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Felix=20Sch=C3=BCtt?= Date: Wed, 24 Aug 2022 11:12:37 +0200 Subject: [PATCH 10/45] Add Module::custom_sections and FromToNativeWasmType::is_from_store --- lib/api/src/js/externals/function.rs | 15 ++++++++++++++- lib/api/src/js/module.rs | 20 ++++++++++---------- lib/api/src/js/ptr.rs | 6 +++++- 3 files changed, 29 insertions(+), 12 deletions(-) diff --git a/lib/api/src/js/externals/function.rs b/lib/api/src/js/externals/function.rs index 2d625ca7f..7cdb61814 100644 --- a/lib/api/src/js/externals/function.rs +++ b/lib/api/src/js/externals/function.rs @@ -599,7 +599,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; @@ -640,6 +640,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 { @@ -658,6 +661,11 @@ mod inner { fn to_native(self) -> Self::Native { self as Self::Native } + + #[inline] + fn is_from_store(&self, _store: &impl AsStoreRef) -> bool { + self.handle.store_id() == store.as_store_ref().objects().id() + } } )* }; @@ -679,6 +687,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 { + self.handle.store_id() == store.as_store_ref().objects().id() + } } )* }; diff --git a/lib/api/src/js/module.rs b/lib/api/src/js/module.rs index 9ad68a7f8..73b12ac21 100644 --- a/lib/api/src/js/module.rs +++ b/lib/api/src/js/module.rs @@ -551,16 +551,16 @@ impl Module { ExportsIterator::new(iter, exports.length() as usize) } - // /// Get the custom sections of the module given a `name`. - // /// - // /// # Important - // /// - // /// Following the WebAssembly spec, one name can have multiple - // /// custom sections. That's why an iterator (rather than one element) - // /// is returned. - // pub fn custom_sections<'a>(&'a self, name: &'a str) -> impl Iterator> + 'a { - // unimplemented!(); - // } + /// Get the custom sections of the module given a `name`. + /// + /// # Important + /// + /// Following the WebAssembly spec, one name can have multiple + /// custom sections. That's why an iterator (rather than one element) + /// is returned. + pub fn custom_sections<'a>(&'a self, name: &'a str) -> impl Iterator> + 'a { + unimplemented!() + } } impl fmt::Debug for Module { diff --git a/lib/api/src/js/ptr.rs b/lib/api/src/js/ptr.rs index b7b812c43..41773f0c8 100644 --- a/lib/api/src/js/ptr.rs +++ b/lib/api/src/js/ptr.rs @@ -1,4 +1,4 @@ -use crate::js::NativeWasmTypeInto; +use crate::{AsStoreRef, js::NativeWasmTypeInto}; use crate::js::{externals::MemoryView, FromToNativeWasmType}; use crate::js::{MemoryAccessError, WasmRef, WasmSlice}; use std::convert::TryFrom; @@ -234,6 +234,10 @@ where _phantom: PhantomData, } } + #[inline] + fn is_from_store(&self, store: &impl AsStoreRef) -> bool { + true // TODO ??? + } } unsafe impl ValueType for WasmPtr { From 4966ec45ba4615affbe70f794ecdcdf79dc5837d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Felix=20Sch=C3=BCtt?= Date: Wed, 24 Aug 2022 11:25:22 +0200 Subject: [PATCH 11/45] Always return true for is_from_store --- lib/api/src/js/externals/function.rs | 4 ++-- lib/api/src/js/module.rs | 2 +- lib/api/src/js/ptr.rs | 4 ++-- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/lib/api/src/js/externals/function.rs b/lib/api/src/js/externals/function.rs index 7cdb61814..d53c0bd5f 100644 --- a/lib/api/src/js/externals/function.rs +++ b/lib/api/src/js/externals/function.rs @@ -664,7 +664,7 @@ mod inner { #[inline] fn is_from_store(&self, _store: &impl AsStoreRef) -> bool { - self.handle.store_id() == store.as_store_ref().objects().id() + true // Javascript only has one store } } )* @@ -690,7 +690,7 @@ mod inner { #[inline] fn is_from_store(&self, _store: &impl AsStoreRef) -> bool { - self.handle.store_id() == store.as_store_ref().objects().id() + true // Javascript only has one store } } )* diff --git a/lib/api/src/js/module.rs b/lib/api/src/js/module.rs index 73b12ac21..e0b5e91b3 100644 --- a/lib/api/src/js/module.rs +++ b/lib/api/src/js/module.rs @@ -559,7 +559,7 @@ impl Module { /// custom sections. That's why an iterator (rather than one element) /// is returned. pub fn custom_sections<'a>(&'a self, name: &'a str) -> impl Iterator> + 'a { - unimplemented!() + unimplemented!() // TODO: implement on JavaScript } } diff --git a/lib/api/src/js/ptr.rs b/lib/api/src/js/ptr.rs index 41773f0c8..d04115aab 100644 --- a/lib/api/src/js/ptr.rs +++ b/lib/api/src/js/ptr.rs @@ -235,8 +235,8 @@ where } } #[inline] - fn is_from_store(&self, store: &impl AsStoreRef) -> bool { - true // TODO ??? + fn is_from_store(&self, _store: &impl AsStoreRef) -> bool { + true // in Javascript there are no different stores } } From a52856d18daa2783bc1749d09ca03d6f5d532ee6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Felix=20Sch=C3=BCtt?= Date: Wed, 24 Aug 2022 12:13:30 +0200 Subject: [PATCH 12/45] Add LinkError to JS API --- lib/api/src/js/error.rs | 23 +++++++++++++++++++++++ lib/api/src/js/imports.rs | 15 +++++++-------- 2 files changed, 30 insertions(+), 8 deletions(-) diff --git a/lib/api/src/js/error.rs b/lib/api/src/js/error.rs index f334b4a1c..dbabf6760 100644 --- a/lib/api/src/js/error.rs +++ b/lib/api/src/js/error.rs @@ -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 // @@ -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 diff --git a/lib/api/src/js/imports.rs b/lib/api/src/js/imports.rs index 63a199abb..47b1f86ac 100644 --- a/lib/api/src/js/imports.rs +++ b/lib/api/src/js/imports.rs @@ -1,7 +1,7 @@ //! The import module contains the implementation data structures and helper functions used to //! manipulate and access a wasm module's imports including memories, tables, globals, and //! functions. -use crate::js::error::InstantiationError; +use crate::js::error::{InstantiationError, LinkError}; use crate::js::exports::Exports; use crate::js::module::Module; use crate::js::store::AsStoreRef; @@ -130,7 +130,7 @@ impl Imports { /// Resolve and return a vector of imports in the order they are defined in the `module`'s source code. /// /// This means the returned `Vec` might be a subset of the imports contained in `self`. - pub fn imports_for_module(&self, module: &Module) -> Result, InstantiationError> { + pub fn imports_for_module(&self, module: &Module) -> Result, LinkError> { let mut ret = vec![]; for import in module.imports() { if let Some(imp) = self @@ -139,12 +139,11 @@ impl Imports { { ret.push(imp.clone()); } else { - return Err(InstantiationError::Link(format!( - "Error while importing {0:?}.{1:?}: unknown import. Expected {2:?}", - import.module(), - import.name(), - import.ty() - ))); + return Err(LinkError::Import( + import.module().to_string(), + import.name().to_string(), + ImportError::UnknownImport(import.ty().clone()), + )); } } Ok(ret) From e589318e4fb515da437a233aa4e9b9d28916992e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Felix=20Sch=C3=BCtt?= Date: Wed, 24 Aug 2022 12:20:15 +0200 Subject: [PATCH 13/45] Added missing cases to InstantiationError --- lib/api/src/js/error.rs | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/lib/api/src/js/error.rs b/lib/api/src/js/error.rs index dbabf6760..586e060fa 100644 --- a/lib/api/src/js/error.rs +++ b/lib/api/src/js/error.rs @@ -178,14 +178,20 @@ pub enum LinkError { #[derive(Debug)] #[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"))] From 93abcceacee0e2060a5eb5d983efde2d1fc61205 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Felix=20Sch=C3=BCtt?= Date: Wed, 24 Aug 2022 12:30:16 +0200 Subject: [PATCH 14/45] Add Send + 'static bounds for Function::new_native_with_env --- lib/api/src/js/externals/function.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/api/src/js/externals/function.rs b/lib/api/src/js/externals/function.rs index d53c0bd5f..396906a61 100644 --- a/lib/api/src/js/externals/function.rs +++ b/lib/api/src/js/externals/function.rs @@ -230,13 +230,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( + pub fn new_native_with_env( store: &mut impl AsStoreMut, env: &FunctionEnv, func: F, ) -> Self where - F: HostFunction, + F: HostFunction + 'static + Send + Sync, Args: WasmTypeList, Rets: WasmTypeList, { From 4e93a76c716b70c31e08b708b694cb115c223fdb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Felix=20Sch=C3=BCtt?= Date: Wed, 24 Aug 2022 12:38:53 +0200 Subject: [PATCH 15/45] Add Instance::new_by_index function --- lib/api/src/js/instance.rs | 33 +++++++++++++++++++++++++++++++++ 1 file changed, 33 insertions(+) diff --git a/lib/api/src/js/instance.rs b/lib/api/src/js/instance.rs index 1b1eb0898..2812b3fa5 100644 --- a/lib/api/src/js/instance.rs +++ b/lib/api/src/js/instance.rs @@ -75,6 +75,39 @@ impl Instance { Ok(self_instance) } + /// Creates a new `Instance` from a WebAssembly [`Module`] and a + /// vector of imports. + /// + /// ## Errors + /// + /// The function can return [`InstantiationError`]s. + /// + /// Those are, as defined by the spec: + /// * Link errors that happen when plugging the imports into the instance + /// * Runtime errors that happen when running the module `start` function. + pub fn new_by_index(store: &mut impl AsStoreMut, module: &Module, externs: &[Extern]) + -> Result { + let imports = externs.to_vec(); + let mut handle = module.instantiate(store, &imports)?; + let exports = module + .exports() + .map(|export| { + let name = export.name().to_string(); + let export = handle.lookup(&name).expect("export"); + let extern_ = Extern::from_vm_extern(store, export); + (name, extern_) + }) + .collect::(); + + let instance = Self { + _handle: StoreHandle::new(store.objects_mut(), handle), + module: module.clone(), + exports, + }; + + Ok(instance) + } + /// Creates a Wasmer `Instance` from a Wasmer `Module` and a WebAssembly Instance /// /// # Important From 55cea221e826676a61d0fec0d99d9d2f7205d275 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Felix=20Sch=C3=BCtt?= Date: Wed, 24 Aug 2022 12:43:10 +0200 Subject: [PATCH 16/45] Add From for Function --- lib/api/src/sys/externals/function.rs | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/lib/api/src/sys/externals/function.rs b/lib/api/src/sys/externals/function.rs index 87bfa8237..25f38ceba 100644 --- a/lib/api/src/sys/externals/function.rs +++ b/lib/api/src/sys/externals/function.rs @@ -41,6 +41,16 @@ pub struct Function { pub(crate) handle: StoreHandle, } +impl From> for Function +where + Args: WasmTypeList, + Rets: WasmTypeList, +{ + fn from(other: TypedFunction) -> Self { + other.func + } +} + impl Function { /// Creates a new host `Function` (dynamic) with the provided signature. /// From 66d293a8ff78bb006578285c8af2f9eea03e6aa3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Felix=20Sch=C3=BCtt?= Date: Wed, 24 Aug 2022 12:48:50 +0200 Subject: [PATCH 17/45] Fix Function::ty --- lib/api/src/js/externals/function.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/api/src/js/externals/function.rs b/lib/api/src/js/externals/function.rs index 396906a61..a48aae853 100644 --- a/lib/api/src/js/externals/function.rs +++ b/lib/api/src/js/externals/function.rs @@ -310,8 +310,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. From 88e06c4a849cb198e3247062e5d6e9bdb96e9f38 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Felix=20Sch=C3=BCtt?= Date: Wed, 24 Aug 2022 12:50:06 +0200 Subject: [PATCH 18/45] Fix Table::copy signature --- lib/api/src/js/externals/table.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/lib/api/src/js/externals/table.rs b/lib/api/src/js/externals/table.rs index 3cd9882fe..8a3df5845 100644 --- a/lib/api/src/js/externals/table.rs +++ b/lib/api/src/js/externals/table.rs @@ -143,6 +143,7 @@ impl Table { /// Returns an error if the range is out of bounds of either the source or /// destination tables. pub fn copy( + _store: &mut impl AsStoreMut, _dst_table: &Self, _dst_index: u32, _src_table: &Self, From 2fa85bd873a91d541d4a0e444fd418c1eeb7046d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Felix=20Sch=C3=BCtt?= Date: Wed, 24 Aug 2022 12:55:29 +0200 Subject: [PATCH 19/45] Fix HostFunction trait --- lib/api/src/js/externals/function.rs | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/lib/api/src/js/externals/function.rs b/lib/api/src/js/externals/function.rs index a48aae853..dfd71af0f 100644 --- a/lib/api/src/js/externals/function.rs +++ b/lib/api/src/js/externals/function.rs @@ -900,12 +900,13 @@ mod inner { where Args: WasmTypeList, Rets: WasmTypeList, - Kind: HostFunctionKind, - T: Sized, - Self: Sized, + Kind: HostFunctionKind { /// Get the pointer to the function body. fn function_body_ptr() -> *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 From 2e9a58c4b1fff2a23745a575f34b93f245cd9c3d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Felix=20Sch=C3=BCtt?= Date: Wed, 24 Aug 2022 16:11:58 +0200 Subject: [PATCH 20/45] Add to_vm_extern / from_vm_extern --- lib/api/src/js/externals/function.rs | 7 ++++- lib/api/src/js/externals/mod.rs | 43 ++++++++++++++++++++++------ lib/api/src/js/externals/table.rs | 7 ++++- lib/api/src/sys/externals/memory.rs | 1 + 4 files changed, 48 insertions(+), 10 deletions(-) diff --git a/lib/api/src/js/externals/function.rs b/lib/api/src/js/externals/function.rs index dfd71af0f..eb3785c8c 100644 --- a/lib/api/src/js/externals/function.rs +++ b/lib/api/src/js/externals/function.rs @@ -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 */ @@ -78,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, diff --git a/lib/api/src/js/externals/mod.rs b/lib/api/src/js/externals/mod.rs index 2748e08b1..26c245f01 100644 --- a/lib/api/src/js/externals/mod.rs +++ b/lib/api/src/js/externals/mod.rs @@ -10,14 +10,31 @@ pub use self::memory::{Memory, MemoryError}; pub use self::memory_view::MemoryView; pub use self::table::Table; -use crate::js::export::Export; +use crate::js::export::{Export, VMMemory, VMTable, VMFunction, VMGlobal}; use crate::js::exports::{ExportError, Exportable}; use crate::js::store::StoreObject; +use crate::js::store::InternalStoreHandle; use crate::js::store::{AsStoreMut, AsStoreRef}; use crate::js::types::AsJs; use crate::js::ExternType; use std::fmt; + +/// The value of an export passed from one instance to another. +pub enum VMExtern { + /// A function export value. + Function(InternalStoreHandle), + + /// A table export value. + Table(InternalStoreHandle), + + /// A memory export value. + Memory(InternalStoreHandle), + + /// A global export value. + Global(InternalStoreHandle), +} + /// An `Extern` is the runtime representation of an entity that /// can be imported or exported. /// @@ -45,13 +62,23 @@ impl Extern { } } - /// Create an `Extern` from an `wasmer_compiler::Export`. - pub fn from_vm_extern(store: &mut impl AsStoreMut, export: Export) -> Self { - match export { - Export::Function(f) => Self::Function(Function::from_vm_extern(store, f)), - Export::Memory(m) => Self::Memory(Memory::from_vm_extern(store, m)), - Export::Global(g) => Self::Global(Global::from_vm_extern(store, g)), - Export::Table(t) => Self::Table(Table::from_vm_extern(store, t)), + /// Create an `Extern` from an `wasmer_engine::Export`. + pub fn from_vm_extern(store: &mut impl AsStoreMut, vm_extern: VMExtern) -> Self { + match vm_extern { + VMExtern::Function(f) => Self::Function(Function::from_vm_extern(store, f)), + VMExtern::Memory(m) => Self::Memory(Memory::from_vm_extern(store, m)), + VMExtern::Global(g) => Self::Global(Global::from_vm_extern(store, g)), + VMExtern::Table(t) => Self::Table(Table::from_vm_extern(store, t)), + } + } + + /// To `VMExtern`. + pub fn to_vm_extern(&self) -> VMExtern { + match self { + Self::Function(f) => f.to_vm_extern(), + Self::Global(g) => g.to_vm_extern(), + Self::Memory(m) => m.to_vm_extern(), + Self::Table(t) => t.to_vm_extern(), } } diff --git a/lib/api/src/js/externals/table.rs b/lib/api/src/js/externals/table.rs index 8a3df5845..87e638305 100644 --- a/lib/api/src/js/externals/table.rs +++ b/lib/api/src/js/externals/table.rs @@ -1,6 +1,6 @@ use crate::js::export::{VMFunction, VMTable}; 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::RuntimeError; @@ -75,6 +75,11 @@ impl Table { }) } + /// To `VMExtern`. + pub fn to_vm_extern(&self) -> VMExtern { + VMExtern::Table(self.handle.internal_handle()) + } + /// Returns the [`TableType`] of the `Table`. pub fn ty(&self, store: &impl AsStoreRef) -> TableType { self.handle.get(store.as_store_ref().objects()).ty diff --git a/lib/api/src/sys/externals/memory.rs b/lib/api/src/sys/externals/memory.rs index 285acb231..0793513f5 100644 --- a/lib/api/src/sys/externals/memory.rs +++ b/lib/api/src/sys/externals/memory.rs @@ -154,6 +154,7 @@ impl Memory { mem.try_clone().map(|mem| mem.into()) } + /// To `VMExtern`. pub(crate) fn to_vm_extern(&self) -> VMExtern { VMExtern::Memory(self.handle.internal_handle()) } From 355be4bc7cdbb11ee26e8f2981e6cf7880e50873 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Felix=20Sch=C3=BCtt?= Date: Wed, 24 Aug 2022 16:26:52 +0200 Subject: [PATCH 21/45] Reexport wasmparser from js --- lib/api/src/js/mod.rs | 3 +++ 1 file changed, 3 insertions(+) diff --git a/lib/api/src/js/mod.rs b/lib/api/src/js/mod.rs index 1e660a530..7711cd85d 100644 --- a/lib/api/src/js/mod.rs +++ b/lib/api/src/js/mod.rs @@ -88,6 +88,9 @@ pub use wasmer_types::{ #[cfg(feature = "wat")] pub use wat::parse_bytes as wat2wasm; +#[cfg(feature = "wasm-types-polyfill")] +pub use wasmparser; + /// Version number of this crate. pub const VERSION: &str = env!("CARGO_PKG_VERSION"); From bafe1a9d3c8d9a4bc7ae52dd7de5d98c2e0a071c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Felix=20Sch=C3=BCtt?= Date: Wed, 24 Aug 2022 16:34:16 +0200 Subject: [PATCH 22/45] Fix some compilation errors in make test-js --- lib/api/src/js/externals/function.rs | 2 +- lib/api/src/js/externals/global.rs | 11 +---------- lib/api/src/js/imports.rs | 1 + lib/api/src/js/module.rs | 3 ++- 4 files changed, 5 insertions(+), 12 deletions(-) diff --git a/lib/api/src/js/externals/function.rs b/lib/api/src/js/externals/function.rs index eb3785c8c..3e808e624 100644 --- a/lib/api/src/js/externals/function.rs +++ b/lib/api/src/js/externals/function.rs @@ -316,7 +316,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.get(store.as_store_ref().objects()).ty.clone() } /// Returns the number of parameters that this function takes. diff --git a/lib/api/src/js/externals/global.rs b/lib/api/src/js/externals/global.rs index 35e2fa464..2892c1624 100644 --- a/lib/api/src/js/externals/global.rs +++ b/lib/api/src/js/externals/global.rs @@ -123,7 +123,7 @@ impl Global { /// /// assert_eq!(g.get(), Value::I32(1)); /// ``` - pub fn get(&self, store: &impl AsStoreRef) -> Value { + pub fn get(&self, store: &mut impl AsStoreMut) -> Value { unsafe { let raw = self .handle @@ -135,15 +135,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. diff --git a/lib/api/src/js/imports.rs b/lib/api/src/js/imports.rs index 47b1f86ac..603a5bc72 100644 --- a/lib/api/src/js/imports.rs +++ b/lib/api/src/js/imports.rs @@ -7,6 +7,7 @@ use crate::js::module::Module; use crate::js::store::AsStoreRef; use crate::js::types::AsJs; use crate::Extern; +use wasmer_types::ImportError; use std::collections::HashMap; use std::fmt; diff --git a/lib/api/src/js/module.rs b/lib/api/src/js/module.rs index e0b5e91b3..fc08967d0 100644 --- a/lib/api/src/js/module.rs +++ b/lib/api/src/js/module.rs @@ -559,7 +559,8 @@ impl Module { /// custom sections. That's why an iterator (rather than one element) /// is returned. pub fn custom_sections<'a>(&'a self, name: &'a str) -> impl Iterator> + 'a { - unimplemented!() // TODO: implement on JavaScript + // TODO: implement on JavaScript + unimplemented!() } } From 037cecaef1a75987725c7f6ca8b0e58a7394c80b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Felix=20Sch=C3=BCtt?= Date: Wed, 24 Aug 2022 16:37:49 +0200 Subject: [PATCH 23/45] Remove impl From> for Function --- lib/api/src/sys/native.rs | 10 ---------- 1 file changed, 10 deletions(-) diff --git a/lib/api/src/sys/native.rs b/lib/api/src/sys/native.rs index 827931aef..373cc6a7f 100644 --- a/lib/api/src/sys/native.rs +++ b/lib/api/src/sys/native.rs @@ -45,16 +45,6 @@ impl Clone for TypedFunction } } -impl From> for Function -where - Args: WasmTypeList, - Rets: WasmTypeList, -{ - fn from(other: TypedFunction) -> Self { - other.func - } -} - macro_rules! impl_native_traits { ( $( $x:ident ),* ) => { #[allow(unused_parens, non_snake_case)] From e788bbc11fa4b09c2685cef6fa664b173fbd720d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Felix=20Sch=C3=BCtt?= Date: Wed, 24 Aug 2022 18:36:13 +0200 Subject: [PATCH 24/45] Fix errors in "make lint" --- lib/api/src/js/error.rs | 1 - lib/api/src/js/externals/function.rs | 2 +- lib/api/src/js/externals/mod.rs | 5 ++-- lib/api/src/js/externals/table.rs | 2 +- lib/api/src/js/imports.rs | 2 +- lib/api/src/js/instance.rs | 7 +++-- lib/api/src/js/ptr.rs | 2 +- lib/api/src/sys/externals/function.rs | 10 ------- lib/api/src/sys/native.rs | 2 +- lib/api/src/sys/native_type.rs | 12 ++++++++- lib/cli/src/c_gen/mod.rs | 4 +-- .../src/artifact_builders/artifact_builder.rs | 2 +- lib/compiler/src/engine/artifact.rs | 4 +-- lib/emscripten/src/lib.rs | 2 +- lib/types/src/error.rs | 2 +- lib/types/src/serialize.rs | 2 +- lib/vm/src/instance/mod.rs | 4 +-- lib/vm/src/libcalls.rs | 26 +++++++++---------- lib/wasi/src/syscalls/mod.rs | 6 ++--- 19 files changed, 49 insertions(+), 48 deletions(-) diff --git a/lib/api/src/js/error.rs b/lib/api/src/js/error.rs index 586e060fa..a999a4235 100644 --- a/lib/api/src/js/error.rs +++ b/lib/api/src/js/error.rs @@ -178,7 +178,6 @@ pub enum LinkError { #[derive(Debug)] #[cfg_attr(feature = "std", derive(Error))] pub enum InstantiationError { - /// A linking ocurred during instantiation. #[cfg_attr(feature = "std", error(transparent))] Link(LinkError), diff --git a/lib/api/src/js/externals/function.rs b/lib/api/src/js/externals/function.rs index 3e808e624..a8a8bea24 100644 --- a/lib/api/src/js/externals/function.rs +++ b/lib/api/src/js/externals/function.rs @@ -905,7 +905,7 @@ mod inner { where Args: WasmTypeList, Rets: WasmTypeList, - Kind: HostFunctionKind + Kind: HostFunctionKind, { /// Get the pointer to the function body. fn function_body_ptr() -> *const VMFunctionBody; diff --git a/lib/api/src/js/externals/mod.rs b/lib/api/src/js/externals/mod.rs index 26c245f01..5472ee52f 100644 --- a/lib/api/src/js/externals/mod.rs +++ b/lib/api/src/js/externals/mod.rs @@ -10,16 +10,15 @@ pub use self::memory::{Memory, MemoryError}; pub use self::memory_view::MemoryView; pub use self::table::Table; -use crate::js::export::{Export, VMMemory, VMTable, VMFunction, VMGlobal}; +use crate::js::export::{Export, VMFunction, VMGlobal, VMMemory, VMTable}; use crate::js::exports::{ExportError, Exportable}; -use crate::js::store::StoreObject; use crate::js::store::InternalStoreHandle; +use crate::js::store::StoreObject; use crate::js::store::{AsStoreMut, AsStoreRef}; use crate::js::types::AsJs; use crate::js::ExternType; use std::fmt; - /// The value of an export passed from one instance to another. pub enum VMExtern { /// A function export value. diff --git a/lib/api/src/js/externals/table.rs b/lib/api/src/js/externals/table.rs index 87e638305..e81400bb6 100644 --- a/lib/api/src/js/externals/table.rs +++ b/lib/api/src/js/externals/table.rs @@ -148,7 +148,7 @@ impl Table { /// Returns an error if the range is out of bounds of either the source or /// destination tables. pub fn copy( - _store: &mut impl AsStoreMut, + _store: &mut impl AsStoreMut, _dst_table: &Self, _dst_index: u32, _src_table: &Self, diff --git a/lib/api/src/js/imports.rs b/lib/api/src/js/imports.rs index 603a5bc72..8b4b3ad95 100644 --- a/lib/api/src/js/imports.rs +++ b/lib/api/src/js/imports.rs @@ -7,9 +7,9 @@ use crate::js::module::Module; use crate::js::store::AsStoreRef; use crate::js::types::AsJs; use crate::Extern; -use wasmer_types::ImportError; use std::collections::HashMap; use std::fmt; +use wasmer_types::ImportError; /// All of the import data used when instantiating. /// diff --git a/lib/api/src/js/instance.rs b/lib/api/src/js/instance.rs index 2812b3fa5..7ee379a75 100644 --- a/lib/api/src/js/instance.rs +++ b/lib/api/src/js/instance.rs @@ -85,8 +85,11 @@ impl Instance { /// Those are, as defined by the spec: /// * Link errors that happen when plugging the imports into the instance /// * Runtime errors that happen when running the module `start` function. - pub fn new_by_index(store: &mut impl AsStoreMut, module: &Module, externs: &[Extern]) - -> Result { + pub fn new_by_index( + store: &mut impl AsStoreMut, + module: &Module, + externs: &[Extern], + ) -> Result { let imports = externs.to_vec(); let mut handle = module.instantiate(store, &imports)?; let exports = module diff --git a/lib/api/src/js/ptr.rs b/lib/api/src/js/ptr.rs index d04115aab..f9ecc19a6 100644 --- a/lib/api/src/js/ptr.rs +++ b/lib/api/src/js/ptr.rs @@ -1,6 +1,6 @@ -use crate::{AsStoreRef, js::NativeWasmTypeInto}; use crate::js::{externals::MemoryView, FromToNativeWasmType}; use crate::js::{MemoryAccessError, WasmRef, WasmSlice}; +use crate::{js::NativeWasmTypeInto, AsStoreRef}; use std::convert::TryFrom; use std::{fmt, marker::PhantomData, mem}; pub use wasmer_types::Memory32; diff --git a/lib/api/src/sys/externals/function.rs b/lib/api/src/sys/externals/function.rs index 25f38ceba..87bfa8237 100644 --- a/lib/api/src/sys/externals/function.rs +++ b/lib/api/src/sys/externals/function.rs @@ -41,16 +41,6 @@ pub struct Function { pub(crate) handle: StoreHandle, } -impl From> for Function -where - Args: WasmTypeList, - Rets: WasmTypeList, -{ - fn from(other: TypedFunction) -> Self { - other.func - } -} - impl Function { /// Creates a new host `Function` (dynamic) with the provided signature. /// diff --git a/lib/api/src/sys/native.rs b/lib/api/src/sys/native.rs index 373cc6a7f..d5d3bc5aa 100644 --- a/lib/api/src/sys/native.rs +++ b/lib/api/src/sys/native.rs @@ -17,7 +17,7 @@ use wasmer_types::RawValue; /// A WebAssembly function that can be called natively /// (using the Native ABI). pub struct TypedFunction { - func: Function, + pub(crate) func: Function, _phantom: PhantomData Rets>, } diff --git a/lib/api/src/sys/native_type.rs b/lib/api/src/sys/native_type.rs index 8446e95b3..42f3f2393 100644 --- a/lib/api/src/sys/native_type.rs +++ b/lib/api/src/sys/native_type.rs @@ -4,7 +4,7 @@ use wasmer_types::{NativeWasmType, RawValue, Type}; use wasmer_vm::{VMExternRef, VMFuncRef}; -use crate::{ExternRef, Function}; +use crate::{ExternRef, Function, TypedFunction, WasmTypeList}; use super::store::AsStoreMut; @@ -165,6 +165,16 @@ impl NativeWasmTypeInto for Option { } } +impl From> for Function +where + Args: WasmTypeList, + Rets: WasmTypeList, +{ + fn from(other: TypedFunction) -> Self { + other.func + } +} + impl NativeWasmType for Function { const WASM_TYPE: Type = Type::FuncRef; type Abi = usize; diff --git a/lib/cli/src/c_gen/mod.rs b/lib/cli/src/c_gen/mod.rs index addc30a8c..dbb56490a 100644 --- a/lib/cli/src/c_gen/mod.rs +++ b/lib/cli/src/c_gen/mod.rs @@ -125,7 +125,7 @@ impl CType { #[allow(clippy::borrowed_box)] let ret: CType = return_value .as_ref() - .map(|i: &Box| (&**i).clone()) + .map(|i: &Box| (**i).clone()) .unwrap_or_default(); ret.generate_c(w); w.push(' '); @@ -183,7 +183,7 @@ impl CType { #[allow(clippy::borrowed_box)] let ret: CType = return_value .as_ref() - .map(|i: &Box| (&**i).clone()) + .map(|i: &Box| (**i).clone()) .unwrap_or_default(); ret.generate_c(w); w.push(' '); diff --git a/lib/compiler/src/artifact_builders/artifact_builder.rs b/lib/compiler/src/artifact_builders/artifact_builder.rs index aef2db988..098cd0b8f 100644 --- a/lib/compiler/src/artifact_builders/artifact_builder.rs +++ b/lib/compiler/src/artifact_builders/artifact_builder.rs @@ -201,7 +201,7 @@ impl ArtifactCreate for ArtifactBuild { } fn data_initializers(&self) -> &[OwnedDataInitializer] { - &*self.serializable.data_initializers + &self.serializable.data_initializers } fn memory_styles(&self) -> &PrimaryMap { diff --git a/lib/compiler/src/engine/artifact.rs b/lib/compiler/src/engine/artifact.rs index 2608723a0..c3b18a042 100644 --- a/lib/compiler/src/engine/artifact.rs +++ b/lib/compiler/src/engine/artifact.rs @@ -343,7 +343,7 @@ impl Artifact { // Get pointers to where metadata about local tables should live in VM memory. let (allocator, memory_definition_locations, table_definition_locations) = - InstanceAllocator::new(&*module); + InstanceAllocator::new(&module); let finished_memories = tunables .create_memories( context, @@ -400,7 +400,7 @@ impl Artifact { .iter() .map(|init| DataInitializer { location: init.location.clone(), - data: &*init.data, + data: &init.data, }) .collect::>(); handle diff --git a/lib/emscripten/src/lib.rs b/lib/emscripten/src/lib.rs index 1e4b7af80..216171e35 100644 --- a/lib/emscripten/src/lib.rs +++ b/lib/emscripten/src/lib.rs @@ -105,7 +105,7 @@ impl EmEnv { /// Get a reference to the memory pub fn memory(&self, _mem_idx: u32) -> Memory { - (&*self.memory.read().unwrap()).as_ref().cloned().unwrap() + (*self.memory.read().unwrap()).as_ref().cloned().unwrap() } pub fn set_functions(&mut self, funcs: EmscriptenFunctions) { diff --git a/lib/types/src/error.rs b/lib/types/src/error.rs index 0e0a1eb12..7063b36ae 100644 --- a/lib/types/src/error.rs +++ b/lib/types/src/error.rs @@ -38,7 +38,7 @@ pub enum DeserializeError { } /// Error type describing things that can go wrong when operating on Wasm Memories. -#[derive(Error, Debug, Clone, PartialEq, Hash)] +#[derive(Error, Debug, Clone, Eq, PartialEq, Hash)] pub enum MemoryError { /// Low level error with mmap. #[error("Error when allocating memory: {0}")] diff --git a/lib/types/src/serialize.rs b/lib/types/src/serialize.rs index 4bf7bfac0..7df4fca9b 100644 --- a/lib/types/src/serialize.rs +++ b/lib/types/src/serialize.rs @@ -144,7 +144,7 @@ impl SerializableModule { /// Returns data initializers to pass to `InstanceHandle::initialize` pub fn data_initializers(&self) -> &[OwnedDataInitializer] { - &*self.data_initializers + &self.data_initializers } /// Returns the memory styles associated with this `Artifact`. diff --git a/lib/vm/src/instance/mod.rs b/lib/vm/src/instance/mod.rs index c91a8f63f..0f189a75e 100644 --- a/lib/vm/src/instance/mod.rs +++ b/lib/vm/src/instance/mod.rs @@ -116,7 +116,7 @@ impl Instance { } pub(crate) fn module_ref(&self) -> &ModuleInfo { - &*self.module + &self.module } fn context(&self) -> &StoreObjects { @@ -868,7 +868,7 @@ impl InstanceHandle { let instance = instance_handle.instance_mut(); let vmctx_ptr = instance.vmctx_ptr(); (instance.funcrefs, instance.imported_funcrefs) = build_funcrefs( - &*instance.module, + &instance.module, context, &imports, &instance.functions, diff --git a/lib/vm/src/libcalls.rs b/lib/vm/src/libcalls.rs index f9b1b2870..9274237f1 100644 --- a/lib/vm/src/libcalls.rs +++ b/lib/vm/src/libcalls.rs @@ -189,7 +189,7 @@ pub unsafe extern "C" fn wasmer_vm_imported_memory32_grow( /// `vmctx` must be dereferenceable. #[no_mangle] pub unsafe extern "C" fn wasmer_vm_memory32_size(vmctx: *mut VMContext, memory_index: u32) -> u32 { - let instance = (&*vmctx).instance(); + let instance = (*vmctx).instance(); let memory_index = LocalMemoryIndex::from_u32(memory_index); instance.memory_size(memory_index).0 @@ -205,7 +205,7 @@ pub unsafe extern "C" fn wasmer_vm_imported_memory32_size( vmctx: *mut VMContext, memory_index: u32, ) -> u32 { - let instance = (&*vmctx).instance(); + let instance = (*vmctx).instance(); let memory_index = MemoryIndex::from_u32(memory_index); instance.imported_memory_size(memory_index).0 @@ -303,7 +303,7 @@ pub unsafe extern "C" fn wasmer_vm_table_fill( /// `vmctx` must be dereferenceable. #[no_mangle] pub unsafe extern "C" fn wasmer_vm_table_size(vmctx: *mut VMContext, table_index: u32) -> u32 { - let instance = (&*vmctx).instance(); + let instance = (*vmctx).instance(); let table_index = LocalTableIndex::from_u32(table_index); instance.table_size(table_index) @@ -319,7 +319,7 @@ pub unsafe extern "C" fn wasmer_vm_imported_table_size( vmctx: *mut VMContext, table_index: u32, ) -> u32 { - let instance = (&*vmctx).instance(); + let instance = (*vmctx).instance(); let table_index = TableIndex::from_u32(table_index); instance.imported_table_size(table_index) @@ -336,7 +336,7 @@ pub unsafe extern "C" fn wasmer_vm_table_get( table_index: u32, elem_index: u32, ) -> RawTableElement { - let instance = (&*vmctx).instance(); + let instance = (*vmctx).instance(); let table_index = LocalTableIndex::from_u32(table_index); // TODO: type checking, maybe have specialized accessors @@ -495,7 +495,7 @@ pub unsafe extern "C" fn wasmer_vm_func_ref( vmctx: *mut VMContext, function_index: u32, ) -> VMFuncRef { - let instance = (&*vmctx).instance(); + let instance = (*vmctx).instance(); let function_index = FunctionIndex::from_u32(function_index); instance.func_ref(function_index).unwrap() @@ -510,7 +510,7 @@ pub unsafe extern "C" fn wasmer_vm_func_ref( pub unsafe extern "C" fn wasmer_vm_elem_drop(vmctx: *mut VMContext, elem_index: u32) { on_host_stack(|| { let elem_index = ElemIndex::from_u32(elem_index); - let instance = (&*vmctx).instance(); + let instance = (*vmctx).instance(); instance.elem_drop(elem_index); }) } @@ -530,7 +530,7 @@ pub unsafe extern "C" fn wasmer_vm_memory32_copy( ) { let result = { let memory_index = LocalMemoryIndex::from_u32(memory_index); - let instance = (&*vmctx).instance(); + let instance = (*vmctx).instance(); instance.local_memory_copy(memory_index, dst, src, len) }; if let Err(trap) = result { @@ -553,7 +553,7 @@ pub unsafe extern "C" fn wasmer_vm_imported_memory32_copy( ) { let result = { let memory_index = MemoryIndex::from_u32(memory_index); - let instance = (&*vmctx).instance(); + let instance = (*vmctx).instance(); instance.imported_memory_copy(memory_index, dst, src, len) }; if let Err(trap) = result { @@ -576,7 +576,7 @@ pub unsafe extern "C" fn wasmer_vm_memory32_fill( ) { let result = { let memory_index = LocalMemoryIndex::from_u32(memory_index); - let instance = (&*vmctx).instance(); + let instance = (*vmctx).instance(); instance.local_memory_fill(memory_index, dst, val, len) }; if let Err(trap) = result { @@ -599,7 +599,7 @@ pub unsafe extern "C" fn wasmer_vm_imported_memory32_fill( ) { let result = { let memory_index = MemoryIndex::from_u32(memory_index); - let instance = (&*vmctx).instance(); + let instance = (*vmctx).instance(); instance.imported_memory_fill(memory_index, dst, val, len) }; if let Err(trap) = result { @@ -624,7 +624,7 @@ pub unsafe extern "C" fn wasmer_vm_memory32_init( let result = { let memory_index = MemoryIndex::from_u32(memory_index); let data_index = DataIndex::from_u32(data_index); - let instance = (&*vmctx).instance(); + let instance = (*vmctx).instance(); instance.memory_init(memory_index, data_index, dst, src, len) }; if let Err(trap) = result { @@ -641,7 +641,7 @@ pub unsafe extern "C" fn wasmer_vm_memory32_init( pub unsafe extern "C" fn wasmer_vm_data_drop(vmctx: *mut VMContext, data_index: u32) { on_host_stack(|| { let data_index = DataIndex::from_u32(data_index); - let instance = (&*vmctx).instance(); + let instance = (*vmctx).instance(); instance.data_drop(data_index) }) } diff --git a/lib/wasi/src/syscalls/mod.rs b/lib/wasi/src/syscalls/mod.rs index 0c5266e6e..e972946c0 100644 --- a/lib/wasi/src/syscalls/mod.rs +++ b/lib/wasi/src/syscalls/mod.rs @@ -307,7 +307,7 @@ pub fn args_get( let env = ctx.data(); let (memory, mut state) = env.get_memory_and_wasi_state(&ctx, 0); - let result = write_buffer_array(&memory, &*state.args, argv, argv_buf); + let result = write_buffer_array(&memory, &state.args, argv, argv_buf); debug!( "=> args:\n{}", @@ -433,7 +433,7 @@ pub fn environ_get( let (memory, mut state) = env.get_memory_and_wasi_state(&ctx, 0); trace!(" -> State envs: {:?}", state.envs); - write_buffer_array(&memory, &*state.envs, environ, environ_buf) + write_buffer_array(&memory, &state.envs, environ, environ_buf) } /// ### `environ_sizes_get()` @@ -5555,7 +5555,7 @@ pub unsafe fn sock_send_file( sock, __WASI_RIGHT_SOCK_SEND, |socket| { - let buf = (&buf[..]).to_vec(); + let buf = (buf[..]).to_vec(); socket.send_bytes::(Bytes::from(buf)) } )); From e64882af8a6a3b698fca4fa375d0b2e3ea58ea78 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Felix=20Sch=C3=BCtt?= Date: Wed, 24 Aug 2022 18:40:53 +0200 Subject: [PATCH 25/45] Fix error in conversion from u128 to f64 in JS bindings --- lib/api/src/js/native_type.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/api/src/js/native_type.rs b/lib/api/src/js/native_type.rs index 23e37c24e..a12a186ce 100644 --- a/lib/api/src/js/native_type.rs +++ b/lib/api/src/js/native_type.rs @@ -127,7 +127,7 @@ impl NativeWasmTypeInto for u128 { #[inline] fn into_raw(self, _store: &mut impl AsStoreMut) -> f64 { - self.into() + self as _ } #[inline] From 63e2046bce974232111bfcf21200ee5568e0daef Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Felix=20Sch=C3=BCtt?= Date: Thu, 25 Aug 2022 12:52:18 +0200 Subject: [PATCH 26/45] Return DefaultCustomSectionsIterator for custom_sections --- lib/api/src/js/module.rs | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/lib/api/src/js/module.rs b/lib/api/src/js/module.rs index fc08967d0..e5f207151 100644 --- a/lib/api/src/js/module.rs +++ b/lib/api/src/js/module.rs @@ -560,7 +560,16 @@ impl Module { /// is returned. pub fn custom_sections<'a>(&'a self, name: &'a str) -> impl Iterator> + 'a { // TODO: implement on JavaScript - unimplemented!() + DefaultCustomSectionsIterator { } + } +} + +pub struct DefaultCustomSectionsIterator { } + +impl Iterator for DefaultCustomSectionsIterator { + type Item = Box<[u8]>; + fn next(&mut self) -> Option { + None } } From 42cbe141fcf98d1811a9bfbbf2284c79badc2da2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Felix=20Sch=C3=BCtt?= Date: Thu, 25 Aug 2022 13:11:36 +0200 Subject: [PATCH 27/45] Fix to_vm_extern function in JS --- lib/api/src/js/externals/function.rs | 8 ++++---- lib/api/src/js/externals/global.rs | 7 ++++++- lib/api/src/js/externals/memory.rs | 7 ++++++- lib/api/src/sys/externals/function.rs | 10 +++++----- 4 files changed, 21 insertions(+), 11 deletions(-) diff --git a/lib/api/src/js/externals/function.rs b/lib/api/src/js/externals/function.rs index a8a8bea24..1a85ad83b 100644 --- a/lib/api/src/js/externals/function.rs +++ b/lib/api/src/js/externals/function.rs @@ -908,7 +908,7 @@ mod inner { Kind: HostFunctionKind, { /// Get the pointer to the function body. - fn function_body_ptr() -> *const VMFunctionBody; + fn function_body_ptr(self) -> *const VMFunctionBody; // /// Get the pointer to the function call trampoline. // fn call_trampoline_address() -> VMTrampoline; @@ -969,7 +969,7 @@ mod inner { T: Sized, { Self { - address: >::function_body_ptr(), + address: function.function_body_ptr(), _phantom: PhantomData, } } @@ -1122,7 +1122,7 @@ mod inner { Func: Fn(FunctionEnvMut<'_, T>, $( $x , )*) -> RetsAsResult + 'static, { #[allow(non_snake_case)] - fn function_body_ptr() -> *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. @@ -1170,7 +1170,7 @@ mod inner { Func: Fn($( $x , )*) -> RetsAsResult + 'static, { #[allow(non_snake_case)] - fn function_body_ptr() -> *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. diff --git a/lib/api/src/js/externals/global.rs b/lib/api/src/js/externals/global.rs index 2892c1624..38e8ef6ac 100644 --- a/lib/api/src/js/externals/global.rs +++ b/lib/api/src/js/externals/global.rs @@ -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; @@ -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, diff --git a/lib/api/src/js/externals/memory.rs b/lib/api/src/js/externals/memory.rs index bfddab87f..b57639b48 100644 --- a/lib/api/src/js/externals/memory.rs +++ b/lib/api/src/js/externals/memory.rs @@ -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; @@ -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 diff --git a/lib/api/src/sys/externals/function.rs b/lib/api/src/sys/externals/function.rs index 87bfa8237..835eea097 100644 --- a/lib/api/src/sys/externals/function.rs +++ b/lib/api/src/sys/externals/function.rs @@ -204,6 +204,7 @@ impl Function { Rets: WasmTypeList, { let env = FunctionEnv::new(store, ()); + let func_ptr = func.function_body_ptr(); let host_data = Box::new(StaticFunction { raw_store: store.as_store_mut().as_raw() as *mut u8, env, @@ -211,7 +212,6 @@ impl Function { }); let function_type = FunctionType::new(Args::wasm_types(), Rets::wasm_types()); - let func_ptr = >::function_body_ptr(); let type_index = store .as_store_mut() .engine() @@ -289,6 +289,7 @@ impl Function { { // println!("new native {:p}", &new_env); + let func_ptr = func.function_body_ptr(); let host_data = Box::new(StaticFunction { raw_store: store.as_store_mut().as_raw() as *mut u8, env: env.clone(), @@ -296,7 +297,6 @@ impl Function { }); let function_type = FunctionType::new(Args::wasm_types(), Rets::wasm_types()); - let func_ptr = >::function_body_ptr(); let type_index = store .as_store_mut() .engine() @@ -1092,7 +1092,7 @@ mod inner { Kind: HostFunctionKind, { /// Get the pointer to the function body. - fn function_body_ptr() -> *const VMFunctionBody; + fn function_body_ptr(self) -> *const VMFunctionBody; /// Get the pointer to the function call trampoline. fn call_trampoline_address() -> VMTrampoline; @@ -1268,7 +1268,7 @@ mod inner { Func: Fn(FunctionEnvMut, $( $x , )*) -> RetsAsResult + 'static, { #[allow(non_snake_case)] - fn function_body_ptr() -> *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. @@ -1352,7 +1352,7 @@ mod inner { Func: Fn($( $x , )*) -> RetsAsResult + 'static, { #[allow(non_snake_case)] - fn function_body_ptr() -> *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. From e0911a4fe61c3851b4be77194731b4c18d549aca Mon Sep 17 00:00:00 2001 From: Syrus Akbary Date: Thu, 25 Aug 2022 17:34:32 +0200 Subject: [PATCH 28/45] Added new_from_js_object method to the Imports object --- lib/api/src/js/imports.rs | 50 ++++++++++++++++++++++++++++++-- lib/api/tests/js_instance.rs | 55 ++++++++++++++++++++++++++++++++++++ 2 files changed, 103 insertions(+), 2 deletions(-) diff --git a/lib/api/src/js/imports.rs b/lib/api/src/js/imports.rs index 63a199abb..4c98e38a0 100644 --- a/lib/api/src/js/imports.rs +++ b/lib/api/src/js/imports.rs @@ -1,11 +1,13 @@ //! The import module contains the implementation data structures and helper functions used to //! manipulate and access a wasm module's imports including memories, tables, globals, and //! functions. -use crate::js::error::InstantiationError; +use crate::js::error::{InstantiationError, WasmError}; +use crate::js::export::Export; use crate::js::exports::Exports; use crate::js::module::Module; -use crate::js::store::AsStoreRef; +use crate::js::store::{AsStoreMut, AsStoreRef}; use crate::js::types::AsJs; +use crate::js::ExternType; use crate::Extern; use std::collections::HashMap; use std::fmt; @@ -179,6 +181,50 @@ impl Imports { pub fn iter<'a>(&'a self) -> ImportsIterator<'a> { ImportsIterator::new(self) } + + /// Create a new `Imports` from a JS Object, it receives a reference to a `Module` to + /// map and assign the types of each import and the JS Object + /// that contains the values of imports. + /// + /// # Usage + /// ```ignore + /// let import_object = Imports::new_from_js_object(&mut store, &module, js_object); + /// ``` + pub fn new_from_js_object( + store: &mut impl AsStoreMut, + module: &Module, + object: js_sys::Object, + ) -> Result { + let module_imports: HashMap<(String, String), ExternType> = module + .imports() + .map(|import| { + ( + (import.module().to_string(), import.name().to_string()), + import.ty().clone(), + ) + }) + .collect::>(); + + let mut map: HashMap<(String, String), Extern> = HashMap::new(); + + for module_entry in js_sys::Object::entries(&object).iter() { + let module_entry: js_sys::Array = module_entry.into(); + let module_name = module_entry.get(0).as_string().unwrap().to_string(); + let module_import_object: js_sys::Object = module_entry.get(1).into(); + for import_entry in js_sys::Object::entries(&module_import_object).iter() { + let import_entry: js_sys::Array = import_entry.into(); + let import_name = import_entry.get(0).as_string().unwrap().to_string(); + let import_js: wasm_bindgen::JsValue = import_entry.get(1); + let key = (module_name.clone(), import_name); + let extern_type = module_imports.get(&key).unwrap(); + let export = Export::from_js_value(import_js, store, extern_type.clone())?; + let extern_ = Extern::from_vm_extern(store, export); + map.insert(key, extern_); + } + } + + Ok(Self { map }) + } } pub struct ImportsIterator<'a> { diff --git a/lib/api/tests/js_instance.rs b/lib/api/tests/js_instance.rs index 4b829ab81..26e1054e6 100644 --- a/lib/api/tests/js_instance.rs +++ b/lib/api/tests/js_instance.rs @@ -92,6 +92,61 @@ mod js { assert_eq!(get_magic.call(&mut store, &[]).unwrap(), expected); } + #[wasm_bindgen_test] + fn test_imports_from_js_object() { + let mut store = Store::default(); + let mut module = Module::new( + &store, + br#" + (module + (func $imported (import "env" "imported") (param i32) (result i32)) + (func (export "exported") (param i32) (result i32) + (call $imported (local.get 0)) + ) + ) + "#, + ) + .unwrap(); + module + .set_type_hints(ModuleTypeHints { + imports: vec![ExternType::Function(FunctionType::new( + vec![Type::I32], + vec![Type::I32], + ))], + exports: vec![ExternType::Function(FunctionType::new( + vec![Type::I32], + vec![Type::I32], + ))], + }) + .unwrap(); + + let obj: js_sys::Object = js_sys::Function::new_with_args( + "", + "return { + \"env\": { + \"imported\": function(num) { + console.log(\"Calling `imported`...\"); + var result = num * 2; + console.log(\"Result of `imported`: \", result); + return result; + } + } + };", + ) + .call0(&wasm_bindgen::JsValue::UNDEFINED) + .unwrap() + .into(); + + let import_object = Imports::new_from_js_object(&mut store, &module, obj) + .expect("Can't get imports from js object"); + let instance = Instance::new(&mut store, &module, &import_object).unwrap(); + + let exported = instance.exports.get_function("exported").unwrap(); + + let expected = vec![Val::I32(6)].into_boxed_slice(); + assert_eq!(exported.call(&mut store, &[Val::I32(3)]).unwrap(), expected); + } + #[wasm_bindgen_test] fn test_imported_function_dynamic() { let mut store = Store::default(); From b122feeb837427dbfa47db69dd702b58f4422c7e Mon Sep 17 00:00:00 2001 From: Syrus Akbary Date: Thu, 25 Aug 2022 17:35:29 +0200 Subject: [PATCH 29/45] Removed deprecated JsImportObject --- lib/api/src/js/js_import_object.rs | 83 ------------------------------ lib/api/src/js/mod.rs | 2 - 2 files changed, 85 deletions(-) delete mode 100644 lib/api/src/js/js_import_object.rs diff --git a/lib/api/src/js/js_import_object.rs b/lib/api/src/js/js_import_object.rs deleted file mode 100644 index 1370d8bd3..000000000 --- a/lib/api/src/js/js_import_object.rs +++ /dev/null @@ -1,83 +0,0 @@ -use crate::js::error::WasmError; -use crate::js::store::AsStoreMut; -use crate::js::{Export, ExternType, Module}; -use std::collections::HashMap; - -/// This struct is used in case you want to create an `Instance` -/// of a `Module` with imports that are provided directly from -/// Javascript with a JS Object. -#[derive(Clone, Default)] -pub struct JsImportObject { - module_imports: HashMap<(String, String), ExternType>, - object: js_sys::Object, -} - -/// JS Objects with wasm-bindgen are not currently Send/Sync (although they -/// are in Javascript, since we can use them safely between webworkers). -unsafe impl Send for JsImportObject {} -unsafe impl Sync for JsImportObject {} - -impl JsImportObject { - /// Create a new `JsImportObject`, it receives a reference to a `Module` to - /// map and assign the types of each import and the JS Object - /// that contains the values of imports. - /// - /// # Usage - /// ```ignore - /// # use wasmer::JsImportObject; - /// let import_object = JsImportObject::new(&module, js_object); - /// ``` - pub fn new(module: &Module, object: js_sys::Object) -> Self { - let module_imports = module - .imports() - .map(|import| { - ( - (import.module().to_string(), import.name().to_string()), - import.ty().clone(), - ) - }) - .collect::>(); - Self { - module_imports, - object, - } - } - - /// Gets an export given a module and a name - /// - /// # Usage - /// ```ignore - /// # use wasmer::JsImportObject; - /// let import_object = JsImportObject::new(&module, js_object); - /// import_object.get_export("module", "name"); - /// ``` - pub fn get_export( - &self, - store: &mut impl AsStoreMut, - module: &str, - name: &str, - ) -> Result { - let namespace = js_sys::Reflect::get(&self.object, &module.into())?; - let js_export = js_sys::Reflect::get(&namespace, &name.into())?; - match self - .module_imports - .get(&(module.to_string(), name.to_string())) - { - Some(extern_type) => Ok(Export::from_js_value( - js_export, - store, - extern_type.clone(), - )?), - None => Err(WasmError::Generic(format!( - "Name {} not found in module {}", - name, module - ))), - } - } -} - -impl Into for JsImportObject { - fn into(self) -> js_sys::Object { - self.object - } -} diff --git a/lib/api/src/js/mod.rs b/lib/api/src/js/mod.rs index 1e660a530..a642e14b5 100644 --- a/lib/api/src/js/mod.rs +++ b/lib/api/src/js/mod.rs @@ -30,7 +30,6 @@ mod externals; mod function_env; mod imports; mod instance; -mod js_import_object; mod mem_access; mod module; #[cfg(feature = "wasm-types-polyfill")] @@ -54,7 +53,6 @@ pub use crate::js::externals::{ pub use crate::js::function_env::{FunctionEnv, FunctionEnvMut}; pub use crate::js::imports::Imports; pub use crate::js::instance::Instance; -pub use crate::js::js_import_object::JsImportObject; pub use crate::js::mem_access::{MemoryAccessError, WasmRef, WasmSlice, WasmSliceIter}; pub use crate::js::module::{Module, ModuleTypeHints}; pub use crate::js::native::TypedFunction; From 1912373e1f5916c29adfb604b7dabf8b69c858e8 Mon Sep 17 00:00:00 2001 From: ptitSeb Date: Fri, 26 Aug 2022 10:46:56 +0200 Subject: [PATCH 30/45] The API breaking changes from future WASIX/Network/Threading addition --- Cargo.lock | 1 + docs/migration_to_3.0.0.md | 5 +- lib/api/Cargo.toml | 1 + lib/api/src/js/module.rs | 81 ++++++++++++++++++++++++------ lib/api/src/js/ptr.rs | 2 +- lib/api/src/lib.rs | 2 +- lib/api/src/sys/function_env.rs | 7 ++- lib/api/src/sys/module.rs | 86 +++++++++++++++++++++++++------- lib/api/src/sys/ptr.rs | 2 +- lib/cli/src/commands/inspect.rs | 15 ++---- lib/cli/src/commands/run.rs | 4 +- lib/cli/src/commands/validate.rs | 2 +- lib/wasi/src/lib.rs | 33 +++++++++++- tests/compilers/imports.rs | 6 +-- tests/compilers/traps.rs | 10 ++-- tests/lib/wast/src/wasi_wast.rs | 2 +- 16 files changed, 197 insertions(+), 62 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 69a3e6b50..8867bdf38 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2923,6 +2923,7 @@ name = "wasmer" version = "3.0.0-beta" dependencies = [ "anyhow", + "bytes", "cfg-if 1.0.0", "hashbrown 0.11.2", "indexmap", diff --git a/docs/migration_to_3.0.0.md b/docs/migration_to_3.0.0.md index c115578cd..02a613c67 100644 --- a/docs/migration_to_3.0.0.md +++ b/docs/migration_to_3.0.0.md @@ -195,14 +195,13 @@ import_object.define("env", "host_function", host_function); let instance = Instance::new(&mut store, &module, &import_object).expect("Could not instantiate module."); ``` -For WASI, don't forget to import memory to `WasiEnv` +For WASI, don't forget to initialize the `WasiEnv` (it will import the memory) ```rust let mut wasi_env = WasiState::new("hello").finalize()?; let import_object = wasi_env.import_object(&mut store, &module)?; let instance = Instance::new(&mut store, &module, &import_object).expect("Could not instantiate module."); -let memory = instance.exports.get_memory("memory")?; -wasi_env.data_mut(&mut store).set_memory(memory.clone()); +wasi_env.initialize(&mut store, &instance).unwrap(); ``` #### `ChainableNamedResolver` is removed diff --git a/lib/api/Cargo.toml b/lib/api/Cargo.toml index 36a6fb7ea..9bcb2c9b0 100644 --- a/lib/api/Cargo.toml +++ b/lib/api/Cargo.toml @@ -26,6 +26,7 @@ indexmap = { version = "1.6" } cfg-if = "1.0" thiserror = "1.0" more-asserts = "0.2" +bytes = "1" # - Optional shared dependencies. wat = { version = "1.0", optional = true } tracing = { version = "0.1", optional = true } diff --git a/lib/api/src/js/module.rs b/lib/api/src/js/module.rs index 975d1bee5..7a614ee75 100644 --- a/lib/api/src/js/module.rs +++ b/lib/api/src/js/module.rs @@ -9,7 +9,9 @@ use crate::js::store::{AsStoreMut, StoreHandle}; use crate::js::types::{AsJs, ExportType, ImportType}; use crate::js::RuntimeError; use crate::AsStoreRef; +use bytes::Bytes; use js_sys::{Reflect, Uint8Array, WebAssembly}; +use std::borrow::Cow; use std::fmt; use std::io; use std::path::Path; @@ -49,6 +51,46 @@ pub struct ModuleTypeHints { pub exports: Vec, } +pub trait IntoBytes { + fn into_bytes(self) -> Bytes; +} + +impl IntoBytes for Bytes { + fn into_bytes(self) -> Bytes { + self + } +} + +impl IntoBytes for Vec { + fn into_bytes(self) -> Bytes { + Bytes::from(self) + } +} + +impl IntoBytes for &[u8] { + fn into_bytes(self) -> Bytes { + Bytes::from(self.to_vec()) + } +} + +impl IntoBytes for &[u8; N] { + fn into_bytes(self) -> Bytes { + Bytes::from(self.to_vec()) + } +} + +impl IntoBytes for &str { + fn into_bytes(self) -> Bytes { + Bytes::from(self.as_bytes().to_vec()) + } +} + +impl IntoBytes for Cow<'_, [u8]> { + fn into_bytes(self) -> Bytes { + Bytes::from(self.to_vec()) + } +} + /// A WebAssembly Module contains stateless WebAssembly /// code that has already been compiled and can be instantiated /// multiple times. @@ -128,15 +170,19 @@ impl Module { /// # } /// ``` #[allow(unreachable_code)] - pub fn new(_store: &impl AsStoreRef, bytes: impl AsRef<[u8]>) -> Result { + pub fn new(_store: &impl AsStoreRef, bytes: impl IntoBytes) -> Result { + let mut bytes = bytes.into_bytes(); #[cfg(feature = "wat")] - let bytes = wat::parse_bytes(bytes.as_ref()).map_err(|e| { - CompileError::Wasm(WasmError::Generic(format!( - "Error when converting wat: {}", - e - ))) - })?; - Self::from_binary(_store, bytes.as_ref()) + if bytes.starts_with(b"\0asm") == false { + let parsed_bytes = wat::parse_bytes(bytes.as_ref()).map_err(|e| { + CompileError::Wasm(WasmError::Generic(format!( + "Error when converting wat: {}", + e + ))) + })?; + bytes = Bytes::from(parsed_bytes.to_vec()); + } + Self::from_binary(_store, bytes) } /// Creates a new WebAssembly module from a file path. @@ -152,7 +198,11 @@ impl Module { /// Opposed to [`Module::new`], this function is not compatible with /// the WebAssembly text format (if the "wat" feature is enabled for /// this crate). - pub fn from_binary(_store: &impl AsStoreRef, binary: &[u8]) -> Result { + pub fn from_binary( + _store: &impl AsStoreRef, + binary: impl IntoBytes, + ) -> Result { + let binary = binary.into_bytes(); // // Self::validate(store, binary)?; unsafe { Self::from_binary_unchecked(_store, binary) } @@ -166,9 +216,10 @@ impl Module { /// We maintain the `unsafe` to preserve the same API as Wasmer pub unsafe fn from_binary_unchecked( _store: &impl AsStoreRef, - binary: &[u8], + binary: impl IntoBytes, ) -> Result { - let js_bytes = Uint8Array::view(binary); + let binary = binary.into_bytes(); + let js_bytes = Uint8Array::view(&binary[..]); let module = WebAssembly::Module::new(&js_bytes.into()).unwrap(); // The module is now validated, so we can safely parse it's types @@ -210,8 +261,9 @@ impl Module { /// This validation is normally pretty fast and checks the enabled /// WebAssembly features in the Store Engine to assure deterministic /// validation of the Module. - pub fn validate(_store: &impl AsStoreRef, binary: &[u8]) -> Result<(), CompileError> { - let js_bytes = unsafe { Uint8Array::view(binary) }; + pub fn validate(_store: &impl AsStoreRef, binary: impl IntoBytes) -> Result<(), CompileError> { + let binary = binary.into_bytes(); + let js_bytes = unsafe { Uint8Array::view(&binary[..]) }; match WebAssembly::validate(&js_bytes.into()) { Ok(true) => Ok(()), _ => Err(CompileError::Validate("Invalid Wasm file".to_owned())), @@ -313,8 +365,9 @@ impl Module { #[cfg(feature = "js-serializable-module")] pub unsafe fn deserialize( _store: &impl AsStoreRef, - bytes: &[u8], + bytes: impl IntoBytes, ) -> Result { + let bytes = bytes.into_bytes(); Self::new(_store, bytes).map_err(|e| DeserializeError::Compiler(e)) } diff --git a/lib/api/src/js/ptr.rs b/lib/api/src/js/ptr.rs index b7b812c43..cdcb19f1f 100644 --- a/lib/api/src/js/ptr.rs +++ b/lib/api/src/js/ptr.rs @@ -71,7 +71,7 @@ impl WasmPtr { /// Get the offset into Wasm linear memory for this `WasmPtr`. #[inline] - pub fn offset(self) -> M::Offset { + pub fn offset(&self) -> M::Offset { self.offset } diff --git a/lib/api/src/lib.rs b/lib/api/src/lib.rs index 663903104..ccb647175 100644 --- a/lib/api/src/lib.rs +++ b/lib/api/src/lib.rs @@ -55,7 +55,7 @@ //! "#; //! //! let mut store = Store::default(); -//! let module = Module::new(&store, &module_wat)?; +//! let module = Module::new(&store, module_wat)?; //! // The module doesn't import anything, so we create an empty import object. //! let import_object = imports! {}; //! let instance = Instance::new(&mut store, &module, &import_object)?; diff --git a/lib/api/src/sys/function_env.rs b/lib/api/src/sys/function_env.rs index deb5c0b43..6ef7b48a3 100644 --- a/lib/api/src/sys/function_env.rs +++ b/lib/api/src/sys/function_env.rs @@ -29,7 +29,7 @@ impl FunctionEnv { } /// Get the data as reference - pub fn as_ref<'a>(&self, store: &'a impl AsStoreMut) -> &'a T + pub fn as_ref<'a>(&self, store: &'a impl AsStoreRef) -> &'a T where T: Any + Send + 'static + Sized, { @@ -105,6 +105,11 @@ impl FunctionEnvMut<'_, T> { self.func_env.as_mut(&mut self.store_mut) } + /// Borrows a new immmutable reference + pub fn as_ref(&self) -> FunctionEnv { + self.func_env.clone() + } + /// Borrows a new mutable reference pub fn as_mut(&mut self) -> FunctionEnvMut<'_, T> { FunctionEnvMut { diff --git a/lib/api/src/sys/module.rs b/lib/api/src/sys/module.rs index b730a19b9..72f1b414a 100644 --- a/lib/api/src/sys/module.rs +++ b/lib/api/src/sys/module.rs @@ -1,6 +1,8 @@ use crate::sys::InstantiationError; use crate::AsStoreMut; use crate::AsStoreRef; +use bytes::Bytes; +use std::borrow::Cow; use std::fmt; use std::io; use std::path::Path; @@ -54,6 +56,46 @@ pub struct Module { module_info: Arc, } +pub trait IntoBytes { + fn into_bytes(self) -> Bytes; +} + +impl IntoBytes for Bytes { + fn into_bytes(self) -> Bytes { + self + } +} + +impl IntoBytes for Vec { + fn into_bytes(self) -> Bytes { + Bytes::from(self) + } +} + +impl IntoBytes for &[u8] { + fn into_bytes(self) -> Bytes { + Bytes::from(self.to_vec()) + } +} + +impl IntoBytes for &[u8; N] { + fn into_bytes(self) -> Bytes { + Bytes::from(self.to_vec()) + } +} + +impl IntoBytes for &str { + fn into_bytes(self) -> Bytes { + Bytes::from(self.as_bytes().to_vec()) + } +} + +impl IntoBytes for Cow<'_, [u8]> { + fn into_bytes(self) -> Bytes { + Bytes::from(self.to_vec()) + } +} + impl Module { #[cfg(feature = "compiler")] /// Creates a new WebAssembly Module given the configuration @@ -116,16 +158,19 @@ impl Module { /// # } /// ``` #[allow(unreachable_code)] - pub fn new(store: &impl AsStoreRef, bytes: impl AsRef<[u8]>) -> Result { + pub fn new(store: &impl AsStoreRef, bytes: impl IntoBytes) -> Result { + let mut bytes = bytes.into_bytes(); #[cfg(feature = "wat")] - let bytes = wat::parse_bytes(bytes.as_ref()).map_err(|e| { - CompileError::Wasm(WasmError::Generic(format!( - "Error when converting wat: {}", - e - ))) - })?; - - Self::from_binary(store, bytes.as_ref()) + if !bytes.starts_with(b"\0asm") { + let parsed_bytes = wat::parse_bytes(&bytes[..]).map_err(|e| { + CompileError::Wasm(WasmError::Generic(format!( + "Error when converting wat: {}", + e + ))) + })?; + bytes = Bytes::from(parsed_bytes.to_vec()); + } + Self::from_binary(store, bytes) } #[cfg(feature = "compiler")] @@ -137,7 +182,7 @@ impl Module { let file_ref = file.as_ref(); let canonical = file_ref.canonicalize()?; let wasm_bytes = std::fs::read(file_ref)?; - let mut module = Self::new(store, &wasm_bytes)?; + let mut module = Self::new(store, wasm_bytes)?; // Set the module name to the absolute path of the filename. // This is useful for debugging the stack traces. let filename = canonical.as_path().to_str().unwrap(); @@ -151,8 +196,12 @@ impl Module { /// Opposed to [`Module::new`], this function is not compatible with /// the WebAssembly text format (if the "wat" feature is enabled for /// this crate). - pub fn from_binary(store: &impl AsStoreRef, binary: &[u8]) -> Result { - Self::validate(store, binary)?; + pub fn from_binary( + store: &impl AsStoreRef, + binary: impl IntoBytes, + ) -> Result { + let binary = binary.into_bytes(); + Self::validate(store, binary.clone())?; unsafe { Self::from_binary_unchecked(store, binary) } } @@ -166,8 +215,9 @@ impl Module { /// beforehand. pub unsafe fn from_binary_unchecked( store: &impl AsStoreRef, - binary: &[u8], + binary: impl IntoBytes, ) -> Result { + let binary = binary.into_bytes(); let module = Self::compile(store, binary)?; Ok(module) } @@ -179,16 +229,18 @@ impl Module { /// This validation is normally pretty fast and checks the enabled /// WebAssembly features in the Store Engine to assure deterministic /// validation of the Module. - pub fn validate(store: &impl AsStoreRef, binary: &[u8]) -> Result<(), CompileError> { - store.as_store_ref().engine().validate(binary) + pub fn validate(store: &impl AsStoreRef, binary: impl IntoBytes) -> Result<(), CompileError> { + let binary = binary.into_bytes(); + store.as_store_ref().engine().validate(&binary[..]) } #[cfg(feature = "compiler")] - fn compile(store: &impl AsStoreRef, binary: &[u8]) -> Result { + fn compile(store: &impl AsStoreRef, binary: impl IntoBytes) -> Result { + let binary = binary.into_bytes(); let artifact = store .as_store_ref() .engine() - .compile(binary, store.as_store_ref().tunables())?; + .compile(&binary[..], store.as_store_ref().tunables())?; Ok(Self::from_artifact(artifact)) } diff --git a/lib/api/src/sys/ptr.rs b/lib/api/src/sys/ptr.rs index f14383946..1f51c2030 100644 --- a/lib/api/src/sys/ptr.rs +++ b/lib/api/src/sys/ptr.rs @@ -76,7 +76,7 @@ impl WasmPtr { /// Get the offset into Wasm linear memory for this `WasmPtr`. #[inline] - pub fn offset(self) -> M::Offset { + pub fn offset(&self) -> M::Offset { self.offset } diff --git a/lib/cli/src/commands/inspect.rs b/lib/cli/src/commands/inspect.rs index b21b96bbb..4d56faa61 100644 --- a/lib/cli/src/commands/inspect.rs +++ b/lib/cli/src/commands/inspect.rs @@ -25,16 +25,11 @@ impl Inspect { fn inner_execute(&self) -> Result<()> { let (store, _compiler_type) = self.store.get_store()?; let module_contents = std::fs::read(&self.path)?; - let module = Module::new(&store, &module_contents)?; - println!( - "Type: {}", - if !is_wasm(&module_contents) { - "wat" - } else { - "wasm" - } - ); - println!("Size: {}", ByteSize(module_contents.len() as _)); + let iswasm = is_wasm(&module_contents); + let module_len = module_contents.len(); + let module = Module::new(&store, module_contents)?; + println!("Type: {}", if !iswasm { "wat" } else { "wasm" }); + println!("Size: {}", ByteSize(module_len as _)); println!("Imports:"); println!(" Functions:"); for f in module.imports().functions() { diff --git a/lib/cli/src/commands/run.rs b/lib/cli/src/commands/run.rs index 4c742306e..c6e0fde6e 100644 --- a/lib/cli/src/commands/run.rs +++ b/lib/cli/src/commands/run.rs @@ -272,7 +272,7 @@ impl Run { let module_result: Result = if !self.disable_cache && contents.len() > 0x1000 { self.get_module_from_cache(&store, &contents, &compiler_type) } else { - Module::new(&store, &contents).map_err(|e| e.into()) + Module::new(&store, contents).map_err(|e| e.into()) }; #[cfg(not(feature = "cache"))] let module_result = Module::new(&store, &contents); @@ -319,7 +319,7 @@ impl Run { warning!("cached module is corrupted: {}", err); } } - let module = Module::new(store, &contents)?; + let module = Module::new(store, contents)?; // Store the compiled Module in cache cache.store(hash, &module)?; Ok(module) diff --git a/lib/cli/src/commands/validate.rs b/lib/cli/src/commands/validate.rs index 4f620ecc3..2e1aa59ec 100644 --- a/lib/cli/src/commands/validate.rs +++ b/lib/cli/src/commands/validate.rs @@ -27,7 +27,7 @@ impl Validate { if !is_wasm(&module_contents) { bail!("`wasmer validate` only validates WebAssembly files"); } - Module::validate(&store, &module_contents)?; + Module::validate(&store, module_contents)?; eprintln!("Validation passed for `{}`.", self.path.display()); Ok(()) } diff --git a/lib/wasi/src/lib.rs b/lib/wasi/src/lib.rs index 4daeb25a4..2ad3b767d 100644 --- a/lib/wasi/src/lib.rs +++ b/lib/wasi/src/lib.rs @@ -62,9 +62,11 @@ use wasmer_wasi_types::__WASI_CLOCK_MONOTONIC; use derivative::*; use std::ops::Deref; use thiserror::Error; +use tracing::trace; use wasmer::{ - imports, namespace, AsStoreMut, AsStoreRef, Exports, Function, FunctionEnv, Imports, Memory, - Memory32, MemoryAccessError, MemorySize, MemoryView, Module, TypedFunction, + imports, namespace, AsStoreMut, AsStoreRef, ExportError, Exports, Function, FunctionEnv, + Imports, Instance, Memory, Memory32, MemoryAccessError, MemorySize, MemoryView, Module, + TypedFunction, }; pub use runtime::{ @@ -166,6 +168,33 @@ impl WasiFunctionEnv { self.env.as_mut(store) } + /// Initializes the WasiEnv using the instance exports + /// (this must be executed before attempting to use it) + /// (as the stores can not by themselves be passed between threads we can store the module + /// in a thread-local variables and use it later - for multithreading) + pub fn initialize( + &mut self, + store: &mut impl AsStoreMut, + instance: &Instance, + ) -> Result<(), ExportError> { + // List all the exports and imports + for ns in instance.module().exports() { + //trace!("module::export - {} ({:?})", ns.name(), ns.ty()); + trace!("module::export - {}", ns.name()); + } + for ns in instance.module().imports() { + trace!("module::import - {}::{}", ns.module(), ns.name()); + } + + // First we get the malloc function which if it exists will be used to + // create the pthread_self structure + let memory = instance.exports.get_memory("memory")?.clone(); + let env = self.data_mut(store); + env.set_memory(memory); + + Ok(()) + } + /// Like `import_object` but containing all the WASI versions detected in /// the module. pub fn import_object_for_all_wasi_versions( diff --git a/tests/compilers/imports.rs b/tests/compilers/imports.rs index 60d452ac6..a14273dd4 100644 --- a/tests/compilers/imports.rs +++ b/tests/compilers/imports.rs @@ -40,7 +40,7 @@ fn get_module(store: &Store) -> Result { (start $foo) "#; - let module = Module::new(store, &wat)?; + let module = Module::new(store, wat)?; Ok(module) } @@ -339,7 +339,7 @@ fn static_function_that_fails(config: crate::Config) -> Result<()> { (start $foo) "#; - let module = Module::new(&store, &wat)?; + let module = Module::new(&store, wat)?; let f0 = Function::new_typed(&mut store, || -> Result { Err(RuntimeError::new("oops")) }); @@ -375,7 +375,7 @@ fn get_module2(store: &Store) -> Result { (call 0)) "#; - let module = Module::new(store, &wat)?; + let module = Module::new(store, wat)?; Ok(module) } diff --git a/tests/compilers/traps.rs b/tests/compilers/traps.rs index 5c0e6a20d..6bf18c27f 100644 --- a/tests/compilers/traps.rs +++ b/tests/compilers/traps.rs @@ -262,7 +262,7 @@ fn trap_start_function_import(config: crate::Config) -> Result<()> { ) "#; - let module = Module::new(&store, &binary)?; + let module = Module::new(&store, binary)?; let sig = FunctionType::new(vec![], vec![]); let func = Function::new(&mut store, &sig, |_| Err(RuntimeError::new("user trap"))); let err = Instance::new( @@ -302,7 +302,7 @@ fn rust_panic_import(config: crate::Config) -> Result<()> { ) "#; - let module = Module::new(&store, &binary)?; + let module = Module::new(&store, binary)?; let sig = FunctionType::new(vec![], vec![]); let func = Function::new(&mut store, &sig, |_| panic!("this is a panic")); let f0 = Function::new_typed(&mut store, || panic!("this is another panic")); @@ -347,7 +347,7 @@ fn rust_panic_start_function(config: crate::Config) -> Result<()> { ) "#; - let module = Module::new(&store, &binary)?; + let module = Module::new(&store, binary)?; let sig = FunctionType::new(vec![], vec![]); let func = Function::new(&mut store, &sig, |_| panic!("this is a panic")); let err = panic::catch_unwind(AssertUnwindSafe(|| { @@ -393,7 +393,7 @@ fn mismatched_arguments(config: crate::Config) -> Result<()> { ) "#; - let module = Module::new(&store, &binary)?; + let module = Module::new(&store, binary)?; let instance = Instance::new(&mut store, &module, &imports! {})?; let func: &Function = instance.exports.get("foo")?; assert_eq!( @@ -432,7 +432,7 @@ fn call_signature_mismatch(config: crate::Config) -> Result<()> { ) "#; - let module = Module::new(&store, &binary)?; + let module = Module::new(&store, binary)?; let err = Instance::new(&mut store, &module, &imports! {}) .err() .expect("expected error"); diff --git a/tests/lib/wast/src/wasi_wast.rs b/tests/lib/wast/src/wasi_wast.rs index 6b2e13aac..beb11456c 100644 --- a/tests/lib/wast/src/wasi_wast.rs +++ b/tests/lib/wast/src/wasi_wast.rs @@ -82,7 +82,7 @@ impl<'a> WasiTest<'a> { wasm_module.read_to_end(&mut out)?; out }; - let module = Module::new(store, &wasm_bytes)?; + let module = Module::new(store, wasm_bytes)?; let (env, _tempdirs, stdout_rx, stderr_rx) = self.create_wasi_env(store, filesystem_kind)?; let imports = self.get_imports(store, &env.env, &module)?; From 14ddcfd153c45bb06dfbec7389d7377546e31b96 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Felix=20Sch=C3=BCtt?= Date: Fri, 26 Aug 2022 18:44:25 +0200 Subject: [PATCH 31/45] Fix all errors up to the last one --- lib/api/src/js/error.rs | 4 ++++ lib/api/src/js/imports.rs | 2 +- lib/api/src/js/instance.rs | 29 ++++++----------------------- 3 files changed, 11 insertions(+), 24 deletions(-) diff --git a/lib/api/src/js/error.rs b/lib/api/src/js/error.rs index a999a4235..23df188dc 100644 --- a/lib/api/src/js/error.rs +++ b/lib/api/src/js/error.rs @@ -199,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 for InstantiationError { diff --git a/lib/api/src/js/imports.rs b/lib/api/src/js/imports.rs index 8b4b3ad95..aad247c0c 100644 --- a/lib/api/src/js/imports.rs +++ b/lib/api/src/js/imports.rs @@ -1,7 +1,7 @@ //! The import module contains the implementation data structures and helper functions used to //! manipulate and access a wasm module's imports including memories, tables, globals, and //! functions. -use crate::js::error::{InstantiationError, LinkError}; +use crate::js::error::LinkError; use crate::js::exports::Exports; use crate::js::module::Module; use crate::js::store::AsStoreRef; diff --git a/lib/api/src/js/instance.rs b/lib/api/src/js/instance.rs index 7ee379a75..8a1e73cb2 100644 --- a/lib/api/src/js/instance.rs +++ b/lib/api/src/js/instance.rs @@ -90,25 +90,11 @@ impl Instance { module: &Module, externs: &[Extern], ) -> Result { - let imports = externs.to_vec(); - let mut handle = module.instantiate(store, &imports)?; - let exports = module - .exports() - .map(|export| { - let name = export.name().to_string(); - let export = handle.lookup(&name).expect("export"); - let extern_ = Extern::from_vm_extern(store, export); - (name, extern_) - }) - .collect::(); - - let instance = Self { - _handle: StoreHandle::new(store.objects_mut(), handle), - module: module.clone(), - exports, - }; - - Ok(instance) + let mut imports = Imports::new(); + for (import_ty, extern_ty) in module.imports().zip(externs.iter()) { + imports.define(import_ty.module(), import_ty.name(), extern_ty.clone()); + } + Self::new(store, module, &imports) } /// Creates a Wasmer `Instance` from a Wasmer `Module` and a WebAssembly Instance @@ -134,10 +120,7 @@ impl Instance { let extern_type = export_type.ty().clone(); let js_export = js_sys::Reflect::get(&instance_exports, &name.into()).map_err(|_e| { - InstantiationError::Link(format!( - "Can't get {} from the instance exports", - &name - )) + InstantiationError::NotInExports(name.to_string()) })?; let export: Export = Export::from_js_value(js_export, &mut store, extern_type)?.into(); From 2ee66140c998eff253442e339028742c59919c1c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Felix=20Sch=C3=BCtt?= Date: Fri, 26 Aug 2022 18:48:48 +0200 Subject: [PATCH 32/45] cargo fmt && fix issue with function_body_ptr --- lib/api/src/js/externals/function.rs | 6 +++--- lib/api/src/js/instance.rs | 6 ++---- lib/api/src/js/module.rs | 4 ++-- lib/api/src/sys/externals/function.rs | 6 +++--- 4 files changed, 10 insertions(+), 12 deletions(-) diff --git a/lib/api/src/js/externals/function.rs b/lib/api/src/js/externals/function.rs index 1a85ad83b..5e1d169ea 100644 --- a/lib/api/src/js/externals/function.rs +++ b/lib/api/src/js/externals/function.rs @@ -908,7 +908,7 @@ mod inner { Kind: HostFunctionKind, { /// 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; @@ -1122,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. @@ -1170,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. diff --git a/lib/api/src/js/instance.rs b/lib/api/src/js/instance.rs index 8a1e73cb2..985a50bf2 100644 --- a/lib/api/src/js/instance.rs +++ b/lib/api/src/js/instance.rs @@ -118,10 +118,8 @@ impl Instance { .map(|export_type| { let name = export_type.name(); let extern_type = export_type.ty().clone(); - let js_export = - js_sys::Reflect::get(&instance_exports, &name.into()).map_err(|_e| { - InstantiationError::NotInExports(name.to_string()) - })?; + let js_export = js_sys::Reflect::get(&instance_exports, &name.into()) + .map_err(|_e| InstantiationError::NotInExports(name.to_string()))?; let export: Export = Export::from_js_value(js_export, &mut store, extern_type)?.into(); let extern_ = Extern::from_vm_extern(&mut store, export); diff --git a/lib/api/src/js/module.rs b/lib/api/src/js/module.rs index e5f207151..f1cdbaec1 100644 --- a/lib/api/src/js/module.rs +++ b/lib/api/src/js/module.rs @@ -560,11 +560,11 @@ impl Module { /// is returned. pub fn custom_sections<'a>(&'a self, name: &'a str) -> impl Iterator> + 'a { // TODO: implement on JavaScript - DefaultCustomSectionsIterator { } + DefaultCustomSectionsIterator {} } } -pub struct DefaultCustomSectionsIterator { } +pub struct DefaultCustomSectionsIterator {} impl Iterator for DefaultCustomSectionsIterator { type Item = Box<[u8]>; diff --git a/lib/api/src/sys/externals/function.rs b/lib/api/src/sys/externals/function.rs index 835eea097..1b90a43c4 100644 --- a/lib/api/src/sys/externals/function.rs +++ b/lib/api/src/sys/externals/function.rs @@ -1092,7 +1092,7 @@ mod inner { Kind: HostFunctionKind, { /// 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; @@ -1268,7 +1268,7 @@ mod inner { Func: Fn(FunctionEnvMut, $( $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. @@ -1352,7 +1352,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. From 329bfb2c4b68438d8b92891b625c87279cb5e9c7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Felix=20Sch=C3=BCtt?= Date: Mon, 29 Aug 2022 11:08:30 +0200 Subject: [PATCH 33/45] Add to_jsvalue / from_jsvalue --- lib/api/src/js/externals/mod.rs | 82 +++++++++++++++++++++++++++++++++ lib/api/src/js/instance.rs | 5 +- 2 files changed, 85 insertions(+), 2 deletions(-) diff --git a/lib/api/src/js/externals/mod.rs b/lib/api/src/js/externals/mod.rs index 5472ee52f..8d7e83bc0 100644 --- a/lib/api/src/js/externals/mod.rs +++ b/lib/api/src/js/externals/mod.rs @@ -18,6 +18,8 @@ use crate::js::store::{AsStoreMut, AsStoreRef}; use crate::js::types::AsJs; use crate::js::ExternType; use std::fmt; +use wasm_bindgen::{JsValue, JsCast}; +use crate::js::error::WasmError; /// The value of an export passed from one instance to another. pub enum VMExtern { @@ -34,6 +36,86 @@ pub enum VMExtern { Global(InternalStoreHandle), } +impl VMExtern { + /// Return the export as a `JSValue`. + pub fn as_jsvalue<'context>(&self, store: &'context impl AsStoreRef) -> &'context 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(), + } + } + + /// 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(InternalStoreHandle::new( + &mut store.objects_mut(), + 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(InternalStoreHandle::new( + &mut store.objects_mut(), + 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(InternalStoreHandle::new( + &mut store.objects_mut(), + 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(InternalStoreHandle::new( + &mut store.objects_mut(), + 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. /// diff --git a/lib/api/src/js/instance.rs b/lib/api/src/js/instance.rs index 985a50bf2..14e3db2c7 100644 --- a/lib/api/src/js/instance.rs +++ b/lib/api/src/js/instance.rs @@ -112,6 +112,7 @@ impl Instance { instance: StoreHandle, imports: Imports, ) -> Result { + use crate::js::externals::VMExtern; let instance_exports = instance.get(store.as_store_ref().objects()).exports(); let exports = module .exports() @@ -120,8 +121,8 @@ impl Instance { let extern_type = export_type.ty().clone(); let js_export = js_sys::Reflect::get(&instance_exports, &name.into()) .map_err(|_e| InstantiationError::NotInExports(name.to_string()))?; - let export: Export = - Export::from_js_value(js_export, &mut store, extern_type)?.into(); + let export: VMExtern = + VMExtern::from_js_value(js_export, &mut store, extern_type)?.into(); let extern_ = Extern::from_vm_extern(&mut store, export); Ok((name.to_string(), extern_)) }) From f2b13f10dd7c11d5d5df487b2d9d149155bf9cdf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Felix=20Sch=C3=BCtt?= Date: Mon, 29 Aug 2022 11:35:14 +0200 Subject: [PATCH 34/45] make test-js passes --- lib/api/src/js/externals/global.rs | 2 +- lib/api/src/js/externals/mod.rs | 35 ++++++++++++++++++++---------- lib/api/src/js/types.rs | 1 + lib/api/src/js/value.rs | 2 +- lib/api/tests/js_externals.rs | 2 +- 5 files changed, 27 insertions(+), 15 deletions(-) diff --git a/lib/api/src/js/externals/global.rs b/lib/api/src/js/externals/global.rs index 38e8ef6ac..69b9b9595 100644 --- a/lib/api/src/js/externals/global.rs +++ b/lib/api/src/js/externals/global.rs @@ -128,7 +128,7 @@ impl Global { /// /// assert_eq!(g.get(), Value::I32(1)); /// ``` - pub fn get(&self, store: &mut impl AsStoreMut) -> Value { + pub fn get(&self, store: &impl AsStoreRef) -> Value { unsafe { let raw = self .handle diff --git a/lib/api/src/js/externals/mod.rs b/lib/api/src/js/externals/mod.rs index 8d7e83bc0..a40ecb1c3 100644 --- a/lib/api/src/js/externals/mod.rs +++ b/lib/api/src/js/externals/mod.rs @@ -12,14 +12,25 @@ pub use self::table::Table; use crate::js::export::{Export, VMFunction, VMGlobal, VMMemory, VMTable}; use crate::js::exports::{ExportError, Exportable}; -use crate::js::store::InternalStoreHandle; -use crate::js::store::StoreObject; -use crate::js::store::{AsStoreMut, AsStoreRef}; use crate::js::types::AsJs; +use crate::js::store::StoreObject; + +/* + + +use crate::js::store::InternalStoreHandle; +use crate::js::store::{AsStoreMut, AsStoreRef}; use crate::js::ExternType; use std::fmt; -use wasm_bindgen::{JsValue, JsCast}; +*/ use crate::js::error::WasmError; +use crate::js::store::{AsStoreMut, AsStoreRef, InternalStoreHandle}; +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 std::fmt; +use wasm_bindgen::{JsCast, JsValue}; +use wasmer_types::{ExternType, FunctionType, GlobalType, MemoryType, TableType}; /// The value of an export passed from one instance to another. pub enum VMExtern { @@ -67,10 +78,10 @@ impl VMExtern { ) -> Result { match extern_type { ExternType::Memory(memory_type) => { - if val.is_instance_of::() { + if val.is_instance_of::() { Ok(Self::Memory(InternalStoreHandle::new( &mut store.objects_mut(), - VMMemory::new(val.unchecked_into::(), memory_type), + VMMemory::new(val.unchecked_into::(), memory_type), ))) } else { Err(WasmError::TypeMismatch( @@ -83,30 +94,30 @@ impl VMExtern { } } ExternType::Global(global_type) => { - if val.is_instance_of::() { + if val.is_instance_of::() { Ok(Self::Global(InternalStoreHandle::new( &mut store.objects_mut(), - VMGlobal::new(val.unchecked_into::(), global_type), + 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::() { + if val.is_instance_of::() { Ok(Self::Function(InternalStoreHandle::new( &mut store.objects_mut(), - VMFunction::new(val.unchecked_into::(), function_type), + 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::
() { + if val.is_instance_of::() { Ok(Self::Table(InternalStoreHandle::new( &mut store.objects_mut(), - VMTable::new(val.unchecked_into::
(), table_type), + VMTable::new(val.unchecked_into::(), table_type), ))) } else { panic!("Extern type doesn't match js value type"); diff --git a/lib/api/src/js/types.rs b/lib/api/src/js/types.rs index 0e9716073..c7a4efd9f 100644 --- a/lib/api/src/js/types.rs +++ b/lib/api/src/js/types.rs @@ -43,6 +43,7 @@ impl AsJs for Value { Self::I64(i) => JsValue::from_f64(*i as f64), 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()) diff --git a/lib/api/src/js/value.rs b/lib/api/src/js/value.rs index a1def4de9..6eb2cb512 100644 --- a/lib/api/src/js/value.rs +++ b/lib/api/src/js/value.rs @@ -110,7 +110,7 @@ impl Value { /// /// # Safety /// - pub unsafe fn from_raw(store: &mut impl AsStoreMut, ty: Type, raw: f64) -> Self { + pub unsafe fn from_raw(_store: &impl AsStoreRef, ty: Type, raw: f64) -> Self { match ty { Type::I32 => Self::I32(raw as _), Type::I64 => Self::I64(raw as _), diff --git a/lib/api/tests/js_externals.rs b/lib/api/tests/js_externals.rs index 4795c1ba4..90a181ec8 100644 --- a/lib/api/tests/js_externals.rs +++ b/lib/api/tests/js_externals.rs @@ -29,7 +29,7 @@ mod js { fn global_get() { let mut store = Store::default(); let global_i32 = Global::new(&mut store, Value::I32(10)); - assert_eq!(global_i32.get(&store), Value::I32(10)); + assert_eq!(global_i32.get(&mut store), Value::I32(10)); // 64-bit values are not yet fully supported in some versions of Node // Commenting this tests for now: From 68939d6ce9014e3763f99cef1eb8a71e840b3e53 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Felix=20Sch=C3=BCtt?= Date: Mon, 29 Aug 2022 11:44:22 +0200 Subject: [PATCH 35/45] cargo fmt --- lib/api/src/js/externals/mod.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/api/src/js/externals/mod.rs b/lib/api/src/js/externals/mod.rs index a40ecb1c3..60ed02f18 100644 --- a/lib/api/src/js/externals/mod.rs +++ b/lib/api/src/js/externals/mod.rs @@ -12,10 +12,10 @@ pub use self::table::Table; use crate::js::export::{Export, VMFunction, VMGlobal, VMMemory, VMTable}; use crate::js::exports::{ExportError, Exportable}; -use crate::js::types::AsJs; use crate::js::store::StoreObject; +use crate::js::types::AsJs; -/* +/* use crate::js::store::InternalStoreHandle; From cdf85a2f1ddb4e1ff796b4754c219981682635be Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Felix=20Sch=C3=BCtt?= Date: Mon, 29 Aug 2022 16:20:06 +0200 Subject: [PATCH 36/45] Update CHANGELOG --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index a95eed136..c2e7526f7 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -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 From d023c1e7d13f065799dbc3c46d6908a3227e0569 Mon Sep 17 00:00:00 2001 From: Syrus Akbary Date: Mon, 29 Aug 2022 19:31:34 +0200 Subject: [PATCH 37/45] Improved JS API a bit further --- lib/api/src/js/imports.rs | 311 ++++++++++++++++++++++--------------- lib/api/src/js/instance.rs | 17 +- lib/api/src/js/module.rs | 49 +----- 3 files changed, 197 insertions(+), 180 deletions(-) diff --git a/lib/api/src/js/imports.rs b/lib/api/src/js/imports.rs index 4c98e38a0..193838e96 100644 --- a/lib/api/src/js/imports.rs +++ b/lib/api/src/js/imports.rs @@ -227,6 +227,36 @@ impl Imports { } } +impl AsJs for Imports { + fn as_jsvalue(&self, store: &impl AsStoreRef) -> wasm_bindgen::JsValue { + let imports_object = js_sys::Object::new(); + for (namespace, name, extern_) in self.iter() { + let val = js_sys::Reflect::get(&imports_object, &namespace.into()).unwrap(); + if !val.is_undefined() { + // If the namespace is already set + js_sys::Reflect::set( + &val, + &name.into(), + &extern_.as_jsvalue(&store.as_store_ref()), + ) + .unwrap(); + } else { + // If the namespace doesn't exist + let import_namespace = js_sys::Object::new(); + js_sys::Reflect::set( + &import_namespace, + &name.into(), + &extern_.as_jsvalue(&store.as_store_ref()), + ) + .unwrap(); + js_sys::Reflect::set(&imports_object, &namespace.into(), &import_namespace.into()) + .unwrap(); + } + } + imports_object.into() + } +} + pub struct ImportsIterator<'a> { iter: std::collections::hash_map::Iter<'a, (String, String), Extern>, } @@ -363,89 +393,18 @@ macro_rules! import_namespace { }; } -/* +#[cfg(test)] mod test { - use crate::js::exports::Exportable; - use crate::js::Type; - use crate::js::{Global, Store, Val}; + use crate::js::{Global, Store, Value}; - use crate::js::export::Export; + // use wasm_bindgen::*; use wasm_bindgen_test::*; - 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), - } - }; - } + #[wasm_bindgen_test] fn chaining_works() { let mut store = Store::default(); - let g = Global::new(&store, Val::I32(0)); + + let g = Global::new(&mut store, Value::I32(0)); let mut imports1 = imports! { "dog" => { @@ -458,7 +417,7 @@ mod test { "small" => g.clone() }, "cat" => { - "small" => g.clone() + "small" => g } }; @@ -472,62 +431,162 @@ 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 + // }; - 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 happy_dog_entry = imports1.get_export("dog", "happy").unwrap(); - let mut imports1 = imports! { - "dog" => { - "happy" => g1, - }, - }; + // assert!( + // if let Export::Global(happy_dog_global) = happy_dog_entry.to_export() { + // happy_dog_global.ty.ty == Type::I32 + // } else { + // false + // } + // ); + // } - let imports2 = imports! { - "dog" => { - "happy" => g2, - }, - }; + // fn imports_macro_allows_trailing_comma_and_none() { + // use crate::js::Function; - imports1.extend(&imports2); - let happy_dog_entry = imports1.get_export("dog", "happy").unwrap(); + // let mut store = Default::default(); - assert!( - if let Export::Global(happy_dog_global) = happy_dog_entry.to_export() { - happy_dog_global.ty.ty == Type::F32 - } else { - false - } - ); + // fn func(arg: i32) -> i32 { + // arg + 1 + // } - // 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 _ = 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), + // } + // }; + // } - let imports1 = imports! { - "dog" => { - "happy" => g1, - }, - }; + // fn chaining_works() { + // let mut store = Store::default(); + // let g = Global::new(&store, Val::I32(0)); - let mut imports2 = imports! { - "dog" => { - "happy" => g2, - }, - }; + // let mut imports1 = imports! { + // "dog" => { + // "happy" => g.clone() + // } + // }; - imports2.extend(&imports1); - let happy_dog_entry = imports2.get_export("dog", "happy").unwrap(); + // let imports2 = imports! { + // "dog" => { + // "small" => g.clone() + // }, + // "cat" => { + // "small" => g.clone() + // } + // }; - assert!( - if let Export::Global(happy_dog_global) = happy_dog_entry.to_export() { - happy_dog_global.ty.ty == Type::I32 - } else { - false - } - ); - } + // 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 1b1eb0898..fe914626f 100644 --- a/lib/api/src/js/instance.rs +++ b/lib/api/src/js/instance.rs @@ -20,8 +20,6 @@ use std::fmt; pub struct Instance { _handle: StoreHandle, module: Module, - #[allow(dead_code)] - imports: Imports, /// The exports for an instance. pub exports: Exports, } @@ -65,12 +63,11 @@ impl Instance { module: &Module, imports: &Imports, ) -> Result { - let import_copy = imports.clone(); - let (instance, _imports): (StoreHandle, Vec) = module + let instance: WebAssembly::Instance = module .instantiate(&mut store, imports) .map_err(|e| InstantiationError::Start(e))?; - let self_instance = Self::from_module_and_instance(store, module, instance, import_copy)?; + let self_instance = Self::from_module_and_instance(store, module, instance)?; //self_instance.init_envs(&imports.iter().map(Extern::to_export).collect::>())?; Ok(self_instance) } @@ -87,10 +84,9 @@ impl Instance { pub fn from_module_and_instance( mut store: &mut impl AsStoreMut, module: &Module, - instance: StoreHandle, - imports: Imports, + instance: WebAssembly::Instance, ) -> Result { - let instance_exports = instance.get(store.as_store_ref().objects()).exports(); + let instance_exports = instance.exports(); let exports = module .exports() .map(|export_type| { @@ -109,11 +105,10 @@ impl Instance { Ok((name.to_string(), extern_)) }) .collect::>()?; - + let handle = StoreHandle::new(store.as_store_mut().objects_mut(), instance); Ok(Self { - _handle: instance, + _handle: handle, module: module.clone(), - imports, exports, }) } diff --git a/lib/api/src/js/module.rs b/lib/api/src/js/module.rs index 975d1bee5..dc3df9075 100644 --- a/lib/api/src/js/module.rs +++ b/lib/api/src/js/module.rs @@ -3,9 +3,8 @@ use crate::js::error::WasmError; use crate::js::error::{CompileError, InstantiationError}; #[cfg(feature = "js-serializable-module")] use crate::js::error::{DeserializeError, SerializeError}; -use crate::js::externals::Extern; use crate::js::imports::Imports; -use crate::js::store::{AsStoreMut, StoreHandle}; +use crate::js::store::AsStoreMut; use crate::js::types::{AsJs, ExportType, ImportType}; use crate::js::RuntimeError; use crate::AsStoreRef; @@ -222,7 +221,7 @@ impl Module { &self, store: &mut impl AsStoreMut, imports: &Imports, - ) -> Result<(StoreHandle, Vec), RuntimeError> { + ) -> Result { // Ensure all imports come from the same store. if imports .into_iter() @@ -232,46 +231,10 @@ impl Module { InstantiationError::DifferentStores, ))); } - let imports_object = js_sys::Object::new(); - let mut import_externs: Vec = vec![]; - for import_type in self.imports() { - let resolved_import = imports.get_export(import_type.module(), import_type.name()); - if let Some(import) = resolved_import { - let val = js_sys::Reflect::get(&imports_object, &import_type.module().into())?; - if !val.is_undefined() { - // If the namespace is already set - js_sys::Reflect::set( - &val, - &import_type.name().into(), - &import.as_jsvalue(&store.as_store_ref()), - )?; - } else { - // If the namespace doesn't exist - let import_namespace = js_sys::Object::new(); - js_sys::Reflect::set( - &import_namespace, - &import_type.name().into(), - &import.as_jsvalue(&store.as_store_ref()), - )?; - js_sys::Reflect::set( - &imports_object, - &import_type.module().into(), - &import_namespace.into(), - )?; - } - import_externs.push(import); - } - // in case the import is not found, the JS Wasm VM will handle - // the error for us, so we don't need to handle it - } - Ok(( - StoreHandle::new( - store.as_store_mut().objects_mut(), - WebAssembly::Instance::new(&self.module, &imports_object) - .map_err(|e: JsValue| -> RuntimeError { e.into() })?, - ), - import_externs, - )) + + let imports_js_obj = imports.as_jsvalue(store).into(); + Ok(WebAssembly::Instance::new(&self.module, &imports_js_obj) + .map_err(|e: JsValue| -> RuntimeError { e.into() })?) } /// Returns the name of the current module. From f5996f12504f0d9367bd81bb04a3af8f97b97971 Mon Sep 17 00:00:00 2001 From: Syrus Akbary Date: Tue, 30 Aug 2022 12:32:22 -0700 Subject: [PATCH 38/45] Use wasix conditionally --- Cargo.lock | 8 -------- lib/vbus/Cargo.toml | 4 ---- lib/vnet/Cargo.toml | 4 ---- lib/wasi/Cargo.toml | 3 ++- lib/wasi/src/lib.rs | 12 +++++++++--- lib/wasi/src/syscalls/mod.rs | 2 ++ lib/wasi/src/utils.rs | 1 + 7 files changed, 14 insertions(+), 20 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 69a3e6b50..fe78d5ade 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -3220,11 +3220,7 @@ dependencies = [ name = "wasmer-vbus" version = "3.0.0-beta" dependencies = [ - "libc", - "slab", "thiserror", - "tracing", - "typetag", "wasmer-vfs", ] @@ -3268,11 +3264,7 @@ name = "wasmer-vnet" version = "3.0.0-beta" dependencies = [ "bytes", - "libc", - "slab", "thiserror", - "tracing", - "typetag", "wasmer-vfs", ] diff --git a/lib/vbus/Cargo.toml b/lib/vbus/Cargo.toml index 287005766..b996bf0dd 100644 --- a/lib/vbus/Cargo.toml +++ b/lib/vbus/Cargo.toml @@ -7,11 +7,7 @@ license = "MIT" edition = "2018" [dependencies] -libc = { version = "^0.2", default-features = false, optional = true } thiserror = "1" -tracing = { version = "0.1" } -typetag = { version = "0.1", optional = true } -slab = { version = "0.4", optional = true } wasmer-vfs = { path = "../vfs", version = "=3.0.0-beta", default-features = false } [features] diff --git a/lib/vnet/Cargo.toml b/lib/vnet/Cargo.toml index edaba9e48..c263df339 100644 --- a/lib/vnet/Cargo.toml +++ b/lib/vnet/Cargo.toml @@ -7,11 +7,7 @@ license = "MIT" edition = "2018" [dependencies] -libc = { version = "^0.2", default-features = false, optional = true } thiserror = "1" -tracing = { version = "0.1" } -typetag = { version = "0.1", optional = true } -slab = { version = "0.4", optional = true } wasmer-vfs = { path = "../vfs", version = "=3.0.0-beta", default-features = false } bytes = "1" diff --git a/lib/wasi/Cargo.toml b/lib/wasi/Cargo.toml index 798d13046..c02fff666 100644 --- a/lib/wasi/Cargo.toml +++ b/lib/wasi/Cargo.toml @@ -44,8 +44,9 @@ tracing-wasm = "0.2" [features] default = ["sys-default"] +wasix = [] -sys = ["wasmer/sys"] +sys = ["wasmer/sys", "wasix"] sys-default = ["wasmer/wat", "wasmer/compiler", "sys", "logging", "host-fs", "sys-poll", "host-vnet" ] sys-poll = [] diff --git a/lib/wasi/src/lib.rs b/lib/wasi/src/lib.rs index 4daeb25a4..64924c871 100644 --- a/lib/wasi/src/lib.rs +++ b/lib/wasi/src/lib.rs @@ -47,9 +47,9 @@ pub use crate::state::{ WasiStateCreationError, ALL_RIGHTS, VIRTUAL_ROOT_FD, }; pub use crate::syscalls::types; -pub use crate::utils::{ - get_wasi_version, get_wasi_versions, is_wasi_module, is_wasix_module, WasiVersion, -}; +#[cfg(feature = "wasix")] +pub use crate::utils::is_wasix_module; +pub use crate::utils::{get_wasi_version, get_wasi_versions, is_wasi_module, WasiVersion}; pub use wasmer_vbus::{UnsupportedVirtualBus, VirtualBus}; #[deprecated(since = "2.1.0", note = "Please use `wasmer_vfs::FsError`")] pub use wasmer_vfs::FsError as WasiFsError; @@ -184,6 +184,7 @@ impl WasiFunctionEnv { } } + #[cfg(feature = "wasix")] if is_wasix_module(module) { self.data_mut(store) .state @@ -394,8 +395,11 @@ pub fn generate_import_object_from_env( WasiVersion::Snapshot1 | WasiVersion::Latest => { generate_import_object_snapshot1(store, env) } + #[cfg(feature = "wasix")] WasiVersion::Wasix32v1 => generate_import_object_wasix32_v1(store, env), + #[cfg(feature = "wasix")] WasiVersion::Wasix64v1 => generate_import_object_wasix64_v1(store, env), + _ => unimplemented!(), } } @@ -537,6 +541,7 @@ fn generate_import_object_snapshot1( } /// Combines a state generating function with the import list for snapshot 1 +#[cfg(feature = "wasix")] fn generate_import_object_wasix32_v1( mut store: &mut impl AsStoreMut, env: &FunctionEnv, @@ -655,6 +660,7 @@ fn generate_import_object_wasix32_v1( } } +#[cfg(feature = "wasix")] fn generate_import_object_wasix64_v1( mut store: &mut impl AsStoreMut, env: &FunctionEnv, diff --git a/lib/wasi/src/syscalls/mod.rs b/lib/wasi/src/syscalls/mod.rs index e972946c0..903abae2a 100644 --- a/lib/wasi/src/syscalls/mod.rs +++ b/lib/wasi/src/syscalls/mod.rs @@ -18,7 +18,9 @@ pub mod windows; pub mod legacy; //pub mod wasi; +#[cfg(feature = "wasix")] pub mod wasix32; +#[cfg(feature = "wasix")] pub mod wasix64; use self::types::*; diff --git a/lib/wasi/src/utils.rs b/lib/wasi/src/utils.rs index 772228891..0fbc5c221 100644 --- a/lib/wasi/src/utils.rs +++ b/lib/wasi/src/utils.rs @@ -10,6 +10,7 @@ pub fn is_wasi_module(module: &Module) -> bool { } #[allow(dead_code)] +#[cfg(feature = "wasix")] /// Returns if the module is WASIX or not pub fn is_wasix_module(module: &Module) -> bool { match get_wasi_versions(module, false).ok_or(false) { From 0301b2e5f49d7394def05d23d77fc033b224faa4 Mon Sep 17 00:00:00 2001 From: Syrus Akbary Date: Tue, 30 Aug 2022 12:44:14 -0700 Subject: [PATCH 39/45] Allow unreacheable --- lib/wasi/src/lib.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/lib/wasi/src/lib.rs b/lib/wasi/src/lib.rs index 64924c871..9670bb31b 100644 --- a/lib/wasi/src/lib.rs +++ b/lib/wasi/src/lib.rs @@ -399,6 +399,7 @@ pub fn generate_import_object_from_env( WasiVersion::Wasix32v1 => generate_import_object_wasix32_v1(store, env), #[cfg(feature = "wasix")] WasiVersion::Wasix64v1 => generate_import_object_wasix64_v1(store, env), + #[allow(unreachable_code)] _ => unimplemented!(), } } From 368a53fb71ff297110491e39e6a734f63b178a20 Mon Sep 17 00:00:00 2001 From: Syrus Akbary Date: Tue, 30 Aug 2022 12:59:48 -0700 Subject: [PATCH 40/45] Fixed linting --- lib/wasi/src/lib.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/wasi/src/lib.rs b/lib/wasi/src/lib.rs index 9670bb31b..11f644983 100644 --- a/lib/wasi/src/lib.rs +++ b/lib/wasi/src/lib.rs @@ -399,7 +399,7 @@ pub fn generate_import_object_from_env( WasiVersion::Wasix32v1 => generate_import_object_wasix32_v1(store, env), #[cfg(feature = "wasix")] WasiVersion::Wasix64v1 => generate_import_object_wasix64_v1(store, env), - #[allow(unreachable_code)] + #[cfg(not(feature = "wasix"))] _ => unimplemented!(), } } From 3dc2e26b22c469b46fe59f7c12885c36719a0508 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Felix=20Sch=C3=BCtt?= Date: Wed, 31 Aug 2022 13:33:51 +0200 Subject: [PATCH 41/45] Fix merge errors --- lib/api/src/js/imports.rs | 3 ++- lib/api/src/js/instance.rs | 2 +- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/lib/api/src/js/imports.rs b/lib/api/src/js/imports.rs index 91db636c4..a668b96d5 100644 --- a/lib/api/src/js/imports.rs +++ b/lib/api/src/js/imports.rs @@ -195,6 +195,7 @@ 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| { @@ -217,7 +218,7 @@ impl Imports { let import_js: wasm_bindgen::JsValue = import_entry.get(1); let key = (module_name.clone(), import_name); let extern_type = module_imports.get(&key).unwrap(); - let export = Export::from_js_value(import_js, store, extern_type.clone())?; + let export = VMExtern::from_js_value(import_js, store, extern_type.clone())?; let extern_ = Extern::from_vm_extern(store, export); map.insert(key, extern_); } diff --git a/lib/api/src/js/instance.rs b/lib/api/src/js/instance.rs index 23b07130d..5e1ddbf2e 100644 --- a/lib/api/src/js/instance.rs +++ b/lib/api/src/js/instance.rs @@ -109,7 +109,7 @@ impl Instance { instance: WebAssembly::Instance, ) -> Result { use crate::js::externals::VMExtern; - let instance_exports = instance.get(store.as_store_ref().objects()).exports(); + let instance_exports = instance.exports(); let exports = module .exports() .map(|export_type| { From 436bec735bc532f608a49fdf2e32b5d69b7b15dd Mon Sep 17 00:00:00 2001 From: ptitSeb Date: Thu, 1 Sep 2022 13:52:53 +0200 Subject: [PATCH 42/45] Using IntoBytes only for Module::deserialise (both sys and js) --- lib/api/src/js/module.rs | 31 ++++++++-------------- lib/api/src/sys/module.rs | 45 +++++++++++++------------------- lib/cli/src/commands/validate.rs | 2 +- tests/compilers/serialize.rs | 2 +- 4 files changed, 31 insertions(+), 49 deletions(-) diff --git a/lib/api/src/js/module.rs b/lib/api/src/js/module.rs index 48fa0b80f..27f9d6686 100644 --- a/lib/api/src/js/module.rs +++ b/lib/api/src/js/module.rs @@ -169,19 +169,15 @@ impl Module { /// # } /// ``` #[allow(unreachable_code)] - pub fn new(_store: &impl AsStoreRef, bytes: impl IntoBytes) -> Result { - let mut bytes = bytes.into_bytes(); + pub fn new(_store: &impl AsStoreRef, bytes: impl AsRef<[u8]>) -> Result { #[cfg(feature = "wat")] - if bytes.starts_with(b"\0asm") == false { - let parsed_bytes = wat::parse_bytes(bytes.as_ref()).map_err(|e| { - CompileError::Wasm(WasmError::Generic(format!( - "Error when converting wat: {}", - e - ))) - })?; - bytes = Bytes::from(parsed_bytes.to_vec()); - } - Self::from_binary(_store, bytes) + let bytes = wat::parse_bytes(bytes.as_ref()).map_err(|e| { + CompileError::Wasm(WasmError::Generic(format!( + "Error when converting wat: {}", + e + ))) + })?; + Self::from_binary(_store, bytes.as_ref()) } /// Creates a new WebAssembly module from a file path. @@ -197,11 +193,7 @@ impl Module { /// Opposed to [`Module::new`], this function is not compatible with /// the WebAssembly text format (if the "wat" feature is enabled for /// this crate). - pub fn from_binary( - _store: &impl AsStoreRef, - binary: impl IntoBytes, - ) -> Result { - let binary = binary.into_bytes(); + pub fn from_binary(_store: &impl AsStoreRef, binary: &[u8]) -> Result { // // Self::validate(store, binary)?; unsafe { Self::from_binary_unchecked(_store, binary) } @@ -215,9 +207,8 @@ impl Module { /// We maintain the `unsafe` to preserve the same API as Wasmer pub unsafe fn from_binary_unchecked( _store: &impl AsStoreRef, - binary: impl IntoBytes, + binary: &[u8], ) -> Result { - let binary = binary.into_bytes(); let js_bytes = Uint8Array::view(&binary[..]); let module = WebAssembly::Module::new(&js_bytes.into()).unwrap(); @@ -260,7 +251,7 @@ impl Module { /// This validation is normally pretty fast and checks the enabled /// WebAssembly features in the Store Engine to assure deterministic /// validation of the Module. - pub fn validate(_store: &impl AsStoreRef, binary: impl IntoBytes) -> Result<(), CompileError> { + pub fn validate(_store: &impl AsStoreRef, binary: &[u8]) -> Result<(), CompileError> { let binary = binary.into_bytes(); let js_bytes = unsafe { Uint8Array::view(&binary[..]) }; match WebAssembly::validate(&js_bytes.into()) { diff --git a/lib/api/src/sys/module.rs b/lib/api/src/sys/module.rs index 72f1b414a..bc4257ab0 100644 --- a/lib/api/src/sys/module.rs +++ b/lib/api/src/sys/module.rs @@ -158,19 +158,15 @@ impl Module { /// # } /// ``` #[allow(unreachable_code)] - pub fn new(store: &impl AsStoreRef, bytes: impl IntoBytes) -> Result { - let mut bytes = bytes.into_bytes(); + pub fn new(store: &impl AsStoreRef, bytes: impl AsRef<[u8]>) -> Result { #[cfg(feature = "wat")] - if !bytes.starts_with(b"\0asm") { - let parsed_bytes = wat::parse_bytes(&bytes[..]).map_err(|e| { - CompileError::Wasm(WasmError::Generic(format!( - "Error when converting wat: {}", - e - ))) - })?; - bytes = Bytes::from(parsed_bytes.to_vec()); - } - Self::from_binary(store, bytes) + let bytes = wat::parse_bytes(bytes.as_ref()).map_err(|e| { + CompileError::Wasm(WasmError::Generic(format!( + "Error when converting wat: {}", + e + ))) + })?; + Self::from_binary(store, bytes.as_ref()) } #[cfg(feature = "compiler")] @@ -182,7 +178,7 @@ impl Module { let file_ref = file.as_ref(); let canonical = file_ref.canonicalize()?; let wasm_bytes = std::fs::read(file_ref)?; - let mut module = Self::new(store, wasm_bytes)?; + let mut module = Self::new(store, &wasm_bytes)?; // Set the module name to the absolute path of the filename. // This is useful for debugging the stack traces. let filename = canonical.as_path().to_str().unwrap(); @@ -196,12 +192,8 @@ impl Module { /// Opposed to [`Module::new`], this function is not compatible with /// the WebAssembly text format (if the "wat" feature is enabled for /// this crate). - pub fn from_binary( - store: &impl AsStoreRef, - binary: impl IntoBytes, - ) -> Result { - let binary = binary.into_bytes(); - Self::validate(store, binary.clone())?; + pub fn from_binary(store: &impl AsStoreRef, binary: &[u8]) -> Result { + Self::validate(store, binary)?; unsafe { Self::from_binary_unchecked(store, binary) } } @@ -215,9 +207,8 @@ impl Module { /// beforehand. pub unsafe fn from_binary_unchecked( store: &impl AsStoreRef, - binary: impl IntoBytes, + binary: &[u8], ) -> Result { - let binary = binary.into_bytes(); let module = Self::compile(store, binary)?; Ok(module) } @@ -229,13 +220,12 @@ impl Module { /// This validation is normally pretty fast and checks the enabled /// WebAssembly features in the Store Engine to assure deterministic /// validation of the Module. - pub fn validate(store: &impl AsStoreRef, binary: impl IntoBytes) -> Result<(), CompileError> { - let binary = binary.into_bytes(); - store.as_store_ref().engine().validate(&binary[..]) + pub fn validate(store: &impl AsStoreRef, binary: &[u8]) -> Result<(), CompileError> { + store.as_store_ref().engine().validate(binary) } #[cfg(feature = "compiler")] - fn compile(store: &impl AsStoreRef, binary: impl IntoBytes) -> Result { + fn compile(store: &impl AsStoreRef, binary: &[u8]) -> Result { let binary = binary.into_bytes(); let artifact = store .as_store_ref() @@ -306,9 +296,10 @@ impl Module { /// ``` pub unsafe fn deserialize( store: &impl AsStoreRef, - bytes: &[u8], + bytes: impl IntoBytes, ) -> Result { - let artifact = store.as_store_ref().engine().deserialize(bytes)?; + let bytes = bytes.into_bytes(); + let artifact = store.as_store_ref().engine().deserialize(&bytes)?; Ok(Self::from_artifact(artifact)) } diff --git a/lib/cli/src/commands/validate.rs b/lib/cli/src/commands/validate.rs index 2e1aa59ec..4f620ecc3 100644 --- a/lib/cli/src/commands/validate.rs +++ b/lib/cli/src/commands/validate.rs @@ -27,7 +27,7 @@ impl Validate { if !is_wasm(&module_contents) { bail!("`wasmer validate` only validates WebAssembly files"); } - Module::validate(&store, module_contents)?; + Module::validate(&store, &module_contents)?; eprintln!("Validation passed for `{}`.", self.path.display()); Ok(()) } diff --git a/tests/compilers/serialize.rs b/tests/compilers/serialize.rs index 4bca9000f..48997f0e4 100644 --- a/tests/compilers/serialize.rs +++ b/tests/compilers/serialize.rs @@ -45,7 +45,7 @@ fn test_deserialize(config: crate::Config) -> Result<()> { let serialized_bytes = module.serialize()?; let headless_store = config.headless_store(); - let deserialized_module = unsafe { Module::deserialize(&headless_store, &serialized_bytes)? }; + let deserialized_module = unsafe { Module::deserialize(&headless_store, serialized_bytes)? }; assert_eq!(deserialized_module.name(), Some("name")); assert_eq!( deserialized_module.exports().collect::>(), From 35285558694bc3f6e050bb962e17d6225b2800cc Mon Sep 17 00:00:00 2001 From: ptitSeb Date: Thu, 1 Sep 2022 17:18:13 +0200 Subject: [PATCH 43/45] Made Module::serialize to gives Bytes instead of Vec --- lib/api/src/js/module.rs | 11 +++++------ lib/api/src/sys/module.rs | 7 +++---- lib/c-api/src/wasm_c_api/module.rs | 2 +- 3 files changed, 9 insertions(+), 11 deletions(-) diff --git a/lib/api/src/js/module.rs b/lib/api/src/js/module.rs index 27f9d6686..38ac279a7 100644 --- a/lib/api/src/js/module.rs +++ b/lib/api/src/js/module.rs @@ -105,7 +105,7 @@ pub struct Module { // WebAssembly type hints type_hints: Option, #[cfg(feature = "js-serializable-module")] - raw_bytes: Option>, + raw_bytes: Option, } impl Module { @@ -209,7 +209,7 @@ impl Module { _store: &impl AsStoreRef, binary: &[u8], ) -> Result { - let js_bytes = Uint8Array::view(&binary[..]); + let js_bytes = Uint8Array::view(binary); let module = WebAssembly::Module::new(&js_bytes.into()).unwrap(); // The module is now validated, so we can safely parse it's types @@ -241,7 +241,7 @@ impl Module { type_hints, name, #[cfg(feature = "js-serializable-module")] - raw_bytes: Some(binary.to_vec()), + raw_bytes: Some(binary), }) } @@ -252,8 +252,7 @@ impl Module { /// WebAssembly features in the Store Engine to assure deterministic /// validation of the Module. pub fn validate(_store: &impl AsStoreRef, binary: &[u8]) -> Result<(), CompileError> { - let binary = binary.into_bytes(); - let js_bytes = unsafe { Uint8Array::view(&binary[..]) }; + let js_bytes = unsafe { Uint8Array::view(binary) }; match WebAssembly::validate(&js_bytes.into()) { Ok(true) => Ok(()), _ => Err(CompileError::Validate("Invalid Wasm file".to_owned())), @@ -306,7 +305,7 @@ impl Module { /// can later process via [`Module::deserialize`]. /// #[cfg(feature = "js-serializable-module")] - pub fn serialize(&self) -> Result, SerializeError> { + pub fn serialize(&self) -> Result { self.raw_bytes.clone().ok_or(SerializeError::Generic( "Not able to serialize module".to_string(), )) diff --git a/lib/api/src/sys/module.rs b/lib/api/src/sys/module.rs index bc4257ab0..24e372663 100644 --- a/lib/api/src/sys/module.rs +++ b/lib/api/src/sys/module.rs @@ -226,11 +226,10 @@ impl Module { #[cfg(feature = "compiler")] fn compile(store: &impl AsStoreRef, binary: &[u8]) -> Result { - let binary = binary.into_bytes(); let artifact = store .as_store_ref() .engine() - .compile(&binary[..], store.as_store_ref().tunables())?; + .compile(binary, store.as_store_ref().tunables())?; Ok(Self::from_artifact(artifact)) } @@ -248,8 +247,8 @@ impl Module { /// # Ok(()) /// # } /// ``` - pub fn serialize(&self) -> Result, SerializeError> { - self.artifact.serialize() + pub fn serialize(&self) -> Result { + self.artifact.serialize().map(|bytes| bytes.into()) } /// Serializes a module into a file that the `Engine` diff --git a/lib/c-api/src/wasm_c_api/module.rs b/lib/c-api/src/wasm_c_api/module.rs index 26cbfd3fc..4afa7760c 100644 --- a/lib/c-api/src/wasm_c_api/module.rs +++ b/lib/c-api/src/wasm_c_api/module.rs @@ -475,7 +475,7 @@ pub unsafe extern "C" fn wasm_module_deserialize( #[no_mangle] pub unsafe extern "C" fn wasm_module_serialize(module: &wasm_module_t, out: &mut wasm_byte_vec_t) { let byte_vec = c_try!(module.inner.serialize(); otherwise ()); - out.set_buffer(byte_vec); + out.set_buffer(byte_vec.to_vec()); } #[cfg(test)] From cc9fb4693d6d340a93c3b5c9d0fe0562bfb8aee8 Mon Sep 17 00:00:00 2001 From: ptitSeb Date: Thu, 1 Sep 2022 17:39:18 +0200 Subject: [PATCH 44/45] Fixed js build --- lib/api/src/js/module.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/api/src/js/module.rs b/lib/api/src/js/module.rs index 38ac279a7..4bad30fea 100644 --- a/lib/api/src/js/module.rs +++ b/lib/api/src/js/module.rs @@ -241,7 +241,7 @@ impl Module { type_hints, name, #[cfg(feature = "js-serializable-module")] - raw_bytes: Some(binary), + raw_bytes: Some(binary.into_bytes()), }) } From 2752f7d3908c87fbcac0c6c374a0b5b2eeea12c5 Mon Sep 17 00:00:00 2001 From: ptitSeb Date: Thu, 1 Sep 2022 18:02:14 +0200 Subject: [PATCH 45/45] More rollback fixes --- lib/api/src/lib.rs | 2 +- tests/compilers/imports.rs | 6 +++--- tests/compilers/traps.rs | 10 +++++----- tests/lib/wast/src/wasi_wast.rs | 2 +- 4 files changed, 10 insertions(+), 10 deletions(-) diff --git a/lib/api/src/lib.rs b/lib/api/src/lib.rs index ccb647175..663903104 100644 --- a/lib/api/src/lib.rs +++ b/lib/api/src/lib.rs @@ -55,7 +55,7 @@ //! "#; //! //! let mut store = Store::default(); -//! let module = Module::new(&store, module_wat)?; +//! let module = Module::new(&store, &module_wat)?; //! // The module doesn't import anything, so we create an empty import object. //! let import_object = imports! {}; //! let instance = Instance::new(&mut store, &module, &import_object)?; diff --git a/tests/compilers/imports.rs b/tests/compilers/imports.rs index a14273dd4..60d452ac6 100644 --- a/tests/compilers/imports.rs +++ b/tests/compilers/imports.rs @@ -40,7 +40,7 @@ fn get_module(store: &Store) -> Result { (start $foo) "#; - let module = Module::new(store, wat)?; + let module = Module::new(store, &wat)?; Ok(module) } @@ -339,7 +339,7 @@ fn static_function_that_fails(config: crate::Config) -> Result<()> { (start $foo) "#; - let module = Module::new(&store, wat)?; + let module = Module::new(&store, &wat)?; let f0 = Function::new_typed(&mut store, || -> Result { Err(RuntimeError::new("oops")) }); @@ -375,7 +375,7 @@ fn get_module2(store: &Store) -> Result { (call 0)) "#; - let module = Module::new(store, wat)?; + let module = Module::new(store, &wat)?; Ok(module) } diff --git a/tests/compilers/traps.rs b/tests/compilers/traps.rs index 6bf18c27f..5c0e6a20d 100644 --- a/tests/compilers/traps.rs +++ b/tests/compilers/traps.rs @@ -262,7 +262,7 @@ fn trap_start_function_import(config: crate::Config) -> Result<()> { ) "#; - let module = Module::new(&store, binary)?; + let module = Module::new(&store, &binary)?; let sig = FunctionType::new(vec![], vec![]); let func = Function::new(&mut store, &sig, |_| Err(RuntimeError::new("user trap"))); let err = Instance::new( @@ -302,7 +302,7 @@ fn rust_panic_import(config: crate::Config) -> Result<()> { ) "#; - let module = Module::new(&store, binary)?; + let module = Module::new(&store, &binary)?; let sig = FunctionType::new(vec![], vec![]); let func = Function::new(&mut store, &sig, |_| panic!("this is a panic")); let f0 = Function::new_typed(&mut store, || panic!("this is another panic")); @@ -347,7 +347,7 @@ fn rust_panic_start_function(config: crate::Config) -> Result<()> { ) "#; - let module = Module::new(&store, binary)?; + let module = Module::new(&store, &binary)?; let sig = FunctionType::new(vec![], vec![]); let func = Function::new(&mut store, &sig, |_| panic!("this is a panic")); let err = panic::catch_unwind(AssertUnwindSafe(|| { @@ -393,7 +393,7 @@ fn mismatched_arguments(config: crate::Config) -> Result<()> { ) "#; - let module = Module::new(&store, binary)?; + let module = Module::new(&store, &binary)?; let instance = Instance::new(&mut store, &module, &imports! {})?; let func: &Function = instance.exports.get("foo")?; assert_eq!( @@ -432,7 +432,7 @@ fn call_signature_mismatch(config: crate::Config) -> Result<()> { ) "#; - let module = Module::new(&store, binary)?; + let module = Module::new(&store, &binary)?; let err = Instance::new(&mut store, &module, &imports! {}) .err() .expect("expected error"); diff --git a/tests/lib/wast/src/wasi_wast.rs b/tests/lib/wast/src/wasi_wast.rs index beb11456c..6b2e13aac 100644 --- a/tests/lib/wast/src/wasi_wast.rs +++ b/tests/lib/wast/src/wasi_wast.rs @@ -82,7 +82,7 @@ impl<'a> WasiTest<'a> { wasm_module.read_to_end(&mut out)?; out }; - let module = Module::new(store, wasm_bytes)?; + let module = Module::new(store, &wasm_bytes)?; let (env, _tempdirs, stdout_rx, stderr_rx) = self.create_wasi_env(store, filesystem_kind)?; let imports = self.get_imports(store, &env.env, &module)?;