xref: /wasmtime-44.0.1/crates/c-api/src/error.rs (revision cfb506ba)
1 use crate::{wasm_frame_vec_t, wasm_name_t};
2 use anyhow::{anyhow, Error, Result};
3 
4 #[repr(C)]
5 pub struct wasmtime_error_t {
6     error: Error,
7 }
8 
9 wasmtime_c_api_macros::declare_own!(wasmtime_error_t);
10 
11 impl From<Error> for wasmtime_error_t {
12     fn from(error: Error) -> wasmtime_error_t {
13         wasmtime_error_t { error }
14     }
15 }
16 
17 impl Into<Error> for wasmtime_error_t {
18     fn into(self) -> Error {
19         self.error
20     }
21 }
22 
23 #[no_mangle]
24 pub extern "C" fn wasmtime_error_new(
25     msg: *const std::ffi::c_char,
26 ) -> Option<Box<wasmtime_error_t>> {
27     let msg_string = String::from_utf8_lossy(unsafe { std::ffi::CStr::from_ptr(msg).to_bytes() });
28     Some(Box::new(wasmtime_error_t::from(anyhow!(msg_string))))
29 }
30 
31 pub(crate) fn handle_result<T>(
32     result: Result<T>,
33     ok: impl FnOnce(T),
34 ) -> Option<Box<wasmtime_error_t>> {
35     match result {
36         Ok(value) => {
37             ok(value);
38             None
39         }
40         Err(error) => Some(Box::new(wasmtime_error_t { error })),
41     }
42 }
43 
44 pub(crate) fn bad_utf8() -> Option<Box<wasmtime_error_t>> {
45     Some(Box::new(wasmtime_error_t {
46         error: anyhow!("input was not valid utf-8"),
47     }))
48 }
49 
50 #[no_mangle]
51 pub extern "C" fn wasmtime_error_message(error: &wasmtime_error_t, message: &mut wasm_name_t) {
52     message.set_buffer(format!("{:?}", error.error).into_bytes());
53 }
54 
55 #[no_mangle]
56 pub extern "C" fn wasmtime_error_exit_status(raw: &wasmtime_error_t, status: &mut i32) -> bool {
57     #[cfg(feature = "wasi")]
58     if let Some(exit) = raw.error.downcast_ref::<wasmtime_wasi::I32Exit>() {
59         *status = exit.0;
60         return true;
61     }
62 
63     // Squash unused warnings in wasi-disabled builds.
64     drop((raw, status));
65 
66     false
67 }
68 
69 #[no_mangle]
70 pub extern "C" fn wasmtime_error_wasm_trace<'a>(
71     raw: &'a wasmtime_error_t,
72     out: &mut wasm_frame_vec_t<'a>,
73 ) {
74     crate::trap::error_trace(&raw.error, out)
75 }
76