diff --git a/crates/api/examples/hello.rs b/crates/api/examples/hello.rs index ccf146bea8..6d00ed15bb 100644 --- a/crates/api/examples/hello.rs +++ b/crates/api/examples/hello.rs @@ -7,7 +7,7 @@ use wasmtime::*; struct HelloCallback; impl Callable for HelloCallback { - fn call(&self, _params: &[Val], _results: &mut [Val]) -> Result<(), HostRef> { + fn call(&self, _params: &[Val], _results: &mut [Val]) -> Result<(), Trap> { println!("Calling back..."); println!("> Hello World!"); Ok(()) diff --git a/crates/api/examples/multi.rs b/crates/api/examples/multi.rs index 7f980f581b..a1632a644e 100644 --- a/crates/api/examples/multi.rs +++ b/crates/api/examples/multi.rs @@ -7,7 +7,7 @@ use wasmtime::*; struct Callback; impl Callable for Callback { - fn call(&self, args: &[Val], results: &mut [Val]) -> Result<(), HostRef> { + fn call(&self, args: &[Val], results: &mut [Val]) -> Result<(), Trap> { println!("Calling back..."); println!("> {} {}", args[0].unwrap_i32(), args[1].unwrap_i64()); diff --git a/crates/api/src/callable.rs b/crates/api/src/callable.rs index 374bbdc95b..bb203ffd46 100644 --- a/crates/api/src/callable.rs +++ b/crates/api/src/callable.rs @@ -1,7 +1,7 @@ use crate::r#ref::HostRef; use crate::runtime::Store; use crate::trampoline::{generate_func_export, take_api_trap}; -use crate::trap::Trap; +use crate::trap::{Trap, TrapInfo}; use crate::types::FuncType; use crate::values::Val; use std::rc::Rc; @@ -18,7 +18,7 @@ use wasmtime_runtime::Export; /// struct TimesTwo; /// /// impl wasmtime::Callable for TimesTwo { -/// fn call(&self, params: &[Val], results: &mut [Val]) -> Result<(), HostRef> { +/// fn call(&self, params: &[Val], results: &mut [Val]) -> Result<(), wasmtime::Trap> { /// let mut value = params[0].unwrap_i32(); /// value *= 2; /// results[0] = value.into(); @@ -75,7 +75,7 @@ use wasmtime_runtime::Export; /// let results = run_function /// .borrow() /// .call(&[original.into()]) -/// .map_err(|trap| trap.borrow().to_string())?; +/// .map_err(|trap| trap.to_string())?; /// /// // Compare that the results returned matches what we expect. /// assert_eq!(original * 2, results[0].unwrap_i32()); @@ -87,11 +87,11 @@ pub trait Callable { /// `params` is an immutable list of parameters provided to the function. /// `results` is mutable list of results to be potentially set by your /// function. Produces a `Trap` if the function encounters any errors. - fn call(&self, params: &[Val], results: &mut [Val]) -> Result<(), HostRef>; + fn call(&self, params: &[Val], results: &mut [Val]) -> Result<(), Trap>; } pub(crate) trait WrappedCallable { - fn call(&self, params: &[Val], results: &mut [Val]) -> Result<(), HostRef>; + fn call(&self, params: &[Val], results: &mut [Val]) -> Result<(), Trap>; fn signature(&self) -> &ir::Signature { match self.wasmtime_export() { Export::Function { signature, .. } => signature, @@ -119,7 +119,7 @@ impl WasmtimeFn { } impl WrappedCallable for WasmtimeFn { - fn call(&self, params: &[Val], results: &mut [Val]) -> Result<(), HostRef> { + fn call(&self, params: &[Val], results: &mut [Val]) -> Result<(), Trap> { use std::cmp::max; use std::mem; @@ -150,7 +150,7 @@ impl WrappedCallable for WasmtimeFn { .context() .compiler() .get_published_trampoline(body, &signature, value_size) - .map_err(|_| HostRef::new(Trap::fake()))?; //was ActionError::Setup)?; + .map_err(|e| Trap::new(format!("trampoline error: {:?}", e)))?; // Call the trampoline. if let Err(message) = unsafe { @@ -160,8 +160,9 @@ impl WrappedCallable for WasmtimeFn { values_vec.as_mut_ptr() as *mut u8, ) } { - let trap = take_api_trap().unwrap_or_else(|| HostRef::new(Trap::new(message))); - return Err(trap); + let trap = take_api_trap() + .unwrap_or_else(|| HostRef::new(TrapInfo::new(format!("call error: {}", message)))); + return Err(trap.into()); } // Load the return values out of `values_vec`. @@ -206,7 +207,7 @@ impl NativeCallable { } impl WrappedCallable for NativeCallable { - fn call(&self, params: &[Val], results: &mut [Val]) -> Result<(), HostRef> { + fn call(&self, params: &[Val], results: &mut [Val]) -> Result<(), Trap> { self.callable.call(params, results) } fn wasmtime_handle(&self) -> &InstanceHandle { diff --git a/crates/api/src/externals.rs b/crates/api/src/externals.rs index 8a710e1f25..5a70885a5d 100644 --- a/crates/api/src/externals.rs +++ b/crates/api/src/externals.rs @@ -147,7 +147,7 @@ impl Func { self.r#type.results().len() } - pub fn call(&self, params: &[Val]) -> Result, HostRef> { + pub fn call(&self, params: &[Val]) -> Result, Trap> { let mut results = vec![Val::null(); self.result_arity()]; self.callable.call(params, &mut results)?; Ok(results.into_boxed_slice()) diff --git a/crates/api/src/instance.rs b/crates/api/src/instance.rs index 49eecce2ed..f7fc2f599a 100644 --- a/crates/api/src/instance.rs +++ b/crates/api/src/instance.rs @@ -4,8 +4,9 @@ use crate::module::Module; use crate::r#ref::HostRef; use crate::runtime::Store; use crate::trampoline::take_api_trap; +use crate::trap::Trap; use crate::types::{ExportType, ExternType}; -use anyhow::Result; +use anyhow::{Error, Result}; use std::cell::RefCell; use std::collections::{HashMap, HashSet}; use std::rc::Rc; @@ -31,7 +32,7 @@ pub fn instantiate_in_context( imports: Vec<(String, String, Extern)>, mut context: Context, exports: Rc>>>, -) -> Result<(InstanceHandle, HashSet)> { +) -> Result<(InstanceHandle, HashSet), Error> { let mut contexts = HashSet::new(); let debug_info = context.debug_info(); let mut resolver = SimpleResolver { imports }; @@ -42,10 +43,12 @@ pub fn instantiate_in_context( exports, debug_info, ) - .map_err(|e| { - // TODO wrap HostRef into Error - drop(take_api_trap()); - e + .map_err(|e| -> Error { + if let Some(trap) = take_api_trap() { + Trap::from(trap).into() + } else { + e.into() + } })?; contexts.insert(context); Ok((instance, contexts)) @@ -68,7 +71,7 @@ impl Instance { store: &HostRef, module: &HostRef, externs: &[Extern], - ) -> Result { + ) -> Result { let context = store.borrow_mut().context().clone(); let exports = store.borrow_mut().global_exports().clone(); let imports = module diff --git a/crates/api/src/lib.rs b/crates/api/src/lib.rs index cde6b0a336..22cd1f8f84 100644 --- a/crates/api/src/lib.rs +++ b/crates/api/src/lib.rs @@ -28,6 +28,6 @@ pub use crate::instance::Instance; pub use crate::module::Module; pub use crate::r#ref::{AnyRef, HostInfo, HostRef}; pub use crate::runtime::{Config, Engine, Store}; -pub use crate::trap::Trap; +pub use crate::trap::{FrameInfo, Trap, TrapInfo}; pub use crate::types::*; pub use crate::values::*; diff --git a/crates/api/src/trampoline/func.rs b/crates/api/src/trampoline/func.rs index eb0a496a2b..aa411cbb0d 100644 --- a/crates/api/src/trampoline/func.rs +++ b/crates/api/src/trampoline/func.rs @@ -96,6 +96,7 @@ unsafe extern "C" fn stub_fn(vmctx: *mut VMContext, call_id: u32, values_vec: *m 0 } Err(trap) => { + let trap = trap.trap_info_unchecked(); record_api_trap(trap); 1 } diff --git a/crates/api/src/trampoline/trap.rs b/crates/api/src/trampoline/trap.rs index bb8df5f567..e10f159f2d 100644 --- a/crates/api/src/trampoline/trap.rs +++ b/crates/api/src/trampoline/trap.rs @@ -1,7 +1,7 @@ use std::cell::Cell; use crate::r#ref::HostRef; -use crate::Trap; +use crate::TrapInfo; use wasmtime_environ::ir::{SourceLoc, TrapCode}; use wasmtime_environ::TrapInformation; use wasmtime_jit::trampoline::binemit; @@ -10,10 +10,10 @@ use wasmtime_jit::trampoline::binemit; pub const API_TRAP_CODE: TrapCode = TrapCode::User(13); thread_local! { - static RECORDED_API_TRAP: Cell>> = Cell::new(None); + static RECORDED_API_TRAP: Cell>> = Cell::new(None); } -pub fn record_api_trap(trap: HostRef) { +pub fn record_api_trap(trap: HostRef) { RECORDED_API_TRAP.with(|data| { let trap = Cell::new(Some(trap)); data.swap(&trap); @@ -24,7 +24,7 @@ pub fn record_api_trap(trap: HostRef) { }); } -pub fn take_api_trap() -> Option> { +pub fn take_api_trap() -> Option> { RECORDED_API_TRAP.with(|data| data.take()) } diff --git a/crates/api/src/trap.rs b/crates/api/src/trap.rs index dff98354d6..60c2d1f858 100644 --- a/crates/api/src/trap.rs +++ b/crates/api/src/trap.rs @@ -1,11 +1,88 @@ +use crate::instance::Instance; +use crate::r#ref::HostRef; +use std::fmt; +use std::sync::{Arc, Mutex}; use thiserror::Error; +#[derive(Debug)] +pub struct FrameInfo; + +impl FrameInfo { + pub fn instance(&self) -> *const Instance { + unimplemented!("FrameInfo::instance"); + } + + pub fn func_index() -> usize { + unimplemented!("FrameInfo::func_index"); + } + + pub fn func_offset() -> usize { + unimplemented!("FrameInfo::func_offset"); + } + + pub fn module_offset() -> usize { + unimplemented!("FrameInfo::module_offset"); + } +} + +#[derive(Debug)] +pub struct TrapInfo { + message: String, + trace: Vec, +} + +impl TrapInfo { + pub fn new>(message: I) -> Self { + Self { + message: message.into(), + trace: vec![], + } + } + + /// Returns a reference the `message` stored in `Trap`. + pub fn message(&self) -> &str { + &self.message + } + + pub fn origin(&self) -> Option<&FrameInfo> { + self.trace.first() + } + + pub fn trace(&self) -> &[FrameInfo] { + &self.trace + } +} + +/// A struct to hold unsafe TrapInfo host reference, designed +/// to be Send-able. The only access for it provided via the +/// Trap::trap_info_unchecked() method. +struct UnsafeTrapInfo(HostRef); + +impl UnsafeTrapInfo { + fn trap_info(&self) -> HostRef { + self.0.clone() + } +} + +unsafe impl Send for UnsafeTrapInfo {} + +impl fmt::Debug for UnsafeTrapInfo { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + write!(f, "UnsafeTrapInfo") + } +} + /// A struct representing an aborted instruction execution, with a message /// indicating the cause. #[derive(Error, Debug)] #[error("Wasm trap: {message}")] pub struct Trap { message: String, + info: Arc>, +} + +fn _assert_trap_is_sync_and_send(t: &Trap) -> (&dyn Sync, &dyn Send) { + (t, t) } impl Trap { @@ -15,20 +92,26 @@ impl Trap { /// let trap = wasmtime::Trap::new("unexpected error"); /// assert_eq!("unexpected error", trap.message()); /// ``` - pub fn new>(message: I) -> Trap { - Self { - message: message.into(), - } - } - - /// Create a `Trap` without defining a message for the trap. Mostly useful - /// for prototypes and tests. - pub fn fake() -> Trap { - Self::new("TODO trap") + pub fn new>(message: I) -> Self { + Trap::from(HostRef::new(TrapInfo::new(message))) } /// Returns a reference the `message` stored in `Trap`. pub fn message(&self) -> &str { &self.message } + + /// Returns inner TrapInfo assotiated with the Trap. + /// The method is unsafe: obtained TrapInfo is not thread safe. + pub(crate) unsafe fn trap_info_unchecked(&self) -> HostRef { + self.info.lock().unwrap().trap_info() + } +} + +impl From> for Trap { + fn from(trap_info: HostRef) -> Self { + let message = trap_info.borrow().message().to_string(); + let info = Arc::new(Mutex::new(UnsafeTrapInfo(trap_info))); + Trap { message, info } + } } diff --git a/crates/api/src/wasm.rs b/crates/api/src/wasm.rs index 40f4f32b14..7cd8961ca4 100644 --- a/crates/api/src/wasm.rs +++ b/crates/api/src/wasm.rs @@ -8,7 +8,7 @@ use super::{ AnyRef, Callable, Engine, ExportType, Extern, ExternType, Func, FuncType, Global, GlobalType, HostInfo, HostRef, ImportType, Instance, Limits, Memory, MemoryType, Module, Store, Table, - TableType, Trap, Val, ValType, + TableType, Trap, TrapInfo, Val, ValType, }; use std::rc::Rc; use std::{mem, ptr, slice}; @@ -317,7 +317,7 @@ pub type wasm_message_t = wasm_name_t; #[repr(C)] #[derive(Clone)] pub struct wasm_trap_t { - trap: HostRef, + trap_info: HostRef, } #[repr(C)] #[derive(Clone)] @@ -469,7 +469,8 @@ pub unsafe extern "C" fn wasm_func_call( ptr::null_mut() } Err(trap) => { - let trap = Box::new(wasm_trap_t { trap }); + let trap_info = trap.trap_info_unchecked(); + let trap = Box::new(wasm_trap_t { trap_info }); Box::into_raw(trap) } } @@ -539,7 +540,7 @@ impl wasm_val_t { } impl Callable for wasm_func_callback_t { - fn call(&self, params: &[Val], results: &mut [Val]) -> Result<(), HostRef> { + fn call(&self, params: &[Val], results: &mut [Val]) -> Result<(), Trap> { let params = params .iter() .map(|p| wasm_val_t::from_val(p)) @@ -549,7 +550,8 @@ impl Callable for wasm_func_callback_t { let out = unsafe { func(params.as_ptr(), out_results.as_mut_ptr()) }; if !out.is_null() { let trap: Box = unsafe { Box::from_raw(out) }; - return Err((*trap).into()); + let trap_info: HostRef = (*trap).into(); + return Err(Trap::from(trap_info)); } for i in 0..results.len() { results[i] = out_results[i].val(); @@ -558,9 +560,9 @@ impl Callable for wasm_func_callback_t { } } -impl Into> for wasm_trap_t { - fn into(self) -> HostRef { - self.trap +impl Into> for wasm_trap_t { + fn into(self) -> HostRef { + self.trap_info } } @@ -571,7 +573,7 @@ struct CallbackWithEnv { } impl Callable for CallbackWithEnv { - fn call(&self, params: &[Val], results: &mut [Val]) -> Result<(), HostRef> { + fn call(&self, params: &[Val], results: &mut [Val]) -> Result<(), Trap> { let params = params .iter() .map(|p| wasm_val_t::from_val(p)) @@ -581,7 +583,8 @@ impl Callable for CallbackWithEnv { let out = unsafe { func(self.env, params.as_ptr(), out_results.as_mut_ptr()) }; if !out.is_null() { let trap: Box = unsafe { Box::from_raw(out) }; - return Err((*trap).into()); + let trap_info: HostRef = (*trap).into(); + return Err(Trap::from(trap_info)); } for i in 0..results.len() { results[i] = out_results[i].val(); @@ -677,12 +680,13 @@ pub unsafe extern "C" fn wasm_instance_new( } Box::into_raw(instance) } - Err(_) => { + Err(trap) => { if !result.is_null() { - // TODO Unwrap trap from error - let trap = Box::new(wasm_trap_t { - trap: HostRef::new(Trap::new("trap during instantiation".to_string())), - }); + let trap_info = match trap.downcast::() { + Ok(trap) => trap.trap_info_unchecked(), + Err(_) => HostRef::new(TrapInfo::new("instance error".to_string())), + }; + let trap = Box::new(wasm_trap_t { trap_info }); (*result) = Box::into_raw(trap); } ptr::null_mut() @@ -925,7 +929,7 @@ pub unsafe extern "C" fn wasm_trap_new( } let message = String::from_utf8_lossy(message).to_string(); let trap = Box::new(wasm_trap_t { - trap: HostRef::new(Trap::new(message)), + trap_info: HostRef::new(TrapInfo::new(message)), }); Box::into_raw(trap) } @@ -933,7 +937,7 @@ pub unsafe extern "C" fn wasm_trap_new( #[no_mangle] pub unsafe extern "C" fn wasm_trap_message(trap: *const wasm_trap_t, out: *mut wasm_message_t) { let mut buffer = Vec::new(); - buffer.extend_from_slice((*trap).trap.borrow().message().as_bytes()); + buffer.extend_from_slice((*trap).trap_info.borrow().message().as_bytes()); buffer.reserve_exact(1); buffer.push(0); (*out).set_buffer(buffer); diff --git a/crates/api/tests/import_calling_export.rs b/crates/api/tests/import_calling_export.rs index dd714c248b..0157d5d315 100644 --- a/crates/api/tests/import_calling_export.rs +++ b/crates/api/tests/import_calling_export.rs @@ -20,7 +20,7 @@ fn test_import_calling_export() { } impl Callable for Callback { - fn call(&self, _params: &[Val], _results: &mut [Val]) -> Result<(), HostRef> { + fn call(&self, _params: &[Val], _results: &mut [Val]) -> Result<(), Trap> { self.other .borrow() .as_ref() diff --git a/crates/api/tests/traps.rs b/crates/api/tests/traps.rs index 7ead7b322c..25527fbfcd 100644 --- a/crates/api/tests/traps.rs +++ b/crates/api/tests/traps.rs @@ -7,8 +7,8 @@ fn test_trap_return() -> Result<(), String> { struct HelloCallback; impl Callable for HelloCallback { - fn call(&self, _params: &[Val], _results: &mut [Val]) -> Result<(), HostRef> { - Err(HostRef::new(Trap::new("test 123"))) + fn call(&self, _params: &[Val], _results: &mut [Val]) -> Result<(), Trap> { + Err(Trap::new("test 123")) } } @@ -32,7 +32,7 @@ fn test_trap_return() -> Result<(), String> { let imports = vec![hello_func.into()]; let instance = Instance::new(&store, &module, imports.as_slice()) - .map_err(|e| format!("failed to instantiate module: {}", e))?; + .map_err(|e| format!("failed to instantiate module: {:?}", e))?; let run_func = instance.exports()[0] .func() .expect("expected function export"); @@ -43,7 +43,7 @@ fn test_trap_return() -> Result<(), String> { .err() .expect("error calling function"); - assert_eq!(e.borrow().message(), "test 123"); + assert_eq!(e.message(), "test 123"); Ok(()) } diff --git a/crates/fuzzing/src/oracles/dummy.rs b/crates/fuzzing/src/oracles/dummy.rs index b20212a1db..829eb5206c 100644 --- a/crates/fuzzing/src/oracles/dummy.rs +++ b/crates/fuzzing/src/oracles/dummy.rs @@ -10,7 +10,7 @@ use wasmtime::{ pub fn dummy_imports( store: &HostRef, import_tys: &[ImportType], -) -> Result, HostRef> { +) -> Result, Trap> { let mut imports = Vec::with_capacity(import_tys.len()); for imp in import_tys { imports.push(match imp.ty() { @@ -45,7 +45,7 @@ impl DummyFunc { } impl Callable for DummyFunc { - fn call(&self, _params: &[Val], results: &mut [Val]) -> Result<(), HostRef> { + fn call(&self, _params: &[Val], results: &mut [Val]) -> Result<(), Trap> { for (ret_ty, result) in self.0.results().iter().zip(results) { *result = dummy_value(ret_ty)?; } @@ -55,38 +55,38 @@ impl Callable for DummyFunc { } /// Construct a dummy value for the given value type. -pub fn dummy_value(val_ty: &ValType) -> Result> { +pub fn dummy_value(val_ty: &ValType) -> Result { Ok(match val_ty { ValType::I32 => Val::I32(0), ValType::I64 => Val::I64(0), ValType::F32 => Val::F32(0), ValType::F64 => Val::F64(0), ValType::V128 => { - return Err(HostRef::new(Trap::new( + return Err(Trap::new( "dummy_value: unsupported function return type: v128".to_string(), - ))) + )) } ValType::AnyRef => { - return Err(HostRef::new(Trap::new( + return Err(Trap::new( "dummy_value: unsupported function return type: anyref".to_string(), - ))) + )) } ValType::FuncRef => { - return Err(HostRef::new(Trap::new( + return Err(Trap::new( "dummy_value: unsupported function return type: funcref".to_string(), - ))) + )) } }) } /// Construct a dummy global for the given global type. -pub fn dummy_global(store: &HostRef, ty: GlobalType) -> Result> { +pub fn dummy_global(store: &HostRef, ty: GlobalType) -> Result { let val = dummy_value(ty.content())?; Ok(Global::new(store, ty, val)) } /// Construct a dummy table for the given table type. -pub fn dummy_table(store: &HostRef, ty: TableType) -> Result> { +pub fn dummy_table(store: &HostRef, ty: TableType) -> Result { let init_val = dummy_value(&ty.element())?; Ok(Table::new(store, ty, init_val)) } diff --git a/crates/misc/py/src/function.rs b/crates/misc/py/src/function.rs index 661566dadc..7093ea4aff 100644 --- a/crates/misc/py/src/function.rs +++ b/crates/misc/py/src/function.rs @@ -82,7 +82,7 @@ impl wasmtime::Callable for WrappedFn { &self, params: &[wasmtime::Val], returns: &mut [wasmtime::Val], - ) -> Result<(), wasmtime::HostRef> { + ) -> Result<(), wasmtime::Trap> { let gil = Python::acquire_gil(); let py = gil.python(); diff --git a/crates/test-programs/tests/wasm_tests/runtime.rs b/crates/test-programs/tests/wasm_tests/runtime.rs index ad45a2ece9..b8c88308ba 100644 --- a/crates/test-programs/tests/wasm_tests/runtime.rs +++ b/crates/test-programs/tests/wasm_tests/runtime.rs @@ -91,7 +91,7 @@ pub fn instantiate(data: &[u8], bin_name: &str, workspace: Option<&Path>) -> any .borrow() .call(&[]) { - bail!("trapped: {:?}", trap.borrow()); + bail!("trapped: {:?}", trap); } Ok(()) diff --git a/crates/wast/src/spectest.rs b/crates/wast/src/spectest.rs index b94319fc7d..6dc7d976de 100644 --- a/crates/wast/src/spectest.rs +++ b/crates/wast/src/spectest.rs @@ -9,9 +9,9 @@ struct MyCall(F); impl Callable for MyCall where - F: Fn(&[Val], &mut [Val]) -> Result<(), HostRef>, + F: Fn(&[Val], &mut [Val]) -> Result<(), Trap>, { - fn call(&self, params: &[Val], results: &mut [Val]) -> Result<(), HostRef> { + fn call(&self, params: &[Val], results: &mut [Val]) -> Result<(), Trap> { (self.0)(params, results) } } @@ -19,7 +19,7 @@ where fn wrap( store: &HostRef, ty: FuncType, - callable: impl Fn(&[Val], &mut [Val]) -> Result<(), HostRef> + 'static, + callable: impl Fn(&[Val], &mut [Val]) -> Result<(), Trap> + 'static, ) -> Func { Func::new(store, ty, Rc::new(MyCall(callable))) } diff --git a/crates/wast/src/wast.rs b/crates/wast/src/wast.rs index 1f8dad270d..8fd11f8995 100644 --- a/crates/wast/src/wast.rs +++ b/crates/wast/src/wast.rs @@ -36,7 +36,7 @@ pub struct WastContext { enum Outcome> { Ok(T), - Trap(HostRef), + Trap(Trap), } impl WastContext { @@ -101,7 +101,7 @@ impl WastContext { .filter_map(|e| e.downcast_ref::()) .next(); if let Some(InstantiationError::StartTrap(msg)) = err { - return Ok(Outcome::Trap(HostRef::new(Trap::new(msg.clone())))); + return Ok(Outcome::Trap(Trap::new(msg.clone()))); } return Err(e); } @@ -139,7 +139,7 @@ impl WastContext { fn module(&mut self, instance_name: Option<&str>, module: &[u8]) -> Result<()> { let instance = match self.instantiate(module)? { Outcome::Ok(i) => i, - Outcome::Trap(e) => bail!("instantiation failed with: {}", e.borrow().message()), + Outcome::Trap(e) => bail!("instantiation failed with: {}", e.message()), }; if let Some(name) = instance_name { self.instances.insert(name.to_string(), instance.clone()); @@ -241,7 +241,6 @@ impl WastContext { } } Outcome::Trap(t) => { - let t = t.borrow(); bail!("{}\nunexpected trap: {}", context(span), t.message()) } }, @@ -254,7 +253,6 @@ impl WastContext { bail!("{}\nexpected trap, got {:?}", context(span), values) } Outcome::Trap(t) => { - let t = t.borrow(); if t.message().contains(message) { continue; } @@ -283,7 +281,6 @@ impl WastContext { bail!("{}\nexpected trap, got {:?}", context(span), values) } Outcome::Trap(t) => { - let t = t.borrow(); if t.message().contains(message) { continue; } @@ -315,7 +312,6 @@ impl WastContext { } } Outcome::Trap(t) => { - let t = t.borrow(); bail!("{}\nunexpected trap: {}", context(span), t.message()) } } @@ -340,7 +336,6 @@ impl WastContext { } } Outcome::Trap(t) => { - let t = t.borrow(); bail!("{}\nunexpected trap: {}", context(span), t.message()) } } @@ -365,7 +360,6 @@ impl WastContext { } } Outcome::Trap(t) => { - let t = t.borrow(); bail!("{}\nunexpected trap: {}", context(span), t.message()) } } @@ -390,7 +384,6 @@ impl WastContext { } } Outcome::Trap(t) => { - let t = t.borrow(); bail!("{}\nunexpected trap: {}", context(span), t.message()) } } @@ -415,7 +408,6 @@ impl WastContext { } } Outcome::Trap(t) => { - let t = t.borrow(); bail!("{}\nunexpected trap: {}", context(span), t.message()) } } @@ -440,7 +432,6 @@ impl WastContext { } } Outcome::Trap(t) => { - let t = t.borrow(); bail!("{}\nunexpected trap: {}", context(span), t.message()) } } diff --git a/src/bin/wasmtime.rs b/src/bin/wasmtime.rs index fc0c1f319d..4a8be1441f 100644 --- a/src/bin/wasmtime.rs +++ b/src/bin/wasmtime.rs @@ -349,7 +349,10 @@ fn instantiate_module( }) .collect::, _>>()?; - let instance = HostRef::new(Instance::new(store, &module, &imports)?); + let instance = HostRef::new(match Instance::new(store, &module, &imports) { + Ok(instance) => instance, + Err(trap) => bail!("Failed to instantiate {:?}: {:?}", path, trap), + }); Ok((instance, module, data)) }