Skip to content

Commit

Permalink
test: impprove panic reporting
Browse files Browse the repository at this point in the history
Signed-off-by: Henry Gressmann <mail@henrygressmann.de>
  • Loading branch information
explodingcamera committed Jan 4, 2024
1 parent c0dbf46 commit ca1837b
Show file tree
Hide file tree
Showing 7 changed files with 46 additions and 15 deletions.
2 changes: 1 addition & 1 deletion crates/cli/src/bin.rs
Original file line number Diff line number Diff line change
Expand Up @@ -117,7 +117,7 @@ fn run(module: Module, func: Option<String>, args: Vec<WasmValue>) -> Result<()>
let instance = module.instantiate(&mut store)?;

if let Some(func) = func {
let func = instance.get_func(&store, &func)?;
let func = instance.exported_func_by_name(&store, &func)?;
let res = func.call(&mut store, &args)?;
info!("{res:?}");
}
Expand Down
13 changes: 11 additions & 2 deletions crates/tinywasm/src/instance.rs
Original file line number Diff line number Diff line change
Expand Up @@ -58,8 +58,17 @@ impl ModuleInstance {
&self.0.types[addr as usize]
}

// resolve a function address to the index of the function in the store
pub(crate) fn func_addr(&self, addr: FuncAddr) -> FuncAddr {
self.0.func_addrs[addr as usize]
}

pub(crate) fn func_addrs(&self) -> &[FuncAddr] {
&self.0.func_addrs
}

/// Get an exported function by name
pub fn get_func(&self, store: &Store, name: &str) -> Result<FuncHandle> {
pub fn exported_func_by_name(&self, store: &Store, name: &str) -> Result<FuncHandle> {
if self.0.store_id != store.id() {
return Err(Error::InvalidStore);
}
Expand Down Expand Up @@ -90,7 +99,7 @@ impl ModuleInstance {
P: IntoWasmValueTuple,
R: FromWasmValueTuple,
{
let func = self.get_func(store, name)?;
let func = self.exported_func_by_name(store, name)?;
Ok(TypedFuncHandle {
func,
marker: core::marker::PhantomData,
Expand Down
9 changes: 7 additions & 2 deletions crates/tinywasm/src/runtime/executor/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,10 @@ use traits::*;

impl DefaultRuntime {
pub(crate) fn exec(&self, store: &mut Store, stack: &mut Stack, module: ModuleInstance) -> Result<()> {
log::info!("exports: {:?}", module.exports());
log::info!("func_addrs: {:?}", module.func_addrs());
log::info!("store funcs: {:?}", store.data.funcs.len());

// The current call frame, gets updated inside of exec_one
let mut cf = stack.call_stack.pop()?;

Expand Down Expand Up @@ -106,8 +110,9 @@ fn exec_one(
Call(v) => {
debug!("start call");
// prepare the call frame
let func = store.get_func(*v as usize)?;
let func_ty = module.func_ty(*v);
let func_idx = module.func_addr(*v);
let func = store.get_func(func_idx as usize)?;
let func_ty = module.func_ty(func_idx);

debug!("params: {:?}", func_ty.params);
debug!("stack: {:?}", stack.values);
Expand Down
7 changes: 5 additions & 2 deletions crates/tinywasm/src/store.rs
Original file line number Diff line number Diff line change
Expand Up @@ -124,18 +124,21 @@ impl Store {
Ok(())
}

/// Add functions to the store, returning their addresses in the store
pub(crate) fn add_funcs(&mut self, funcs: Vec<Function>, idx: ModuleInstanceAddr) -> Vec<FuncAddr> {
let mut func_addrs = Vec::with_capacity(funcs.len());
let func_count = self.data.funcs.len();
let mut func_addrs = Vec::with_capacity(func_count);
for (i, func) in funcs.into_iter().enumerate() {
self.data.funcs.push(Rc::new(FunctionInstance {
func,
_module_instance: idx,
}));
func_addrs.push(i as FuncAddr);
func_addrs.push((i + func_count) as FuncAddr);
}
func_addrs
}

/// Get the function at the actual index in the store
pub(crate) fn get_func(&self, addr: usize) -> Result<&Rc<FunctionInstance>> {
self.data
.funcs
Expand Down
2 changes: 0 additions & 2 deletions crates/tinywasm/tests/testsuite/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -161,8 +161,6 @@ impl TestGroup {
}

fn stats(&self) -> (usize, usize) {
log::error!("stats: {:?}", self.tests);

let mut passed_count = 0;
let mut failed_count = 0;

Expand Down
10 changes: 5 additions & 5 deletions crates/tinywasm/tests/testsuite/run.rs
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ impl TestSuite {
debug!("got wat module");

let result = catch_unwind_silent(move || parse_module_bytes(&module.encode().unwrap()))
.map_err(|e| eyre!("failed to parse module: {:?}", e))
.map_err(|e| eyre!("failed to parse module: {:?}", try_downcast_panic(e)))
.and_then(|res| res);

match &result {
Expand All @@ -77,7 +77,7 @@ impl TestSuite {
};

let res = catch_unwind_silent(|| parse_module_bytes(&module))
.map_err(|e| eyre!("failed to parse module: {:?}", e))
.map_err(|e| eyre!("failed to parse module: {:?}", try_downcast_panic(e)))
.and_then(|res| res);

test_group.add_result(
Expand All @@ -96,7 +96,7 @@ impl TestSuite {
message: _,
} => {
let res = catch_unwind_silent(move || parse_module_bytes(&module.encode().unwrap()))
.map_err(|e| eyre!("failed to parse module: {:?}", e))
.map_err(|e| eyre!("failed to parse module: {:?}", try_downcast_panic(e)))
.and_then(|res| res);

test_group.add_result(
Expand Down Expand Up @@ -133,7 +133,7 @@ impl TestSuite {
Err(err) => test_group.add_result(
&format!("AssertTrap({})", i),
span.linecol_in(wast),
Err(eyre!("test panicked: {:?}", err)),
Err(eyre!("test panicked: {:?}", try_downcast_panic(err))),
),
Ok(Err(tinywasm::Error::Trap(_))) => {
test_group.add_result(&format!("AssertTrap({})", i), span.linecol_in(wast), Ok(()))
Expand Down Expand Up @@ -222,7 +222,7 @@ impl TestSuite {
});

let res = res
.map_err(|e| eyre!("test panicked: {:?}", e.downcast_ref::<&str>()))
.map_err(|e| eyre!("test panicked: {:?}", try_downcast_panic(e)))
.and_then(|r| r);

test_group.add_result(
Expand Down
18 changes: 17 additions & 1 deletion crates/tinywasm/tests/testsuite/util.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,22 @@ use std::panic;
use eyre::{eyre, Result};
use tinywasm_types::{TinyWasmModule, WasmValue};

pub fn try_downcast_panic(panic: Box<dyn std::any::Any + Send>) -> String {
let info = panic
.downcast_ref::<panic::PanicInfo>()
.or(None)
.map(|p| p.to_string())
.clone();
let info_string = panic.downcast_ref::<String>().cloned();
let info_str = panic.downcast::<&str>().ok().map(|s| *s);

info.unwrap_or(
info_str
.unwrap_or(&info_string.unwrap_or("unknown panic".to_owned()))
.to_string(),
)
}

pub fn exec_fn(
module: Option<&TinyWasmModule>,
name: &str,
Expand All @@ -15,7 +31,7 @@ pub fn exec_fn(
let mut store = tinywasm::Store::new();
let module = tinywasm::Module::from(module);
let instance = module.instantiate(&mut store)?;
instance.get_func(&store, name)?.call(&mut store, args)
instance.exported_func_by_name(&store, name)?.call(&mut store, args)
}

pub fn catch_unwind_silent<F: FnOnce() -> R + panic::UnwindSafe, R>(f: F) -> std::thread::Result<R> {
Expand Down

0 comments on commit ca1837b

Please sign in to comment.