Skip to main content

wasefire_interpreter/
error.rs

1// Copyright 2022 Google LLC
2//
3// Licensed under the Apache License, Version 2.0 (the "License");
4// you may not use this file except in compliance with the License.
5// You may obtain a copy of the License at
6//
7//     http://www.apache.org/licenses/LICENSE-2.0
8//
9// Unless required by applicable law or agreed to in writing, software
10// distributed under the License is distributed on an "AS IS" BASIS,
11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12// See the License for the specific language governing permissions and
13// limitations under the License.
14
15/// Errors returned by functions in this crate.
16#[derive(Debug, Copy, Clone, PartialEq, Eq)]
17pub enum Error {
18    /// An argument is invalid.
19    Invalid,
20
21    /// An argument is not found.
22    NotFound,
23
24    /// An argument is not supported.
25    Unsupported(Unsupported),
26
27    /// Execution trapped.
28    // TODO: In debug mode, trap could describe the reason (like resource exhaustion, etc).
29    Trap,
30}
31
32pub const TRAP_CODE: u16 = 0xffff;
33
34impl From<Error> for wasefire_error::Error {
35    fn from(value: Error) -> Self {
36        use wasefire_error::{Code, Error as WError};
37        match value {
38            Error::Invalid => WError::user(Code::InvalidArgument),
39            Error::NotFound => WError::user(Code::NotFound),
40            Error::Unsupported(_) => WError::internal(Code::NotImplemented),
41            Error::Trap => WError::user(TRAP_CODE),
42        }
43    }
44}
45
46#[cfg(not(feature = "debug"))]
47pub type Unsupported = ();
48
49#[derive(Debug, Copy, Clone, PartialEq, Eq)]
50#[non_exhaustive]
51#[cfg(feature = "debug")]
52pub enum Unsupported {
53    Exception,
54    HeapType,
55    MaxLocals,
56    Opcode(u8),
57    OpcodeFc(u32),
58    SideTable,
59    TableInit,
60    TailCall,
61}
62
63#[cfg(feature = "debug")]
64pub fn print_backtrace() {
65    let backtrace = std::backtrace::Backtrace::capture();
66    if matches!(backtrace.status(), std::backtrace::BacktraceStatus::Captured) {
67        println!("{backtrace}");
68    }
69}
70
71pub fn invalid() -> Error {
72    #[cfg(feature = "debug")]
73    print_backtrace();
74    Error::Invalid
75}
76
77pub fn not_found() -> Error {
78    #[cfg(feature = "debug")]
79    print_backtrace();
80    Error::NotFound
81}
82
83pub fn unsupported(reason: Unsupported) -> Error {
84    #[cfg(feature = "debug")]
85    print_backtrace();
86    Error::Unsupported(reason)
87}
88
89pub fn trap() -> Error {
90    #[cfg(feature = "debug")]
91    print_backtrace();
92    Error::Trap
93}
94
95pub fn check(cond: bool) -> Result<(), Error> {
96    if cond { Ok(()) } else { Err(invalid()) }
97}