wasmtime 0.3.0

Command-line interface for Wasmtime
Documentation
diff --git a/lib/runtime/build.rs b/lib/runtime/build.rs
index d7c9e57..43e96f4 100644
--- a/lib/runtime/build.rs
+++ b/lib/runtime/build.rs
@@ -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
--- a/lib/runtime/signalhandlers/SignalHandlers.cpp
+++ b/lib/runtime/signalhandlers/SignalHandlers.cpp
@@ -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
--- a/lib/runtime/signalhandlers/SignalHandlers.h
+++ b/lib/runtime/signalhandlers/SignalHandlers.h
@@ -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
--- a/lib/runtime/src/traphandlers.rs
+++ b/lib/runtime/src/traphandlers.rs
@@ -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(())
 }