diff --git a/lib/js-api/src/instance.rs b/lib/js-api/src/instance.rs index ec17c1306..25f70a9e8 100644 --- a/lib/js-api/src/instance.rs +++ b/lib/js-api/src/instance.rs @@ -1,9 +1,11 @@ +use crate::env::HostEnvInitError; use crate::export::Export; use crate::exports::Exports; use crate::externals::Extern; use crate::module::Module; -use crate::store::Store; use crate::resolver::Resolver; +use crate::store::Store; +use crate::trap::RuntimeError; use js_sys::WebAssembly; use std::fmt; use thiserror::Error; @@ -39,10 +41,13 @@ pub enum InstantiationError { Link(String), /// A runtime error occured while invoking the start function - #[cfg_attr(feature = "std", error("Start error: {0}"))] - Start(String), -} + #[error(transparent)] + Start(RuntimeError), + /// Error occurred when initializing the host environment. + #[error(transparent)] + HostEnvInitialization(HostEnvInitError), +} impl Instance { /// Creates a new `Instance` from a WebAssembly [`Module`] and a @@ -80,7 +85,9 @@ impl Instance { /// * Runtime errors that happen when running the module `start` function. pub fn new(module: &Module, resolver: &dyn Resolver) -> Result { let store = module.store(); - let (instance, functions) = module.instantiate(resolver).unwrap(); + let (instance, functions) = module + .instantiate(resolver) + .map_err(|e| InstantiationError::Start(e))?; let instance_exports = instance.exports(); let exports = module .exports() @@ -100,7 +107,8 @@ impl Instance { exports, }; for func in functions { - func.init_envs(&self_instance).unwrap(); + func.init_envs(&self_instance) + .map_err(|e| InstantiationError::HostEnvInitialization(e))?; } Ok(self_instance) } diff --git a/lib/js-api/src/module.rs b/lib/js-api/src/module.rs index e41301a43..de02f6221 100644 --- a/lib/js-api/src/module.rs +++ b/lib/js-api/src/module.rs @@ -12,6 +12,7 @@ use std::fmt; use std::io; use std::path::Path; use thiserror::Error; +use wasm_bindgen::JsValue; use wasmer_types::{ ExportsIterator, ExternType, FunctionType, GlobalType, ImportsIterator, MemoryType, Mutability, Pages, TableType, Type, @@ -244,7 +245,8 @@ impl Module { // the error for us, so we don't need to handle it } Ok(( - WebAssembly::Instance::new(&self.module, &imports).unwrap(), + WebAssembly::Instance::new(&self.module, &imports) + .map_err(|e: JsValue| -> RuntimeError { e.into() })?, functions, )) } diff --git a/lib/js-api/src/types.rs b/lib/js-api/src/types.rs index b7ecdaf67..80507ae24 100644 --- a/lib/js-api/src/types.rs +++ b/lib/js-api/src/types.rs @@ -28,7 +28,10 @@ pub fn param_from_js(ty: &ValType, js_val: &JsValue) -> Val { ValType::I64 => Val::I64(js_val.as_f64().unwrap() as _), ValType::F32 => Val::F32(js_val.as_f64().unwrap() as _), ValType::F64 => Val::F64(js_val.as_f64().unwrap()), - t => unimplemented!("The type `{:?}` is not yet supported in the JS Function API", t), + t => unimplemented!( + "The type `{:?}` is not yet supported in the JS Function API", + t + ), } } @@ -40,7 +43,10 @@ impl AsJs for Val { Self::F32(f) => JsValue::from_f64(*f as f64), Self::F64(f) => JsValue::from_f64(*f), Self::FuncRef(func) => func.as_ref().unwrap().exported.function.clone().into(), - v => unimplemented!("The value `{:?}` is not yet supported in the JS Function API", v), + v => unimplemented!( + "The value `{:?}` is not yet supported in the JS Function API", + v + ), } } } diff --git a/lib/js-api/tests/externals.rs b/lib/js-api/tests/externals.rs index bbdeb0a22..e87a08874 100644 --- a/lib/js-api/tests/externals.rs +++ b/lib/js-api/tests/externals.rs @@ -29,6 +29,9 @@ fn global_get() { let store = Store::default(); let global_i32 = Global::new(&store, Value::I32(10)); assert_eq!(global_i32.get(), Value::I32(10)); + // 64-bit values are not yet fully supported in some versions of Node + // Commenting this tests for now: + // let global_i64 = Global::new(&store, Value::I64(20)); // assert_eq!(global_i64.get(), Value::I64(20)); let global_f32 = Global::new(&store, Value::F32(10.0)); @@ -76,6 +79,9 @@ fn table_new() { // assert_eq!(*table.ty(), table_type); } +// Tables are not yet fully supported in Wasm +// Commenting this tests for now + // #[test] // #[ignore] // fn table_get() -> Result<()> { diff --git a/lib/js-api/tests/instance.rs b/lib/js-api/tests/instance.rs index a576d9c7f..58d96588f 100644 --- a/lib/js-api/tests/instance.rs +++ b/lib/js-api/tests/instance.rs @@ -703,3 +703,29 @@ fn test_custom_error() { let run_func = instance.exports.get_function("run").unwrap(); test_result(run_func.call(&[Val::I32(1), Val::I32(7)])); } + +#[wasm_bindgen_test] +fn test_start_function_fails() { + let store = Store::default(); + let module = Module::new( + &store, + br#" + (module + (func $start_function + (i32.div_u + (i32.const 1) + (i32.const 0) + ) + drop + ) + (start $start_function) + ) + "#, + ) + .unwrap(); + + let import_object = imports! {}; + let result = Instance::new(&module, &import_object); + let err = result.unwrap_err(); + assert!(format!("{:?}", err).contains("zero")) +} diff --git a/lib/vm/src/lib.rs b/lib/vm/src/lib.rs index 02b735695..ecf4fd71f 100644 --- a/lib/vm/src/lib.rs +++ b/lib/vm/src/lib.rs @@ -47,8 +47,6 @@ pub use crate::instance::{ }; pub use crate::memory::{LinearMemory, Memory, MemoryError, MemoryStyle}; pub use crate::mmap::Mmap; -#[deprecated(since = "2.1.0", note = "ModuleInfo, ExportsIterator, ImportsIterator should be imported from wasmer_types.")] -pub use wasmer_types::{ModuleInfo, ExportsIterator, ImportsIterator}; pub use crate::probestack::PROBESTACK; pub use crate::sig_registry::SignatureRegistry; pub use crate::table::{LinearTable, Table, TableElement, TableStyle}; @@ -62,6 +60,11 @@ pub use crate::vmcontext::{ pub use crate::vmoffsets::{TargetSharedSignatureIndex, VMOffsets}; use loupe::MemoryUsage; pub use wasmer_types::VMExternRef; +#[deprecated( + since = "2.1.0", + note = "ModuleInfo, ExportsIterator, ImportsIterator should be imported from wasmer_types." +)] +pub use wasmer_types::{ExportsIterator, ImportsIterator, ModuleInfo}; /// Version number of this crate. pub const VERSION: &str = env!("CARGO_PKG_VERSION");