diff --git a/crates/c-api/include/wasmtime.h b/crates/c-api/include/wasmtime.h index 3e04349981..9e0b5b3ca1 100644 --- a/crates/c-api/include/wasmtime.h +++ b/crates/c-api/include/wasmtime.h @@ -65,6 +65,10 @@ WASM_API_EXTERN bool wasmtime_wat2wasm( own wasm_byte_vec_t *error_message ); +/////////////////////////////////////////////////////////////////////////////// +// +// wasmtime_linker_t extension type, binding the `Linker` type in the Rust API + #define WASMTIME_DECLARE_OWN(name) \ typedef struct wasmtime_##name##_t wasmtime_##name##_t; \ \ @@ -100,6 +104,10 @@ WASM_API_EXTERN wasm_instance_t* wasmtime_linker_instantiate( own wasm_trap_t **trap ); +/////////////////////////////////////////////////////////////////////////////// +// +// wasmtime_caller_t extension, binding the `Caller` type in the Rust API + typedef struct wasmtime_caller_t wasmtime_caller_t; typedef own wasm_trap_t* (*wasmtime_func_callback_t)(const wasmtime_caller_t* caller, const wasm_val_t args[], wasm_val_t results[]); @@ -117,6 +125,13 @@ WASM_API_EXTERN own wasm_func_t* wasmtime_func_new_with_env( WASM_API_EXTERN own wasm_extern_t* wasmtime_caller_export_get(const wasmtime_caller_t* caller, const wasm_name_t* name); +/////////////////////////////////////////////////////////////////////////////// +// +// Extensions to `wasm_frame_t` + +WASM_API_EXTERN const wasm_name_t *wasmtime_frame_func_name(const wasm_frame_t*); +WASM_API_EXTERN const wasm_name_t *wasmtime_frame_module_name(const wasm_frame_t*); + #undef own #ifdef __cplusplus diff --git a/crates/c-api/src/trap.rs b/crates/c-api/src/trap.rs index 7c536efe1f..d41d676dbb 100644 --- a/crates/c-api/src/trap.rs +++ b/crates/c-api/src/trap.rs @@ -1,4 +1,5 @@ use crate::{wasm_frame_vec_t, wasm_instance_t, wasm_name_t, wasm_store_t}; +use once_cell::unsync::OnceCell; use wasmtime::{HostRef, Trap}; #[repr(C)] @@ -18,7 +19,10 @@ impl wasm_trap_t { #[repr(C)] #[derive(Clone)] pub struct wasm_frame_t { - _unused: [u8; 0], + trap: HostRef, + idx: usize, + func_name: OnceCell>, + module_name: OnceCell>, } wasmtime_c_api_macros::declare_own!(wasm_frame_t); @@ -50,18 +54,65 @@ pub extern "C" fn wasm_trap_message(trap: &wasm_trap_t, out: &mut wasm_message_t } #[no_mangle] -pub extern "C" fn wasm_trap_origin(_trap: &wasm_trap_t) -> Option> { - None +pub extern "C" fn wasm_trap_origin(raw: &wasm_trap_t) -> Option> { + let trap = raw.trap.borrow(); + if trap.trace().len() > 0 { + Some(Box::new(wasm_frame_t { + trap: raw.trap.clone(), + idx: 0, + func_name: OnceCell::new(), + module_name: OnceCell::new(), + })) + } else { + None + } } #[no_mangle] -pub extern "C" fn wasm_trap_trace(_trap: &wasm_trap_t, out: &mut wasm_frame_vec_t) { - out.set_buffer(Vec::new()); +pub extern "C" fn wasm_trap_trace(raw: &wasm_trap_t, out: &mut wasm_frame_vec_t) { + let trap = raw.trap.borrow(); + let vec = (0..trap.trace().len()) + .map(|idx| { + Some(Box::new(wasm_frame_t { + trap: raw.trap.clone(), + idx, + func_name: OnceCell::new(), + module_name: OnceCell::new(), + })) + }) + .collect(); + out.set_buffer(vec); } #[no_mangle] -pub extern "C" fn wasm_frame_func_index(_arg1: *const wasm_frame_t) -> u32 { - unimplemented!("wasm_frame_func_index") +pub extern "C" fn wasm_frame_func_index(frame: &wasm_frame_t) -> u32 { + frame.trap.borrow().trace()[frame.idx].func_index() +} + +#[no_mangle] +pub extern "C" fn wasmtime_frame_func_name(frame: &wasm_frame_t) -> Option<&wasm_name_t> { + frame + .func_name + .get_or_init(|| { + let trap = frame.trap.borrow(); + trap.trace()[frame.idx] + .func_name() + .map(|s| wasm_name_t::from(s.to_string().into_bytes())) + }) + .as_ref() +} + +#[no_mangle] +pub extern "C" fn wasmtime_frame_module_name(frame: &wasm_frame_t) -> Option<&wasm_name_t> { + frame + .module_name + .get_or_init(|| { + let trap = frame.trap.borrow(); + trap.trace()[frame.idx] + .module_name() + .map(|s| wasm_name_t::from(s.to_string().into_bytes())) + }) + .as_ref() } #[no_mangle]