diff --git a/crates/c-api/include/wasmtime/error.h b/crates/c-api/include/wasmtime/error.h index 2ffee72bed8f..cfa0c9690e2e 100644 --- a/crates/c-api/include/wasmtime/error.h +++ b/crates/c-api/include/wasmtime/error.h @@ -48,6 +48,24 @@ WASM_API_EXTERN void wasmtime_error_message( wasm_name_t *message ); +/** + * \brief Attempts to extract a WASI-specific exit status from this error. + * + * Returns `true` if the error is a WASI "exit" trap and has a return status. + * If `true` is returned then the exit status is returned through the `status` + * pointer. If `false` is returned then this is not a wasi exit trap. + */ +WASM_API_EXTERN bool wasmtime_error_exit_status(const wasmtime_error_t*, int *status); + +/** + * \brief Attempts to extract a WebAssembly trace from this error. + * + * This is similar to #wasm_trap_trace except that it takes a #wasmtime_error_t + * as input. The `out` argument will be filled in with the wasm trace, if + * present. + */ +WASM_API_EXTERN void wasmtime_error_wasm_trace(const wasmtime_error_t*, wasm_frame_vec_t *out); + #ifdef __cplusplus } // extern "C" #endif diff --git a/crates/c-api/include/wasmtime/trap.h b/crates/c-api/include/wasmtime/trap.h index 909a4801f006..6346cf443be4 100644 --- a/crates/c-api/include/wasmtime/trap.h +++ b/crates/c-api/include/wasmtime/trap.h @@ -69,15 +69,6 @@ WASM_API_EXTERN wasm_trap_t *wasmtime_trap_new(const char *msg, size_t msg_len); */ WASM_API_EXTERN bool wasmtime_trap_code(const wasm_trap_t*, wasmtime_trap_code_t *code); -/** - * \brief Attempts to extract a WASI-specific exit status from this trap. - * - * Returns `true` if the trap is a WASI "exit" trap and has a return status. If - * `true` is returned then the exit status is returned through the `status` - * pointer. If `false` is returned then this is not a wasi exit trap. - */ -WASM_API_EXTERN bool wasmtime_trap_exit_status(const wasm_trap_t*, int *status); - /** * \brief Returns a human-readable name for this frame's function. * diff --git a/crates/c-api/src/error.rs b/crates/c-api/src/error.rs index 073c158c3b4d..e1e066531a0f 100644 --- a/crates/c-api/src/error.rs +++ b/crates/c-api/src/error.rs @@ -1,4 +1,4 @@ -use crate::wasm_name_t; +use crate::{wasm_frame_vec_t, wasm_name_t}; use anyhow::{anyhow, Error, Result}; #[repr(C)] @@ -37,3 +37,25 @@ pub(crate) fn bad_utf8() -> Option> { pub extern "C" fn wasmtime_error_message(error: &wasmtime_error_t, message: &mut wasm_name_t) { message.set_buffer(format!("{:?}", error.error).into_bytes()); } + +#[no_mangle] +pub extern "C" fn wasmtime_error_exit_status(raw: &wasmtime_error_t, status: &mut i32) -> bool { + #[cfg(feature = "wasi")] + if let Some(exit) = raw.error.downcast_ref::() { + *status = exit.0; + return true; + } + + // Squash unused warnings in wasi-disabled builds. + drop((raw, status)); + + false +} + +#[no_mangle] +pub extern "C" fn wasmtime_error_wasm_trace<'a>( + raw: &'a wasmtime_error_t, + out: &mut wasm_frame_vec_t<'a>, +) { + crate::trap::error_trace(&raw.error, out) +} diff --git a/crates/c-api/src/instance.rs b/crates/c-api/src/instance.rs index 2f93661ecddd..13fb96a36914 100644 --- a/crates/c-api/src/instance.rs +++ b/crates/c-api/src/instance.rs @@ -98,13 +98,14 @@ pub(crate) fn handle_instantiate( *instance_ptr = i; None } - Err(e) => match e.downcast::() { - Ok(trap) => { - *trap_ptr = Box::into_raw(Box::new(wasm_trap_t::new(trap.into()))); + Err(e) => { + if e.is::() { + *trap_ptr = Box::into_raw(Box::new(wasm_trap_t::new(e))); None + } else { + Some(Box::new(e.into())) } - Err(e) => Some(Box::new(e.into())), - }, + } } } diff --git a/crates/c-api/src/trap.rs b/crates/c-api/src/trap.rs index f6881c5454de..55beff06295a 100644 --- a/crates/c-api/src/trap.rs +++ b/crates/c-api/src/trap.rs @@ -94,7 +94,11 @@ pub extern "C" fn wasm_trap_origin(raw: &wasm_trap_t) -> Option(raw: &'a wasm_trap_t, out: &mut wasm_frame_vec_t<'a>) { - let trace = match raw.error.downcast_ref::() { + error_trace(&raw.error, out) +} + +pub(crate) fn error_trace<'a>(error: &'a Error, out: &mut wasm_frame_vec_t<'a>) { + let trace = match error.downcast_ref::() { Some(trap) => trap, None => return out.set_buffer(Vec::new()), }; @@ -134,20 +138,6 @@ pub extern "C" fn wasmtime_trap_code(raw: &wasm_trap_t, code: &mut i32) -> bool true } -#[no_mangle] -pub extern "C" fn wasmtime_trap_exit_status(raw: &wasm_trap_t, status: &mut i32) -> bool { - #[cfg(feature = "wasi")] - if let Some(exit) = raw.error.downcast_ref::() { - *status = exit.0; - return true; - } - - // Squash unused warnings in wasi-disabled builds. - drop((raw, status)); - - false -} - #[no_mangle] pub extern "C" fn wasm_frame_func_index(frame: &wasm_frame_t<'_>) -> u32 { frame.trace.frames()[frame.idx].func_index()