unc_vm_compiler/
error.rs

1use crate::lib::std::string::String;
2
3// Compilation Errors
4
5/// The WebAssembly.CompileError object indicates an error during
6/// WebAssembly decoding or validation.
7///
8/// This is based on the [Wasm Compile Error][compile-error] API.
9///
10/// [compiler-error]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/WebAssembly/CompileError
11#[derive(Debug, thiserror::Error)]
12pub enum CompileError {
13    /// A Wasm translation error occured.
14    #[error("WebAssembly translation error: {0}")]
15    Wasm(WasmError),
16
17    /// A compilation error occured.
18    #[error("Compilation error: {0}")]
19    Codegen(String),
20
21    /// The module did not pass validation.
22    #[error("Validation error: {0}")]
23    Validate(String),
24
25    /// Finite-wasm failed to handle the module.
26    #[error("Finite-wasm analysis error: {0}")]
27    Analyze(finite_wasm::Error),
28
29    /// The compiler doesn't support a Wasm feature
30    #[error("Feature {0} is not yet supported")]
31    UnsupportedFeature(String),
32
33    /// The compiler cannot compile for the given target.
34    /// This can refer to the OS, the chipset or any other aspect of the target system.
35    #[error("The target {0} is not yet supported (see https://docs.wasmer.io/ecosystem/wasmer/wasmer-features)")]
36    UnsupportedTarget(String),
37
38    /// Insufficient resources available for execution.
39    #[error("Insufficient resources: {0}")]
40    Resource(String),
41
42    /// Cannot downcast the engine to a specific type.
43    #[error("data offset is out of bounds")]
44    InvalidOffset,
45}
46
47impl From<WasmError> for CompileError {
48    fn from(original: WasmError) -> Self {
49        Self::Wasm(original)
50    }
51}
52
53/// A error in the middleware.
54#[derive(Debug, thiserror::Error)]
55#[error("Error in middleware {name}: {message}")]
56pub struct MiddlewareError {
57    /// The name of the middleware where the error was created
58    pub name: String,
59    /// The error message
60    pub message: String,
61}
62
63impl MiddlewareError {
64    /// Create a new `MiddlewareError`
65    pub fn new<A: Into<String>, B: Into<String>>(name: A, message: B) -> Self {
66        Self { name: name.into(), message: message.into() }
67    }
68}
69
70/// A WebAssembly translation error.
71///
72/// When a WebAssembly function can't be translated, one of these error codes will be returned
73/// to describe the failure.
74#[derive(Debug, thiserror::Error)]
75pub enum WasmError {
76    /// The input WebAssembly code is invalid.
77    ///
78    /// This error code is used by a WebAssembly translator when it encounters invalid WebAssembly
79    /// code. This should never happen for validated WebAssembly code.
80    #[error("Invalid input WebAssembly code at offset {offset}: {message}")]
81    InvalidWebAssembly {
82        /// A string describing the validation error.
83        message: String,
84        /// The bytecode offset where the error occurred.
85        offset: usize,
86    },
87
88    /// A feature used by the WebAssembly code is not supported by the embedding environment.
89    ///
90    /// Embedding environments may have their own limitations and feature restrictions.
91    #[error("Unsupported feature: {0}")]
92    Unsupported(String),
93
94    /// An implementation limit was exceeded.
95    #[error("Implementation limit exceeded")]
96    ImplLimitExceeded,
97
98    /// An error from the middleware error.
99    #[error("{0}")]
100    Middleware(MiddlewareError),
101
102    /// A generic error.
103    #[error("{0}")]
104    Generic(String),
105}
106
107impl From<MiddlewareError> for WasmError {
108    fn from(original: MiddlewareError) -> Self {
109        Self::Middleware(original)
110    }
111}
112
113/// The error that can happen while parsing a `str`
114/// to retrieve a [`CpuFeature`](crate::target::CpuFeature).
115#[derive(Debug, thiserror::Error)]
116pub enum ParseCpuFeatureError {
117    /// The provided string feature doesn't exist
118    #[error("CpuFeature {0} not recognized")]
119    Missing(String),
120}
121
122/// A convenient alias for a `Result` that uses `WasmError` as the error type.
123pub type WasmResult<T> = Result<T, WasmError>;
124
125#[cfg(test)]
126mod tests {
127    use super::*;
128
129    #[test]
130    fn middleware_error_can_be_created() {
131        let msg = String::from("Something went wrong");
132        let error = MiddlewareError::new("manipulator3000", msg);
133        assert_eq!(error.name, "manipulator3000");
134        assert_eq!(error.message, "Something went wrong");
135    }
136
137    #[test]
138    fn middleware_error_be_converted_to_wasm_error() {
139        let error = WasmError::from(MiddlewareError::new("manipulator3000", "foo"));
140        match error {
141            WasmError::Middleware(MiddlewareError { name, message }) => {
142                assert_eq!(name, "manipulator3000");
143                assert_eq!(message, "foo");
144            }
145            err => panic!("Unexpected error: {:?}", err),
146        }
147    }
148}