diff --git a/lib/js-api/src/export.rs b/lib/js-api/src/export.rs index 83d1fc4c3..911c0d4ea 100644 --- a/lib/js-api/src/export.rs +++ b/lib/js-api/src/export.rs @@ -1,5 +1,6 @@ use crate::instance::Instance; use crate::wasm_bindgen_polyfill::Global; +use crate::HostEnvInitError; use crate::WasmerEnv; use js_sys::Function; use js_sys::WebAssembly::{Memory, Table}; @@ -65,11 +66,12 @@ impl VMFunction { environment: environment.map(|env| Arc::new(RefCell::new(env))), } } - pub(crate) fn init_envs(&self, instance: &Instance) { + pub(crate) fn init_envs(&self, instance: &Instance) -> Result<(), HostEnvInitError> { if let Some(env) = &self.environment { let mut borrowed_env = env.borrow_mut(); - borrowed_env.init_with_instance(instance); + borrowed_env.init_with_instance(instance)?; } + Ok(()) } } diff --git a/lib/js-api/src/externals/function.rs b/lib/js-api/src/externals/function.rs index 853874434..2ac8b6405 100644 --- a/lib/js-api/src/externals/function.rs +++ b/lib/js-api/src/externals/function.rs @@ -577,7 +577,7 @@ impl Function { let given = Args::wasm_types(); if expected != given { - return Err(RuntimeError::from_str(&format!( + return Err(RuntimeError::new(format!( "given types (`{:?}`) for the function arguments don't match the actual types (`{:?}`)", given, expected, @@ -591,7 +591,7 @@ impl Function { if expected != given { // todo: error result types don't match - return Err(RuntimeError::from_str(&format!( + return Err(RuntimeError::new(format!( "given types (`{:?}`) for the function results don't match the actual types (`{:?}`)", given, expected, diff --git a/lib/js-api/src/externals/global.rs b/lib/js-api/src/externals/global.rs index 2f1cdd363..1010c0ff8 100644 --- a/lib/js-api/src/externals/global.rs +++ b/lib/js-api/src/externals/global.rs @@ -73,12 +73,12 @@ impl Global { }; // This is the value type as string, even though is incorrectly called "value" // in the JS API. - js_sys::Reflect::set(&descriptor, &"value".into(), &type_str.into()); + js_sys::Reflect::set(&descriptor, &"value".into(), &type_str.into())?; js_sys::Reflect::set( &descriptor, &"mutable".into(), &mutability.is_mutable().into(), - ); + )?; let js_global = JSGlobal::new(&descriptor, &value).unwrap(); let global = VMGlobal::new(js_global, global_ty); @@ -188,10 +188,10 @@ impl Global { /// ``` pub fn set(&self, val: Val) -> Result<(), RuntimeError> { if self.vm_global.ty.mutability == Mutability::Const { - return Err(RuntimeError::from_str("The global is immutable")); + return Err(RuntimeError::new("The global is immutable".to_owned())); } if val.ty() != self.vm_global.ty.ty { - return Err(RuntimeError::from_str("The types don't match")); + return Err(RuntimeError::new("The types don't match".to_owned())); } let new_value = match val { Val::I32(i) => JsValue::from_f64(i as _), diff --git a/lib/js-api/src/externals/memory.rs b/lib/js-api/src/externals/memory.rs index 6314922da..b1f0f69ed 100644 --- a/lib/js-api/src/externals/memory.rs +++ b/lib/js-api/src/externals/memory.rs @@ -82,13 +82,14 @@ impl Memory { /// ``` pub fn new(store: &Store, ty: MemoryType) -> Result { let descriptor = js_sys::Object::new(); - js_sys::Reflect::set(&descriptor, &"initial".into(), &ty.minimum.0.into()); + js_sys::Reflect::set(&descriptor, &"initial".into(), &ty.minimum.0.into()).unwrap(); if let Some(max) = ty.maximum { - js_sys::Reflect::set(&descriptor, &"maximum".into(), &max.0.into()); + js_sys::Reflect::set(&descriptor, &"maximum".into(), &max.0.into()).unwrap(); } - js_sys::Reflect::set(&descriptor, &"shared".into(), &ty.shared.into()); + js_sys::Reflect::set(&descriptor, &"shared".into(), &ty.shared.into()).unwrap(); - let js_memory = js_sys::WebAssembly::Memory::new(&descriptor).unwrap(); + let js_memory = js_sys::WebAssembly::Memory::new(&descriptor) + .map_err(|_e| MemoryError::Generic("Error while creating the memory".to_owned()))?; let memory = VMMemory::new(js_memory, ty); Ok(Self { diff --git a/lib/js-api/src/externals/table.rs b/lib/js-api/src/externals/table.rs index 20c8281f0..0e1c4d476 100644 --- a/lib/js-api/src/externals/table.rs +++ b/lib/js-api/src/externals/table.rs @@ -45,13 +45,13 @@ impl Table { /// [`BaseTunables`][crate::tunables::BaseTunables]. pub fn new(store: &Store, ty: TableType, init: Val) -> Result { let descriptor = js_sys::Object::new(); - js_sys::Reflect::set(&descriptor, &"initial".into(), &ty.minimum.into()); + js_sys::Reflect::set(&descriptor, &"initial".into(), &ty.minimum.into())?; if let Some(max) = ty.maximum { - js_sys::Reflect::set(&descriptor, &"maximum".into(), &max.into()); + js_sys::Reflect::set(&descriptor, &"maximum".into(), &max.into())?; } - js_sys::Reflect::set(&descriptor, &"element".into(), &"anyfunc".into()); + js_sys::Reflect::set(&descriptor, &"element".into(), &"anyfunc".into())?; - let js_table = js_sys::WebAssembly::Table::new(&descriptor).unwrap(); + let js_table = js_sys::WebAssembly::Table::new(&descriptor)?; let table = VMTable::new(js_table, ty); let num_elements = table.table.length(); diff --git a/lib/js-api/src/instance.rs b/lib/js-api/src/instance.rs index 4a10ec5f6..59b0f76ae 100644 --- a/lib/js-api/src/instance.rs +++ b/lib/js-api/src/instance.rs @@ -118,7 +118,7 @@ impl Instance { exports, }; for func in functions { - func.init_envs(&self_instance); + func.init_envs(&self_instance).unwrap(); } Ok(self_instance) } diff --git a/lib/js-api/src/lib.rs b/lib/js-api/src/lib.rs index 4d6d5843f..51771ac0e 100644 --- a/lib/js-api/src/lib.rs +++ b/lib/js-api/src/lib.rs @@ -102,6 +102,7 @@ mod native; mod ptr; mod resolver; mod store; +mod trap; mod types; mod utils; mod wasm_bindgen_polyfill; @@ -124,7 +125,7 @@ pub use crate::module::{Module, ModuleTypeHints}; pub use crate::native::NativeFunc; pub use crate::ptr::{Array, Item, WasmPtr}; pub use crate::resolver::{ChainableNamedResolver, NamedResolver, NamedResolverChain, Resolver}; -pub use wasm_bindgen::JsValue as RuntimeError; +pub use crate::trap::RuntimeError; pub use crate::store::{Store, StoreObject}; pub use crate::types::{ diff --git a/lib/js-api/src/module.rs b/lib/js-api/src/module.rs index 8c25485ed..1735348ff 100644 --- a/lib/js-api/src/module.rs +++ b/lib/js-api/src/module.rs @@ -7,6 +7,7 @@ use crate::types::{ExportType, ImportType}; use crate::error::CompileError; #[cfg(feature = "wat")] use crate::error::WasmError; +use crate::RuntimeError; use js_sys::{Reflect, Uint8Array, WebAssembly}; use std::fmt; use std::io; @@ -208,39 +209,31 @@ impl Module { pub(crate) fn instantiate( &self, resolver: &dyn Resolver, - ) -> Result<(WebAssembly::Instance, Vec), ()> { + ) -> Result<(WebAssembly::Instance, Vec), RuntimeError> { let imports = js_sys::Object::new(); let mut functions: Vec = vec![]; for (i, import_type) in self.imports().enumerate() { let resolved_import = resolver.resolve(i as u32, import_type.module(), import_type.name()); if let Some(import) = resolved_import { - match js_sys::Reflect::get(&imports, &import_type.module().into()) { - Ok(val) => { - if !val.is_undefined() { - // If the namespace is already set - js_sys::Reflect::set( - &val, - &import_type.name().into(), - import.as_jsvalue(), - ); - } 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(), - ); - js_sys::Reflect::set( - &imports, - &import_type.module().into(), - &import_namespace.into(), - ); - } - } - Err(_) => return Err(()), - }; + let val = js_sys::Reflect::get(&imports, &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())?; + } 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(), + )?; + js_sys::Reflect::set( + &imports, + &import_type.module().into(), + &import_namespace.into(), + )?; + } if let Export::Function(func) = import { functions.push(func); } diff --git a/lib/js-api/src/ptr.rs b/lib/js-api/src/ptr.rs index b986d05cb..4b912f131 100644 --- a/lib/js-api/src/ptr.rs +++ b/lib/js-api/src/ptr.rs @@ -252,7 +252,7 @@ mod test { let memory = Memory::new(&store, memory_descriptor).unwrap(); let start_wasm_ptr: WasmPtr = WasmPtr::new(2); - let mut val = start_wasm_ptr.deref(&memory).unwrap(); + let val = start_wasm_ptr.deref(&memory).unwrap(); assert_eq!(val.memory.to_vec(), vec![0; 8]); val.set(1200); diff --git a/lib/js-api/src/trap.rs b/lib/js-api/src/trap.rs index e939f10bf..1b9fce49a 100644 --- a/lib/js-api/src/trap.rs +++ b/lib/js-api/src/trap.rs @@ -1,15 +1,22 @@ -use super::frame_info::{FrameInfo, GlobalFrameInfo, FRAME_INFO}; -use backtrace::Backtrace; +// use super::frame_info::{FrameInfo, GlobalFrameInfo, FRAME_INFO}; use std::error::Error; use std::fmt; use std::sync::Arc; -use wasm_bindgen::Exception; +use wasm_bindgen::prelude::*; +use wasm_bindgen::JsValue; /// A struct representing an aborted instruction execution, with a message /// indicating the cause. +#[wasm_bindgen] #[derive(Clone)] pub struct RuntimeError { - inner: Arc, + inner: Arc, +} + +impl PartialEq for RuntimeError { + fn eq(&self, other: &Self) -> bool { + Arc::ptr_eq(&self.inner, &other.inner) + } } /// The source of the `RuntimeError`. @@ -17,6 +24,7 @@ pub struct RuntimeError { enum RuntimeErrorSource { Generic(String), User(Box), + Js(JsValue), } impl fmt::Display for RuntimeErrorSource { @@ -24,20 +32,14 @@ impl fmt::Display for RuntimeErrorSource { match self { Self::Generic(s) => write!(f, "{}", s), Self::User(s) => write!(f, "{}", s), - Self::OOM => write!(f, "Wasmer VM out of memory"), - Self::Trap(s) => write!(f, "{}", s.message()), + Self::Js(s) => write!(f, "{}", s.as_string().unwrap_or("".to_string())), } } } -struct RuntimeErrorInner { - /// The source error (this can be a custom user `Error` or a [`TrapCode`]) - source: RuntimeErrorSource, -} - -fn _assert_trap_is_sync_and_send(t: &Trap) -> (&dyn Sync, &dyn Send) { - (t, t) -} +// fn _assert_trap_is_sync_and_send(t: &Trap) -> (&dyn Sync, &dyn Send) { +// (t, t) +// } impl RuntimeError { /// Creates a new generic `RuntimeError` with the given `message`. @@ -48,82 +50,30 @@ impl RuntimeError { /// assert_eq!("unexpected error", trap.message()); /// ``` pub fn new>(message: I) -> Self { - let info = FRAME_INFO.read().unwrap(); - let msg = message.into(); - Self::new_with_trace( - &info, - None, - RuntimeErrorSource::Generic(msg), - Backtrace::new_unresolved(), - ) + RuntimeError { + inner: Arc::new(RuntimeErrorSource::Generic(message.into())), + } } /// Raises a custom user Error pub fn raise(error: Box) -> ! { - wasm_bindgen::throw_val() - } - - fn new_with_trace( - info: &GlobalFrameInfo, - trap_pc: Option, - source: RuntimeErrorSource, - native_trace: Backtrace, - ) -> Self { - let frames: Vec = native_trace - .frames() - .iter() - .filter_map(|frame| { - let pc = frame.ip() as usize; - if pc == 0 { - None - } else { - // Note that we need to be careful about the pc we pass in here to - // lookup frame information. This program counter is used to - // translate back to an original source location in the origin wasm - // module. If this pc is the exact pc that the trap happened at, - // then we look up that pc precisely. Otherwise backtrace - // information typically points at the pc *after* the call - // instruction (because otherwise it's likely a call instruction on - // the stack). In that case we want to lookup information for the - // previous instruction (the call instruction) so we subtract one as - // the lookup. - let pc_to_lookup = if Some(pc) == trap_pc { pc } else { pc - 1 }; - Some(pc_to_lookup) - } - }) - .collect(); - - // Let's construct the trace - let wasm_trace = frames - .into_iter() - .filter_map(|pc| info.lookup_frame_info(pc)) - .collect::>(); - - Self { - inner: Arc::new(RuntimeErrorInner { - source, - wasm_trace, - native_trace, - }), - } + let error = RuntimeError { + inner: Arc::new(RuntimeErrorSource::User(error)), + }; + let js_error: JsValue = error.into(); + wasm_bindgen::throw_val(js_error) } /// Returns a reference the `message` stored in `Trap`. pub fn message(&self) -> String { - format!("{}", self.inner.source) - } - - /// Returns a list of function frames in WebAssembly code that led to this - /// trap happening. - pub fn trace(&self) -> &[FrameInfo] { - &self.inner.wasm_trace + format!("{}", self.inner) } /// Attempts to downcast the `RuntimeError` to a concrete type. pub fn downcast(self) -> Result { - match self.inner.source { + match Arc::try_unwrap(self.inner) { // We only try to downcast user errors - RuntimeErrorSource::User(err)) if err.is::() => Ok(*err.downcast::().unwrap()), + Ok(RuntimeErrorSource::User(err)) if err.is::() => Ok(*err.downcast::().unwrap()), Ok(inner) => Err(Self { inner: Arc::new(inner), }), @@ -131,18 +81,9 @@ impl RuntimeError { } } - /// Returns trap code, if it's a Trap - pub fn to_trap(self) -> Option { - if let RuntimeErrorSource::Trap(trap_code) = self.inner.source { - Some(trap_code) - } else { - None - } - } - /// Returns true if the `RuntimeError` is the same as T pub fn is(&self) -> bool { - match &self.inner.source { + match self.inner.as_ref() { RuntimeErrorSource::User(err) => err.is::(), _ => false, } @@ -152,9 +93,7 @@ impl RuntimeError { impl fmt::Debug for RuntimeError { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { f.debug_struct("RuntimeError") - .field("source", &self.inner.source) - .field("wasm_trace", &self.inner.wasm_trace) - .field("native_trace", &self.inner.native_trace) + .field("source", &self.inner) .finish() } } @@ -162,46 +101,29 @@ impl fmt::Debug for RuntimeError { impl fmt::Display for RuntimeError { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { write!(f, "RuntimeError: {}", self.message())?; - let trace = self.trace(); - if trace.is_empty() { - return Ok(()); - } - for frame in self.trace().iter() { - let name = frame.module_name(); - let func_index = frame.func_index(); - writeln!(f)?; - write!(f, " at ")?; - match frame.function_name() { - Some(name) => match rustc_demangle::try_demangle(name) { - Ok(name) => write!(f, "{}", name)?, - Err(_) => write!(f, "{}", name)?, - }, - None => write!(f, "")?, - } - write!( - f, - " ({}[{}]:0x{:x})", - name, - func_index, - frame.module_offset() - )?; - } Ok(()) } } impl std::error::Error for RuntimeError { fn source(&self) -> Option<&(dyn std::error::Error + 'static)> { - match &self.inner.source { + match self.inner.as_ref() { RuntimeErrorSource::User(err) => Some(&**err), - RuntimeErrorSource::Trap(err) => Some(err), _ => None, } } } -impl From for RuntimeError { - fn from(trap: Trap) -> Self { - Self::from_trap(trap) +impl From for RuntimeError { + fn from(original: JsValue) -> Self { + RuntimeError { + inner: Arc::new(RuntimeErrorSource::Js(original)), + } } } + +// impl Into for RuntimeError { +// fn into(self) -> JsValue { + +// } +// } diff --git a/lib/js-api/tests/instance.rs b/lib/js-api/tests/instance.rs index b22d52efe..eb7816b8f 100644 --- a/lib/js-api/tests/instance.rs +++ b/lib/js-api/tests/instance.rs @@ -14,10 +14,12 @@ fn test_exported_memory() { "#, ) .unwrap(); - module.set_type_hints(ModuleTypeHints { - imports: vec![], - exports: vec![ExternType::Memory(MemoryType::new(Pages(1), None, false))], - }); + module + .set_type_hints(ModuleTypeHints { + imports: vec![], + exports: vec![ExternType::Memory(MemoryType::new(Pages(1), None, false))], + }) + .unwrap(); let import_object = imports! {}; let instance = Instance::new(&module, &import_object).unwrap(); @@ -47,13 +49,15 @@ fn test_exported_function() { "#, ) .unwrap(); - module.set_type_hints(ModuleTypeHints { - imports: vec![], - exports: vec![ExternType::Function(FunctionType::new( - vec![], - vec![Type::I32], - ))], - }); + module + .set_type_hints(ModuleTypeHints { + imports: vec![], + exports: vec![ExternType::Function(FunctionType::new( + vec![], + vec![Type::I32], + ))], + }) + .unwrap(); let import_object = imports! {}; let instance = Instance::new(&module, &import_object).unwrap(); @@ -83,16 +87,18 @@ fn test_imported_function_dynamic() { "#, ) .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], - ))], - }); + 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 imported_signature = FunctionType::new(vec![Type::I32], vec![Type::I32]); let imported = Function::new(&store, &imported_signature, |args| { @@ -102,15 +108,6 @@ fn test_imported_function_dynamic() { Ok(vec![Value::I32(result)]) }); - let imported_multivalue_signature = - FunctionType::new(vec![Type::I32, Type::I32], vec![Type::I32, Type::I32]); - let imported_multivalue = Function::new(&store, &imported_multivalue_signature, |args| { - println!("Calling `imported`..."); - // let result = args[0].unwrap_i32() * ; - // println!("Result of `imported`: {:?}", result); - Ok(vec![args[1].clone(), args[0].clone()]) - }); - let import_object = imports! { "env" => { "imported" => imported, @@ -199,22 +196,18 @@ fn test_imported_function_dynamic_with_env() { "#, ) .unwrap(); - module.set_type_hints(ModuleTypeHints { - imports: vec![ - ExternType::Function(FunctionType::new(vec![Type::I32], vec![Type::I32])), - ExternType::Function(FunctionType::new( - vec![Type::I32, Type::I32], - vec![Type::I32, Type::I32], - )), - ], - exports: vec![ - ExternType::Function(FunctionType::new(vec![Type::I32], vec![Type::I32])), - ExternType::Function(FunctionType::new( - vec![Type::I32, Type::I32], - vec![Type::I32, Type::I32], - )), - ], - }); + 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(); #[derive(WasmerEnv, Clone)] struct Env { @@ -262,16 +255,18 @@ fn test_imported_function_native() { "#, ) .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], - ))], - }); + 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(); fn imported_fn(arg: u32) -> u32 { return arg + 1; @@ -307,16 +302,18 @@ fn test_imported_function_native_with_env() { "#, ) .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], - ))], - }); + 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(); #[derive(WasmerEnv, Clone)] struct Env { @@ -358,16 +355,18 @@ fn test_imported_function_native_with_wasmer_env() { "#, ) .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])), - ExternType::Memory(MemoryType::new(Pages(1), None, false)), - ], - }); + 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])), + ExternType::Memory(MemoryType::new(Pages(1), None, false)), + ], + }) + .unwrap(); #[derive(WasmerEnv, Clone)] struct Env { @@ -409,11 +408,11 @@ fn test_imported_function_native_with_wasmer_env() { let exported = instance.exports.get_function("exported").unwrap(); - /// It with the provided memory + // It works with the provided memory let expected = vec![Val::I32(24)].into_boxed_slice(); assert_eq!(exported.call(&[Val::I32(4)]), Ok(expected)); - /// It works if we update the memory + // It works if we update the memory memory.uint8view().set_index(0, 3); let expected = vec![Val::I32(36)].into_boxed_slice(); assert_eq!(exported.call(&[Val::I32(4)]), Ok(expected)); @@ -435,16 +434,18 @@ fn test_imported_function_with_wasmer_env() { "#, ) .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])), - ExternType::Memory(MemoryType::new(Pages(1), None, false)), - ], - }); + 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])), + ExternType::Memory(MemoryType::new(Pages(1), None, false)), + ], + }) + .unwrap(); #[derive(WasmerEnv, Clone)] struct Env { @@ -489,11 +490,11 @@ fn test_imported_function_with_wasmer_env() { let exported = instance.exports.get_function("exported").unwrap(); - /// It with the provided memory + // It works with the provided memory let expected = vec![Val::I32(24)].into_boxed_slice(); assert_eq!(exported.call(&[Val::I32(4)]), Ok(expected)); - /// It works if we update the memory + // It works if we update the memory memory.uint8view().set_index(0, 3); let expected = vec![Val::I32(36)].into_boxed_slice(); assert_eq!(exported.call(&[Val::I32(4)]), Ok(expected)); @@ -515,17 +516,19 @@ fn test_imported_exported_global() { "#, ) .unwrap(); - module.set_type_hints(ModuleTypeHints { - imports: vec![ExternType::Global(GlobalType::new( - ValType::I32, - Mutability::Var, - ))], - exports: vec![ - ExternType::Function(FunctionType::new(vec![], vec![Type::I32])), - ExternType::Function(FunctionType::new(vec![], vec![])), - ], - }); - let mut global = Global::new_mut(&store, Value::I32(0)); + module + .set_type_hints(ModuleTypeHints { + imports: vec![ExternType::Global(GlobalType::new( + ValType::I32, + Mutability::Var, + ))], + exports: vec![ + ExternType::Function(FunctionType::new(vec![], vec![Type::I32])), + ExternType::Function(FunctionType::new(vec![], vec![])), + ], + }) + .unwrap(); + let global = Global::new_mut(&store, Value::I32(0)); let import_object = imports! { "" => { "global" => global.clone() @@ -539,14 +542,14 @@ fn test_imported_exported_global() { Ok(vec![Val::I32(0)].into_boxed_slice()) ); - global.set(Value::I32(42)); + global.set(Value::I32(42)).unwrap(); assert_eq!( get_global.call(&[]), Ok(vec![Val::I32(42)].into_boxed_slice()) ); let inc_global = instance.exports.get_function("incGlobal").unwrap(); - inc_global.call(&[]); + inc_global.call(&[]).unwrap(); assert_eq!( get_global.call(&[]), Ok(vec![Val::I32(43)].into_boxed_slice()) diff --git a/lib/js-api/tests/module.rs b/lib/js-api/tests/module.rs index a3132e0a6..f254f9097 100644 --- a/lib/js-api/tests/module.rs +++ b/lib/js-api/tests/module.rs @@ -1,4 +1,3 @@ -use anyhow::Result; use wasm_bindgen_test::*; use wasmer_js::*; @@ -105,15 +104,17 @@ fn exports() { (global (export "global") i32 (i32.const 0)) )"#; let mut module = Module::new(&store, wat).unwrap(); - module.set_type_hints(ModuleTypeHints { - exports: vec![ - ExternType::Function(FunctionType::new(vec![], vec![])), - ExternType::Memory(MemoryType::new(Pages(2), None, false)), - ExternType::Table(TableType::new(Type::FuncRef, 2, None)), - ExternType::Global(GlobalType::new(Type::I32, Mutability::Const)), - ], - imports: vec![], - }); + module + .set_type_hints(ModuleTypeHints { + exports: vec![ + ExternType::Function(FunctionType::new(vec![], vec![])), + ExternType::Memory(MemoryType::new(Pages(2), None, false)), + ExternType::Table(TableType::new(Type::FuncRef, 2, None)), + ExternType::Global(GlobalType::new(Type::I32, Mutability::Const)), + ], + imports: vec![], + }) + .unwrap(); assert_eq!( module.exports().collect::>(), vec![