1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
use crate::vmcontext::{VMContext, VMFunctionBody};
use core::cell::Cell;
use core::ptr;
use std::string::String;
extern "C" {
fn WasmtimeCallTrampoline(
vmctx: *mut u8,
callee: *const VMFunctionBody,
values_vec: *mut u8,
) -> i32;
fn WasmtimeCall(vmctx: *mut u8, callee: *const VMFunctionBody) -> i32;
}
thread_local! {
static TRAP_PC: Cell<*const u8> = Cell::new(ptr::null());
static JMP_BUF: Cell<*const u8> = Cell::new(ptr::null());
}
#[doc(hidden)]
#[allow(non_snake_case)]
#[no_mangle]
pub extern "C" fn RecordTrap(pc: *const u8) {
TRAP_PC.with(|data| data.set(pc));
}
#[doc(hidden)]
#[allow(non_snake_case)]
#[no_mangle]
pub extern "C" fn EnterScope(ptr: *const u8) -> *const u8 {
JMP_BUF.with(|buf| buf.replace(ptr))
}
#[doc(hidden)]
#[allow(non_snake_case)]
#[no_mangle]
pub extern "C" fn GetScope() -> *const u8 {
JMP_BUF.with(|buf| buf.get())
}
#[doc(hidden)]
#[allow(non_snake_case)]
#[no_mangle]
pub extern "C" fn LeaveScope(ptr: *const u8) {
JMP_BUF.with(|buf| buf.set(ptr))
}
fn trap_message(_vmctx: *mut VMContext) -> String {
let pc = TRAP_PC.with(|data| data.replace(ptr::null()));
format!("wasm trap at {:?}", pc)
}
#[no_mangle]
pub unsafe extern "C" fn wasmtime_call_trampoline(
vmctx: *mut VMContext,
callee: *const VMFunctionBody,
values_vec: *mut u8,
) -> Result<(), String> {
if WasmtimeCallTrampoline(vmctx as *mut u8, callee, values_vec) == 0 {
Err(trap_message(vmctx))
} else {
Ok(())
}
}
#[no_mangle]
pub unsafe extern "C" fn wasmtime_call(
vmctx: *mut VMContext,
callee: *const VMFunctionBody,
) -> Result<(), String> {
if WasmtimeCall(vmctx as *mut u8, callee) == 0 {
Err(trap_message(vmctx))
} else {
Ok(())
}
}