Update how exits are modeled in the C API (#5215)
Previously extracting an exit code was only possibly on a `wasm_trap_t` which will never successfully have an exit code on it, so the exit code extractor is moved over to `wasmtime_error_t`. Additionally extracting a wasm trace from a `wasmtime_error_t` is added since traces happen on both traps and errors now.
This commit is contained in:
@@ -48,6 +48,24 @@ WASM_API_EXTERN void wasmtime_error_message(
|
|||||||
wasm_name_t *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
|
#ifdef __cplusplus
|
||||||
} // extern "C"
|
} // extern "C"
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -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);
|
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.
|
* \brief Returns a human-readable name for this frame's function.
|
||||||
*
|
*
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
use crate::wasm_name_t;
|
use crate::{wasm_frame_vec_t, wasm_name_t};
|
||||||
use anyhow::{anyhow, Error, Result};
|
use anyhow::{anyhow, Error, Result};
|
||||||
|
|
||||||
#[repr(C)]
|
#[repr(C)]
|
||||||
@@ -37,3 +37,25 @@ pub(crate) fn bad_utf8() -> Option<Box<wasmtime_error_t>> {
|
|||||||
pub extern "C" fn wasmtime_error_message(error: &wasmtime_error_t, message: &mut wasm_name_t) {
|
pub extern "C" fn wasmtime_error_message(error: &wasmtime_error_t, message: &mut wasm_name_t) {
|
||||||
message.set_buffer(format!("{:?}", error.error).into_bytes());
|
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::<wasmtime_wasi::I32Exit>() {
|
||||||
|
*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)
|
||||||
|
}
|
||||||
|
|||||||
@@ -94,7 +94,11 @@ pub extern "C" fn wasm_trap_origin(raw: &wasm_trap_t) -> Option<Box<wasm_frame_t
|
|||||||
|
|
||||||
#[no_mangle]
|
#[no_mangle]
|
||||||
pub extern "C" fn wasm_trap_trace<'a>(raw: &'a wasm_trap_t, out: &mut wasm_frame_vec_t<'a>) {
|
pub extern "C" fn wasm_trap_trace<'a>(raw: &'a wasm_trap_t, out: &mut wasm_frame_vec_t<'a>) {
|
||||||
let trace = match raw.error.downcast_ref::<WasmBacktrace>() {
|
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::<WasmBacktrace>() {
|
||||||
Some(trap) => trap,
|
Some(trap) => trap,
|
||||||
None => return out.set_buffer(Vec::new()),
|
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
|
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::<wasmtime_wasi::I32Exit>() {
|
|
||||||
*status = exit.0;
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Squash unused warnings in wasi-disabled builds.
|
|
||||||
drop((raw, status));
|
|
||||||
|
|
||||||
false
|
|
||||||
}
|
|
||||||
|
|
||||||
#[no_mangle]
|
#[no_mangle]
|
||||||
pub extern "C" fn wasm_frame_func_index(frame: &wasm_frame_t<'_>) -> u32 {
|
pub extern "C" fn wasm_frame_func_index(frame: &wasm_frame_t<'_>) -> u32 {
|
||||||
frame.trace.frames()[frame.idx].func_index()
|
frame.trace.frames()[frame.idx].func_index()
|
||||||
|
|||||||
Reference in New Issue
Block a user