diff --git a/lib/runtime/build.rs b/lib/runtime/build.rs
index d7c9e57..43e96f4 100644
@@ -17,7 +17,11 @@ fn main() {
.header("signalhandlers/SignalHandlers.h")
.whitelist_type("TrapContext")
.whitelist_type("jmp_buf")
- .whitelist_function("EnsureEagerSignalHandlers");
+ .whitelist_function("EnsureEagerSignalHandlers")
+ .whitelist_function("setjmp")
+ .whitelist_function("longjmp")
+ .whitelist_function("call_trampoline")
+ .whitelist_function("call");
// If we're compiling for Darwin, compile in extra Darwin support routines.
if Regex::new(r"-darwin[[:digit:].]*$")
diff --git a/lib/runtime/signalhandlers/SignalHandlers.cpp b/lib/runtime/signalhandlers/SignalHandlers.cpp
index 6c3989a..63988b8 100644
@@ -819,3 +819,41 @@ EnsureDarwinMachPorts()
#endif
return true;
}
+
+extern "C" void push_jmp_buf(const jmp_buf *);
+
+bool call_trampoline(const void *callee, uint8_t *values_vec, void *vmctx)
+{
+ printf("# call_trampoline here\n");
+ // Set a setjmp catch point.
+ jmp_buf buf;
+ if (setjmp(buf) != 0) {
+ printf("# setjmp false\n");
+ return false;
+ }
+ printf("# push\n");
+ push_jmp_buf(&buf);
+
+ printf("# call the func\n");
+ // Call the function!
+ void (*func)(uint8_t *, void *) =
+ (void (*)(uint8_t *, void *)) callee;
+ func(values_vec, vmctx);
+ printf("# return true\n");
+ return true;
+}
+
+bool call(const void *callee, void *vmctx)
+{
+ // Set a setjmp catch point.
+ jmp_buf buf;
+ if (setjmp(buf) != 0) {
+ return false;
+ }
+ push_jmp_buf(&buf);
+
+ // Call the function!
+ void (*func)(void *) = (void (*)(void *)) callee;
+ func(vmctx);
+ return true;
+}
diff --git a/lib/runtime/signalhandlers/SignalHandlers.h b/lib/runtime/signalhandlers/SignalHandlers.h
index a7214e9..f32d373 100644
@@ -41,6 +41,9 @@ EnsureEagerSignalHandlers(void);
bool
EnsureDarwinMachPorts(void);
+bool call_trampoline(const void *callee, uint8_t *values_vec, void *vmctx);
+bool call(const void *callee, void *vmctx);
+
#ifdef __cplusplus
} // extern "C"
#endif
diff --git a/lib/runtime/src/traphandlers.rs b/lib/runtime/src/traphandlers.rs
index c2c35c7..aa915e8 100644
@@ -2,7 +2,7 @@
//! signalhandling mechanisms.
use libc::c_int;
-use signalhandlers::jmp_buf;
+use signalhandlers::{call, call_trampoline, jmp_buf};
use std::cell::{Cell, RefCell};
use std::mem;
use std::ptr;
@@ -15,13 +15,12 @@ use vmcontext::{VMContext, VMFunctionBody};
// or require any cleanups, and we never unwind through non-wasm frames.
// In the future, we'll likely replace this with fancier stack unwinding.
extern "C" {
- fn setjmp(env: *mut jmp_buf) -> c_int;
fn longjmp(env: *const jmp_buf, val: c_int) -> !;
}
thread_local! {
static TRAP_PC: Cell<*const u8> = Cell::new(ptr::null());
- static JMP_BUFS: RefCell<Vec<jmp_buf>> = RefCell::new(Vec::new());
+ static JMP_BUFS: RefCell<Vec<*const jmp_buf>> = RefCell::new(Vec::new());
}
/// Record the Trap code and wasm bytecode offset in TLS somewhere
@@ -40,7 +39,7 @@ pub extern "C" fn RecordTrap(pc: *const u8) {
pub extern "C" fn Unwind() {
JMP_BUFS.with(|bufs| {
let buf = bufs.borrow_mut().pop().unwrap();
- unsafe { longjmp(&buf, 1) };
+ unsafe { longjmp(buf, 1) };
})
}
@@ -81,7 +80,8 @@ fn trap_message(_vmctx: *mut VMContext) -> String {
format!("wasm trap at {:?}", pc)
}
-fn push_jmp_buf(buf: jmp_buf) {
+#[no_mangle]
+pub extern "C" fn push_jmp_buf(buf: *const jmp_buf) {
JMP_BUFS.with(|bufs| bufs.borrow_mut().push(buf));
}
@@ -97,19 +97,13 @@ pub unsafe extern "C" fn wasmtime_call_trampoline(
// Reset JMP_BUFS if the stack is unwound through this point.
let _guard = ScopeGuard::new();
- println!("calling setjmp");
- // Set a setjmp catch point.
- let mut buf = mem::uninitialized();
- if setjmp(&mut buf) != 0 {
- println!("caught the trap");
+ if !call_trampoline(
+ callee as *const libc::c_void,
+ values_vec,
+ vmctx as *mut libc::c_void,
+ ) {
return Err(trap_message(vmctx));
}
- println!("doing the call");
- push_jmp_buf(buf);
-
- // Call the function!
- let func: fn(*mut u8, *mut VMContext) = mem::transmute(callee);
- func(values_vec, vmctx);
Ok(())
}
@@ -124,16 +118,9 @@ pub unsafe extern "C" fn wasmtime_call(
// Reset JMP_BUFS if the stack is unwound through this point.
let _guard = ScopeGuard::new();
- // Set a setjmp catch point.
- let mut buf = mem::uninitialized();
- if setjmp(&mut buf) != 0 {
+ if !call(callee as *const libc::c_void, vmctx as *mut libc::c_void) {
return Err(trap_message(vmctx));
}
- push_jmp_buf(buf);
-
- // Call the function!
- let func: fn(*mut VMContext) = mem::transmute(callee);
- func(vmctx);
Ok(())
}