wasmtime_environ/
error.rs

1use alloc::string::{String, ToString};
2use core::fmt;
3use core::num::TryFromIntError;
4
5/// A WebAssembly translation error.
6///
7/// When a WebAssembly function can't be translated, one of these error codes will be returned
8/// to describe the failure.
9#[derive(Debug)]
10pub enum WasmError {
11    /// The input WebAssembly code is invalid.
12    ///
13    /// This error code is used by a WebAssembly translator when it encounters invalid WebAssembly
14    /// code. This should never happen for validated WebAssembly code.
15    InvalidWebAssembly {
16        /// A string describing the validation error.
17        message: String,
18        /// The bytecode offset where the error occurred.
19        offset: usize,
20    },
21
22    /// A feature used by the WebAssembly code is not supported by the embedding environment.
23    ///
24    /// Embedding environments may have their own limitations and feature restrictions.
25    Unsupported(String),
26
27    /// An implementation limit was exceeded.
28    ///
29    /// Cranelift can compile very large and complicated functions, but the [implementation has
30    /// limits][limits] that cause compilation to fail when they are exceeded.
31    ///
32    /// [limits]: https://github.com/bytecodealliance/wasmtime/blob/main/cranelift/docs/ir.md#implementation-limits
33    ImplLimitExceeded,
34
35    /// Any user-defined error.
36    User(String),
37}
38
39/// Return an `Err(WasmError::Unsupported(msg))` where `msg` the string built by calling `format!`
40/// on the arguments to this macro.
41#[macro_export]
42macro_rules! wasm_unsupported {
43    ($($arg:tt)*) => { $crate::WasmError::Unsupported($crate::__format!($($arg)*)) }
44}
45#[doc(hidden)]
46pub use alloc::format as __format;
47
48impl From<wasmparser::BinaryReaderError> for WasmError {
49    /// Convert from a `BinaryReaderError` to a `WasmError`.
50    fn from(e: wasmparser::BinaryReaderError) -> Self {
51        Self::InvalidWebAssembly {
52            message: e.message().into(),
53            offset: e.offset(),
54        }
55    }
56}
57
58impl From<TryFromIntError> for WasmError {
59    /// Convert from a `TryFromIntError` to a `WasmError`.
60    fn from(e: TryFromIntError) -> Self {
61        Self::InvalidWebAssembly {
62            message: e.to_string(),
63            offset: 0,
64        }
65    }
66}
67
68/// A convenient alias for a `Result` that uses `WasmError` as the error type.
69pub type WasmResult<T> = Result<T, WasmError>;
70
71impl fmt::Display for WasmError {
72    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
73        match self {
74            WasmError::InvalidWebAssembly { message, offset } => {
75                write!(
76                    f,
77                    "Invalid input WebAssembly code at offset {offset}: {message}"
78                )
79            }
80            WasmError::Unsupported(s) => {
81                write!(f, "Unsupported feature: {s}")
82            }
83            WasmError::ImplLimitExceeded => {
84                write!(f, "Implementation limit exceeded")
85            }
86            WasmError::User(s) => {
87                write!(f, "User error: {s}")
88            }
89        }
90    }
91}
92
93#[cfg(feature = "std")]
94impl std::error::Error for WasmError {}