diff --git a/lib/llvm-backend/cpp/object_loader.hh b/lib/llvm-backend/cpp/object_loader.hh index 0d6bcc603..f1b53f156 100644 --- a/lib/llvm-backend/cpp/object_loader.hh +++ b/lib/llvm-backend/cpp/object_loader.hh @@ -61,15 +61,15 @@ struct UncatchableException : WasmException struct UserException : UncatchableException { public: - UserException(std::string msg) : msg(msg) {} + UserException(size_t data, size_t vtable) : data(data), vtable(vtable) {} virtual std::string description() const noexcept override { - return std::string("user exception: ") + msg; + return "user exception"; } - private: - std::string msg; + // The parts of a `Box`. + size_t data, vtable; }; struct WasmTrap : UncatchableException @@ -176,6 +176,12 @@ extern "C" delete module; } + // Throw a fat pointer that's assumed to be `*mut dyn Any` on the rust + // side. + [[noreturn]] void throw_any(size_t data, size_t vtable) { + throw UserException(data, vtable); + } + bool invoke_trampoline( trampoline_t trampoline, void *ctx, diff --git a/lib/llvm-backend/src/backend.rs b/lib/llvm-backend/src/backend.rs index 1a82cfaf2..f40a6dfb2 100644 --- a/lib/llvm-backend/src/backend.rs +++ b/lib/llvm-backend/src/backend.rs @@ -75,7 +75,11 @@ extern "C" { fn module_delete(module: *mut LLVMModule); fn get_func_symbol(module: *mut LLVMModule, name: *const c_char) -> *const vm::Func; - fn throw_trap(ty: i32); + fn throw_trap(ty: i32) -> !; + + /// This should be the same as spliting up the fat pointer into two arguments, + /// but this is cleaner, I think? + fn throw_any(data: *mut dyn Any) -> !; #[allow(improper_ctypes)] fn invoke_trampoline( @@ -433,8 +437,8 @@ impl ProtectedCaller for LLVMProtectedCaller { } impl UserTrapper for Placeholder { - unsafe fn do_early_trap(&self, _data: Box) -> ! { - unimplemented!("do early trap") + unsafe fn do_early_trap(&self, data: Box) -> ! { + throw_any(Box::leak(data)) } } diff --git a/lib/runtime/examples/call.rs b/lib/runtime/examples/call.rs index 104fa9692..12f149062 100644 --- a/lib/runtime/examples/call.rs +++ b/lib/runtime/examples/call.rs @@ -32,11 +32,11 @@ fn get_wasm() -> Vec { wat2wasm(WAT).unwrap() } -fn foobar(ctx: &mut Ctx) -> i32 { +fn foobar(_ctx: &mut Ctx) -> i32 { 42 } -fn do_panic(ctx: &mut Ctx) -> Result { +fn do_panic(_ctx: &mut Ctx) -> Result { Err("error".to_string()) }