1 use crate::host_ref::HostRef;
2 use crate::{wasm_frame_vec_t, wasm_instance_t, wasm_name_t, wasm_store_t};
3 use once_cell::unsync::OnceCell;
4 use wasmtime::{Store, Trap};
5
6 #[repr(C)]
7 #[derive(Clone)]
8 pub struct wasm_trap_t {
9 pub(crate) trap: HostRef<Trap>,
10 }
11
12 wasmtime_c_api_macros::declare_ref!(wasm_trap_t);
13
14 impl wasm_trap_t {
new(store: &Store, trap: Trap) -> wasm_trap_t15 pub(crate) fn new(store: &Store, trap: Trap) -> wasm_trap_t {
16 wasm_trap_t {
17 trap: HostRef::new(store, trap),
18 }
19 }
20
externref(&self) -> wasmtime::ExternRef21 fn externref(&self) -> wasmtime::ExternRef {
22 self.trap.clone().into()
23 }
24 }
25
26 #[repr(C)]
27 #[derive(Clone)]
28 pub struct wasm_frame_t {
29 trap: HostRef<Trap>,
30 idx: usize,
31 func_name: OnceCell<Option<wasm_name_t>>,
32 module_name: OnceCell<Option<wasm_name_t>>,
33 }
34
35 wasmtime_c_api_macros::declare_own!(wasm_frame_t);
36
37 pub type wasm_message_t = wasm_name_t;
38
39 #[no_mangle]
wasm_trap_new( store: &wasm_store_t, message: &wasm_message_t, ) -> Box<wasm_trap_t>40 pub extern "C" fn wasm_trap_new(
41 store: &wasm_store_t,
42 message: &wasm_message_t,
43 ) -> Box<wasm_trap_t> {
44 let message = message.as_slice();
45 if message[message.len() - 1] != 0 {
46 panic!("wasm_trap_new message stringz expected");
47 }
48 let message = String::from_utf8_lossy(&message[..message.len() - 1]);
49 Box::new(wasm_trap_t {
50 trap: HostRef::new(&store.store, Trap::new(message)),
51 })
52 }
53
54 #[no_mangle]
wasm_trap_message(trap: &wasm_trap_t, out: &mut wasm_message_t)55 pub extern "C" fn wasm_trap_message(trap: &wasm_trap_t, out: &mut wasm_message_t) {
56 let mut buffer = Vec::new();
57 buffer.extend_from_slice(trap.trap.borrow().to_string().as_bytes());
58 buffer.reserve_exact(1);
59 buffer.push(0);
60 out.set_buffer(buffer);
61 }
62
63 #[no_mangle]
wasm_trap_origin(raw: &wasm_trap_t) -> Option<Box<wasm_frame_t>>64 pub extern "C" fn wasm_trap_origin(raw: &wasm_trap_t) -> Option<Box<wasm_frame_t>> {
65 let trap = raw.trap.borrow();
66 if trap.trace().len() > 0 {
67 Some(Box::new(wasm_frame_t {
68 trap: raw.trap.clone(),
69 idx: 0,
70 func_name: OnceCell::new(),
71 module_name: OnceCell::new(),
72 }))
73 } else {
74 None
75 }
76 }
77
78 #[no_mangle]
wasm_trap_trace(raw: &wasm_trap_t, out: &mut wasm_frame_vec_t)79 pub extern "C" fn wasm_trap_trace(raw: &wasm_trap_t, out: &mut wasm_frame_vec_t) {
80 let trap = raw.trap.borrow();
81 let vec = (0..trap.trace().len())
82 .map(|idx| {
83 Some(Box::new(wasm_frame_t {
84 trap: raw.trap.clone(),
85 idx,
86 func_name: OnceCell::new(),
87 module_name: OnceCell::new(),
88 }))
89 })
90 .collect();
91 out.set_buffer(vec);
92 }
93
94 #[no_mangle]
wasm_frame_func_index(frame: &wasm_frame_t) -> u3295 pub extern "C" fn wasm_frame_func_index(frame: &wasm_frame_t) -> u32 {
96 frame.trap.borrow().trace()[frame.idx].func_index()
97 }
98
99 #[no_mangle]
wasmtime_frame_func_name(frame: &wasm_frame_t) -> Option<&wasm_name_t>100 pub extern "C" fn wasmtime_frame_func_name(frame: &wasm_frame_t) -> Option<&wasm_name_t> {
101 frame
102 .func_name
103 .get_or_init(|| {
104 let trap = frame.trap.borrow();
105 trap.trace()[frame.idx]
106 .func_name()
107 .map(|s| wasm_name_t::from(s.to_string().into_bytes()))
108 })
109 .as_ref()
110 }
111
112 #[no_mangle]
wasmtime_frame_module_name(frame: &wasm_frame_t) -> Option<&wasm_name_t>113 pub extern "C" fn wasmtime_frame_module_name(frame: &wasm_frame_t) -> Option<&wasm_name_t> {
114 frame
115 .module_name
116 .get_or_init(|| {
117 let trap = frame.trap.borrow();
118 trap.trace()[frame.idx]
119 .module_name()
120 .map(|s| wasm_name_t::from(s.to_string().into_bytes()))
121 })
122 .as_ref()
123 }
124
125 #[no_mangle]
wasm_frame_func_offset(frame: &wasm_frame_t) -> usize126 pub extern "C" fn wasm_frame_func_offset(frame: &wasm_frame_t) -> usize {
127 let trap = frame.trap.borrow();
128 trap.trace()[frame.idx].func_offset()
129 }
130
131 #[no_mangle]
wasm_frame_instance(_arg1: *const wasm_frame_t) -> *mut wasm_instance_t132 pub extern "C" fn wasm_frame_instance(_arg1: *const wasm_frame_t) -> *mut wasm_instance_t {
133 unimplemented!("wasm_frame_instance")
134 }
135
136 #[no_mangle]
wasm_frame_module_offset(frame: &wasm_frame_t) -> usize137 pub extern "C" fn wasm_frame_module_offset(frame: &wasm_frame_t) -> usize {
138 let trap = frame.trap.borrow();
139 trap.trace()[frame.idx].module_offset()
140 }
141