Coverage Report

Created: 2024-09-10 12:50

/build/source/src/core/error.rs
Line
Count
Source (jump to first uncovered line)
1
use crate::core::indices::GlobalIdx;
2
use crate::validation_stack::LabelKind;
3
use core::fmt::{Display, Formatter};
4
use core::str::Utf8Error;
5
6
use crate::core::reader::section_header::SectionTy;
7
use crate::core::reader::types::ValType;
8
9
#[derive(Debug, PartialEq, Eq, Clone)]
10
pub enum RuntimeError {
11
    DivideBy0,
12
    UnrepresentableResult,
13
    FunctionNotFound,
14
    StackSmash,
15
    // https://github.com/wasmi-labs/wasmi/blob/37d1449524a322817c55026eb21eb97dd693b9ce/crates/core/src/trap.rs#L265C5-L265C27
16
    BadConversionToInteger,
17
}
18
19
#[derive(Debug, PartialEq, Eq, Clone)]
20
pub enum Error {
21
    /// The magic number at the very start of the given WASM file is invalid.
22
    InvalidMagic,
23
    InvalidVersion,
24
    MalformedUtf8String(Utf8Error),
25
    Eof,
26
    InvalidSectionType(u8),
27
    SectionOutOfOrder(SectionTy),
28
    InvalidNumType,
29
    InvalidVecType,
30
    InvalidFuncType,
31
    InvalidRefType,
32
    InvalidValType,
33
    InvalidExportDesc(u8),
34
    InvalidImportDesc(u8),
35
    ExprMissingEnd,
36
    InvalidInstr(u8),
37
    InvalidMultiByteInstr(u8, u8),
38
    EndInvalidValueStack,
39
    InvalidLocalIdx,
40
    InvalidValidationStackValType(Option<ValType>),
41
    InvalidLimitsType(u8),
42
    InvalidMutType(u8),
43
    MoreThanOneMemory,
44
    InvalidGlobalIdx(GlobalIdx),
45
    GlobalIsConst,
46
    RuntimeError(RuntimeError),
47
    FoundLabel(LabelKind),
48
}
49
50
impl Display for Error {
51
0
    fn fmt(&self, f: &mut Formatter<'_>) -> core::fmt::Result {
52
0
        match self {
53
            Error::InvalidMagic => {
54
0
                f.write_str("The magic number at the very start of the given WASM file is invalid.")
55
            }
56
0
            Error::InvalidVersion => f.write_str("The version in the WASM file header is invalid"),
57
0
            Error::MalformedUtf8String(err) => f.write_fmt(format_args!(
58
0
                "A name could not be parsed as it was invalid UTF8: {err}"
59
0
            )),
60
0
            Error::Eof => f.write_str(
61
0
                "A value was expected in the WASM binary but the end of file was reached instead",
62
0
            ),
63
0
            Error::InvalidSectionType(ty) => f.write_fmt(format_args!(
64
0
                "An invalid section type id was found in a section header: {ty}"
65
0
            )),
66
0
            Error::SectionOutOfOrder(ty) => {
67
0
                f.write_fmt(format_args!("The section {ty:?} is out of order"))
68
            }
69
            Error::InvalidNumType => {
70
0
                f.write_str("An invalid byte was read where a numtype was expected")
71
            }
72
            Error::InvalidVecType => {
73
0
                f.write_str("An invalid byte was read where a vectype was expected")
74
            }
75
            Error::InvalidFuncType => {
76
0
                f.write_str("An invalid byte was read where a functype was expected")
77
            }
78
            Error::InvalidRefType => {
79
0
                f.write_str("An invalid byte was read where a reftype was expected")
80
            }
81
            Error::InvalidValType => {
82
0
                f.write_str("An invalid byte was read where a valtype was expected")
83
            }
84
0
            Error::InvalidExportDesc(byte) => f.write_fmt(format_args!(
85
0
                "An invalid byte `{byte:#x?}` was read where an exportdesc was expected"
86
0
            )),
87
0
            Error::InvalidImportDesc(byte) => f.write_fmt(format_args!(
88
0
                "An invalid byte `{byte:#x?}` was read where an importdesc was expected"
89
0
            )),
90
0
            Error::ExprMissingEnd => f.write_str("An expr is missing an end byte"),
91
0
            Error::InvalidInstr(byte) => f.write_fmt(format_args!(
92
0
                "An invalid instruction opcode was found: `{byte:#x?}`"
93
0
            )),
94
0
            Error::InvalidMultiByteInstr(byte1, byte2) => f.write_fmt(format_args!(
95
0
                "An invalid multi-byte instruction opcode was found: `{byte1:#x?} {byte2:#x?}`"
96
0
            )),
97
0
            Error::EndInvalidValueStack => f.write_str(
98
0
                "Different value stack types were expected at the end of a block/function.",
99
0
            ),
100
0
            Error::InvalidLocalIdx => f.write_str("An invalid localidx was used"),
101
0
            Error::InvalidValidationStackValType(ty) => f.write_fmt(format_args!(
102
0
                "An unexpected type was found on the stack when trying to pop another: `{ty:?}`"
103
0
            )),
104
0
            Error::InvalidLimitsType(ty) => {
105
0
                f.write_fmt(format_args!("An invalid limits type was found: {ty:#x?}"))
106
            }
107
0
            Error::InvalidMutType(byte) => f.write_fmt(format_args!(
108
0
                "An invalid mut/const byte was found: {byte:#x?}"
109
0
            )),
110
            Error::MoreThanOneMemory => {
111
0
                f.write_str("As of not only one memory is allowed per module.")
112
            }
113
0
            Error::InvalidGlobalIdx(idx) => f.write_fmt(format_args!(
114
0
                "An invalid global index `{idx}` was specified"
115
0
            )),
116
0
            Error::GlobalIsConst => f.write_str("A const global cannot be written to"),
117
0
            Error::RuntimeError(err) => err.fmt(f),
118
0
            Error::FoundLabel(lk) => f.write_fmt(format_args!(
119
0
                "Expecting a ValType, a Label was found: {lk:?}"
120
0
            )),
121
        }
122
0
    }
123
}
124
125
impl Display for RuntimeError {
126
1
    fn fmt(&self, f: &mut Formatter<'_>) -> core::fmt::Result {
127
1
        match self {
128
0
            RuntimeError::DivideBy0 => f.write_str("Divide by zero is not permitted"),
129
0
            RuntimeError::UnrepresentableResult => f.write_str("Result is unrepresentable"),
130
0
            RuntimeError::FunctionNotFound => f.write_str("Function not found"),
131
0
            RuntimeError::StackSmash => f.write_str("Stack smashed"),
132
1
            RuntimeError::BadConversionToInteger => f.write_str("Bad conversion to integer"),
133
        }
134
1
    }
135
}
136
137
pub type Result<T> = core::result::Result<T, Error>;
138
139
impl From<RuntimeError> for Error {
140
0
    fn from(value: RuntimeError) -> Self {
141
0
        Self::RuntimeError(value)
142
0
    }
143
}