Skip to content

Commit

Permalink
Make sure ExecutionError::Trap is returned when a trap is triggered
Browse files Browse the repository at this point in the history
  • Loading branch information
koute committed Sep 5, 2023
1 parent 81165ff commit 81e5e19
Show file tree
Hide file tree
Showing 2 changed files with 53 additions and 7 deletions.
8 changes: 2 additions & 6 deletions crates/polkavm/src/api.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1313,9 +1313,7 @@ impl<T> Func<T> {
));
}
Err(ExecutionError::Trap(trap)) => {
return Err(ExecutionError::Error(
format!("execution trapped while calling '{}': {}", export.prototype().name(), trap).into(),
));
return Err(ExecutionError::Trap(trap));
}
}

Expand Down Expand Up @@ -1411,9 +1409,7 @@ where
));
}
Err(ExecutionError::Trap(trap)) => {
return Err(ExecutionError::Error(
format!("execution trapped while calling '{}': {}", export.prototype().name(), trap).into(),
));
return Err(ExecutionError::Trap(trap));
}
}

Expand Down
52 changes: 51 additions & 1 deletion crates/polkavm/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ pub use crate::error::Error;

#[cfg(test)]
mod tests {
use crate::{Caller, CallerRef, Config, Engine, Linker, Module, ProgramBlob, Reg, Trap};
use crate::{Caller, CallerRef, Config, Engine, ExecutionError, Linker, Module, ProgramBlob, Reg, Trap, Val};
use std::cell::RefCell;
use std::rc::Rc;

Expand Down Expand Up @@ -87,4 +87,54 @@ mod tests {
let result = std::panic::catch_unwind(std::panic::AssertUnwindSafe(|| caller.get_reg(Reg::A0)));
assert!(result.is_err());
}

#[test]
fn trapping_from_hostcall_handler_works() {
let blob = ProgramBlob::parse(RAW_BLOB).unwrap();
let config = Config::default();
let engine = Engine::new(&config).unwrap();
let module = Module::from_blob(&engine, &blob).unwrap();
let mut linker = Linker::new(&engine);

enum Kind {
Ok,
Trap,
}

linker
.func_wrap("get_third_number", move |caller: Caller<Kind>| -> Result<u32, Trap> {
match *caller.data() {
Kind::Ok => Ok(100),
Kind::Trap => Err(Trap::default()),
}
})
.unwrap();

let instance_pre = linker.instantiate_pre(&module).unwrap();
let instance = instance_pre.instantiate().unwrap();

let result = instance
.get_typed_func::<(u32, u32), u32>("add_numbers")
.unwrap()
.call(&mut Kind::Ok, (1, 10));
assert!(matches!(result, Ok(111)));

let result = instance
.get_typed_func::<(u32, u32), u32>("add_numbers")
.unwrap()
.call(&mut Kind::Trap, (1, 10));
assert!(matches!(result, Err(ExecutionError::Trap(..))));

let result = instance
.get_func("add_numbers")
.unwrap()
.call(&mut Kind::Ok, &[Val::from(1), Val::from(10)]);
assert!(matches!(result, Ok(Some(Val::I32(111)))));

let result = instance
.get_func("add_numbers")
.unwrap()
.call(&mut Kind::Trap, &[Val::from(1), Val::from(10)]);
assert!(matches!(result, Err(ExecutionError::Trap(..))));
}
}

0 comments on commit 81e5e19

Please sign in to comment.