diff --git a/src/bin/instantiate.rs b/src/bin/instantiate.rs index 7e1e7c1f92..646b65b092 100644 --- a/src/bin/instantiate.rs +++ b/src/bin/instantiate.rs @@ -67,8 +67,7 @@ fn main() { } let module = load_from_file(&args[1]).try_parse_names(); - - let _ = ModuleInstance::new( + let res = ModuleInstance::new( &module, &ImportsBuilder::default() // Well known imports. @@ -82,6 +81,11 @@ fn main() { .expect("Failed to instantiate module") .run_start(&mut NopExternals) .expect("Failed to run start function in module") - .invoke_export("_start", &[], &mut NopExternals) - .unwrap(); + .invoke_export("_start", &[], &mut NopExternals); + + // Prints anyway + match res { + Err(Error::Trap(err)) => println!("{:#?}", err), + r => println!("{:#?}", r), + } } diff --git a/src/func.rs b/src/func.rs index 42df5061a9..66df696e4f 100644 --- a/src/func.rs +++ b/src/func.rs @@ -168,16 +168,19 @@ impl FuncInstance { FuncInstanceInternal::Internal { .. } => { let mut interpreter = Interpreter::new(func, args, None)?; let res = interpreter.start_execution(externals); - if res.is_err() { + if let Err(trap) = res { let mut stack = interpreter .trace() .iter() .map(|n| format!("{:#}[{}]", rustc_demangle::demangle(&n.1), n.0)) .collect::>(); + + // Append the panicing trap + stack.append(&mut trap.wasm_trace().clone()); stack.reverse(); // Embed this info into the trap - res.map_err(|e| e.set_wasm_trace(stack)) + Err(trap.set_wasm_trace(stack)) } else { res } diff --git a/src/lib.rs b/src/lib.rs index d4e0daa3c4..5d9d335221 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -148,6 +148,31 @@ impl Trap { } } + /// Embed a new context into wasm trace + pub fn wasm_trace_with(mut self, info: Option<&(usize, String)>) -> Trap { + if let Some(info) = info { + self.wasm_trace.push(format!( + "{:#}[{}]", + rustc_demangle::demangle(&info.1), + info.0 + )); + } + self + } + + /// Embed a new context into wasm trace + pub fn wasm_trace_with_kind(kind: TrapKind, info: Option<&(usize, String)>) -> Trap { + let mut trap: Self = kind.into(); + if let Some(info) = info { + trap.wasm_trace.push(format!( + "{:#}[{}]", + rustc_demangle::demangle(&info.1), + info.0 + )); + } + trap + } + /// Returns wasm trace pub fn wasm_trace(&self) -> &Vec { &self.wasm_trace diff --git a/src/runner.rs b/src/runner.rs index 7933330986..489e0c3821 100644 --- a/src/runner.rs +++ b/src/runner.rs @@ -275,12 +275,14 @@ impl Interpreter { if !function_context.is_initialized() { // Initialize stack frame for the function call. - function_context.initialize(&function_body.locals, &mut self.value_stack)?; + function_context + .initialize(&function_body.locals, &mut self.value_stack) + .map_err(|e| Trap::wasm_trace_with_kind(e, function_ref.clone().info()))?; } let function_return = self .do_run_function(&mut function_context, &function_body.code) - .map_err(Trap::new)?; + .map_err(|e| Trap::wasm_trace_with_kind(e, function_ref.clone().info()))?; match function_return { RunResult::Return => { @@ -292,7 +294,10 @@ impl Interpreter { } RunResult::NestedCall(nested_func) => { if self.call_stack.is_full() { - return Err(TrapKind::StackOverflow.into()); + return Err(Trap::wasm_trace_with_kind( + TrapKind::StackOverflow, + function_ref.clone().info(), + )); } match *nested_func.as_internal() { @@ -315,7 +320,9 @@ impl Interpreter { nested_func.signature().return_type(), ); } - return Err(trap); + return Err( + trap.wasm_trace_with(function_ref.clone().info()) + ); } }; @@ -323,13 +330,16 @@ impl Interpreter { let value_ty = return_val.as_ref().map(|val| val.value_type()); let expected_ty = nested_func.signature().return_type(); if value_ty != expected_ty { - return Err(TrapKind::UnexpectedSignature.into()); + return Err(Trap::wasm_trace_with_kind( + TrapKind::StackOverflow, + function_ref.clone().info(), + )); } if let Some(return_val) = return_val { - self.value_stack - .push(return_val.into()) - .map_err(Trap::new)?; + self.value_stack.push(return_val.into()).map_err(|trap| { + Trap::wasm_trace_with_kind(trap, function_ref.clone().info()) + })?; } } }