diff --git a/CHANGELOG.md b/CHANGELOG.md index 43b03b76e89..4dcbf5438fe 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,7 @@ ## **[Unreleased]** +- [#1305](https://github.com/wasmerio/wasmer/pull/1305) Handle panics from DynamicFunc. - [#1301](https://github.com/wasmerio/wasmer/pull/1301) Update supported stable Rust version to 1.41.1. - [#1300](https://github.com/wasmerio/wasmer/pull/1300) Add support for multiple versions of WASI tests: wasitests now test all versions of WASI. - [#1285](https://github.com/wasmerio/wasmer/pull/1285) Greatly improve errors in `wasmer-interface-types` diff --git a/lib/runtime-core-tests/tests/imports.rs b/lib/runtime-core-tests/tests/imports.rs index e44d5159f8f..f9ac6df9ecf 100644 --- a/lib/runtime-core-tests/tests/imports.rs +++ b/lib/runtime-core-tests/tests/imports.rs @@ -77,6 +77,7 @@ fn imported_functions_forms(test: &dyn Fn(&Instance)) { (import "env" "callback_fn" (func $callback_fn (type $type))) (import "env" "callback_closure" (func $callback_closure (type $type))) (import "env" "callback_fn_dynamic" (func $callback_fn_dynamic (type $type))) + (import "env" "callback_fn_dynamic_panic" (func $callback_fn_dynamic_panic (type $type))) (import "env" "callback_closure_dynamic_0" (func $callback_closure_dynamic_0)) (import "env" "callback_closure_dynamic_1" (func $callback_closure_dynamic_1 (param i32) (result i32))) (import "env" "callback_closure_dynamic_2" (func $callback_closure_dynamic_2 (param i32 i64) (result i64))) @@ -104,6 +105,10 @@ fn imported_functions_forms(test: &dyn Fn(&Instance)) { get_local 0 call $callback_fn_dynamic) + (func (export "function_fn_dynamic_panic") (type $type) + get_local 0 + call $callback_fn_dynamic_panic) + (func (export "function_closure_dynamic_0") call $callback_closure_dynamic_0) @@ -191,6 +196,12 @@ fn imported_functions_forms(test: &dyn Fn(&Instance)) { callback_fn_dynamic, ), + // Polymorphic function that panics. + "callback_fn_dynamic_panic" => DynamicFunc::new( + Arc::new(FuncSig::new(vec![Type::I32], vec![Type::I32])), + callback_fn_dynamic_panic, + ), + // Polymorphic closure “closures”. "callback_closure_dynamic_0" => DynamicFunc::new( Arc::new(FuncSig::new(vec![], vec![])), @@ -325,6 +336,10 @@ fn callback_fn_dynamic(_: &mut vm::Ctx, inputs: &[Value]) -> Vec { } } +fn callback_fn_dynamic_panic(_: &mut vm::Ctx, _: &[Value]) -> Vec { + panic!("test"); +} + fn callback_fn_with_vmctx(vmctx: &mut vm::Ctx, n: i32) -> Result { let memory = vmctx.memory(0); let shift_: i32 = memory.view()[0].get(); @@ -357,6 +372,7 @@ macro_rules! test { test!(test_fn, function_fn(i32) -> i32, (1) == Ok(2)); test!(test_closure, function_closure(i32) -> i32, (1) == Ok(2)); test!(test_fn_dynamic, function_fn_dynamic(i32) -> i32, (1) == Ok(2)); +test!(test_fn_dynamic_panic, function_fn_dynamic_panic(i32) -> i32, (1) == Err(RuntimeError(Box::new("test")))); test!( test_closure_dynamic_0, function_closure_dynamic_0(()) -> (), diff --git a/lib/runtime-core/src/typed_func.rs b/lib/runtime-core/src/typed_func.rs index 6578042a710..a34960134c2 100644 --- a/lib/runtime-core/src/typed_func.rs +++ b/lib/runtime-core/src/typed_func.rs @@ -334,7 +334,14 @@ impl<'a> DynamicFunc<'a> { } }) .collect(); - (ctx.func)(vmctx, &args) + match panic::catch_unwind(panic::AssertUnwindSafe(|| (ctx.func)(vmctx, &args))) { + Ok(x) => x, + Err(e) => { + // At this point, there is an error that needs to be trapped. + drop(args); // Release the Vec which will leak otherwise. + (&*vmctx.module).runnable_module.do_early_trap(e) + } + } } unsafe extern "C" fn enter_host_polymorphic_i( ctx: *const CallContext,