Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[3.0.0] Backport some C-API trap-related changes #5224

Merged
merged 2 commits into from Nov 8, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
18 changes: 18 additions & 0 deletions crates/c-api/include/wasmtime/error.h
Expand Up @@ -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
Expand Down
9 changes: 0 additions & 9 deletions crates/c-api/include/wasmtime/trap.h
Expand Up @@ -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.
*
Expand Down
24 changes: 23 additions & 1 deletion 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)]
Expand Down Expand Up @@ -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) {
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)
}
11 changes: 6 additions & 5 deletions crates/c-api/src/instance.rs
Expand Up @@ -98,13 +98,14 @@ pub(crate) fn handle_instantiate(
*instance_ptr = i;
None
}
Err(e) => match e.downcast::<Trap>() {
Ok(trap) => {
*trap_ptr = Box::into_raw(Box::new(wasm_trap_t::new(trap.into())));
Err(e) => {
if e.is::<Trap>() {
*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())),
},
}
}
}

Expand Down
20 changes: 5 additions & 15 deletions crates/c-api/src/trap.rs
Expand Up @@ -94,7 +94,11 @@ pub extern "C" fn wasm_trap_origin(raw: &wasm_trap_t) -> Option<Box<wasm_frame_t

#[no_mangle]
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,
None => return out.set_buffer(Vec::new()),
};
Expand Down Expand Up @@ -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::<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 wasm_frame_func_index(frame: &wasm_frame_t<'_>) -> u32 {
frame.trace.frames()[frame.idx].func_index()
Expand Down