wasmi_c_api/
trap.rs

1use crate::{wasm_frame_t, wasm_frame_vec_t, wasm_name_t, wasm_store_t};
2use alloc::{boxed::Box, format, string::String, vec::Vec};
3use wasmi::Error;
4
5/// A Wasm trap.
6///
7/// Wraps [`Error`].
8#[repr(C)]
9pub struct wasm_trap_t {
10    pub(crate) error: Error,
11}
12
13impl Clone for wasm_trap_t {
14    fn clone(&self) -> wasm_trap_t {
15        // Note: This API is only needed for the `wasm_trap_copy` API in the C-API.
16        //
17        // # Note
18        //
19        // For now the impl here is "fake it til you make it" since this is losing
20        // context by only cloning the error string.
21        wasm_trap_t {
22            error: Error::new(format!("{}", self.error)),
23        }
24    }
25}
26
27wasmi_c_api_macros::declare_ref!(wasm_trap_t);
28
29impl wasm_trap_t {
30    /// Creates a [`wasm_trap_t`] from the given [`Error`].
31    pub(crate) fn new(error: Error) -> wasm_trap_t {
32        wasm_trap_t { error }
33    }
34}
35
36/// A Wasm error message string buffer.
37pub type wasm_message_t = wasm_name_t;
38
39/// Creates a new [`wasm_trap_t`] for the [`wasm_store_t`] with the given `message`.
40///
41/// # Note
42///
43/// The `message` is expected to contain a valid null-terminated C string.
44#[cfg_attr(not(feature = "prefix-symbols"), no_mangle)]
45#[cfg_attr(feature = "prefix-symbols", wasmi_c_api_macros::prefix_symbol)]
46pub extern "C" fn wasm_trap_new(
47    _store: &wasm_store_t,
48    message: &wasm_message_t,
49) -> Box<wasm_trap_t> {
50    let message = message.as_slice();
51    if message[message.len() - 1] != 0 {
52        panic!("wasm_trap_new: expected `message` to be a null-terminated C-string");
53    }
54    let message = String::from_utf8_lossy(&message[..message.len() - 1]);
55    Box::new(wasm_trap_t {
56        error: Error::new(message.into_owned()),
57    })
58}
59
60/// Creates a new [`wasm_trap_t`] from the given `message` and `len` pair.
61///
62/// # Safety
63///
64/// The caller is responsible to provide a valid `message` and `len` pair.
65#[no_mangle]
66pub unsafe extern "C" fn wasmi_trap_new(message: *const u8, len: usize) -> Box<wasm_trap_t> {
67    let bytes = crate::slice_from_raw_parts(message, len);
68    let message = String::from_utf8_lossy(bytes);
69    Box::new(wasm_trap_t {
70        error: Error::new(message.into_owned()),
71    })
72}
73
74/// Returns the error message of the [`wasm_trap_t`].
75///
76/// Stores the returned error message in `out`.
77#[cfg_attr(not(feature = "prefix-symbols"), no_mangle)]
78#[cfg_attr(feature = "prefix-symbols", wasmi_c_api_macros::prefix_symbol)]
79pub extern "C" fn wasm_trap_message(trap: &wasm_trap_t, out: &mut wasm_message_t) {
80    let mut buffer = Vec::new();
81    buffer.extend_from_slice(format!("{:?}", trap.error).as_bytes());
82    buffer.reserve_exact(1);
83    buffer.push(0);
84    out.set_buffer(buffer.into());
85}
86
87/// Returns the origin of the [`wasm_trap_t`] if any.
88///
89/// # Note
90///
91/// This API is unsupported and will panic upon use.
92#[cfg_attr(not(feature = "prefix-symbols"), no_mangle)]
93#[cfg_attr(feature = "prefix-symbols", wasmi_c_api_macros::prefix_symbol)]
94pub extern "C" fn wasm_trap_origin(_raw: &wasm_trap_t) -> Option<Box<wasm_frame_t<'_>>> {
95    unimplemented!("wasm_trap_origin")
96}
97
98/// Returns the trace of the [`wasm_trap_t`].
99///
100/// Stores the returned trace in `out`.
101///
102/// # Note
103///
104/// This API is unsupported and will panic upon use.
105#[cfg_attr(not(feature = "prefix-symbols"), no_mangle)]
106#[cfg_attr(feature = "prefix-symbols", wasmi_c_api_macros::prefix_symbol)]
107pub extern "C" fn wasm_trap_trace<'a>(_raw: &'a wasm_trap_t, _out: &mut wasm_frame_vec_t<'a>) {
108    unimplemented!("wasm_trap_trace")
109}