Coverage Report

Created: 2024-11-19 11:03

/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
use super::indices::{DataIdx, MemIdx};
10
11
#[derive(Debug, PartialEq, Eq, Clone)]
12
pub enum RuntimeError {
13
    DivideBy0,
14
    UnrepresentableResult,
15
    FunctionNotFound,
16
    StackSmash,
17
    // https://github.com/wasmi-labs/wasmi/blob/37d1449524a322817c55026eb21eb97dd693b9ce/crates/core/src/trap.rs#L265C5-L265C27
18
    BadConversionToInteger,
19
    MemoryAccessOutOfBounds,
20
}
21
22
#[derive(Debug, PartialEq, Eq, Clone)]
23
pub enum Error {
24
    /// The magic number at the very start of the given WASM file is invalid.
25
    InvalidMagic,
26
    InvalidVersion,
27
    MalformedUtf8String(Utf8Error),
28
    Eof,
29
    InvalidSectionType(u8),
30
    SectionOutOfOrder(SectionTy),
31
    InvalidNumType,
32
    InvalidVecType,
33
    InvalidFuncType,
34
    InvalidRefType,
35
    InvalidValType,
36
    InvalidExportDesc(u8),
37
    InvalidImportDesc(u8),
38
    ExprMissingEnd,
39
    InvalidInstr(u8),
40
    InvalidMultiByteInstr(u8, u8),
41
    EndInvalidValueStack,
42
    InvalidLocalIdx,
43
    InvalidValidationStackValType(Option<ValType>),
44
    ExpectedAnOperand,
45
    InvalidLimitsType(u8),
46
    InvalidMutType(u8),
47
    MoreThanOneMemory,
48
    InvalidLimit,
49
    MemSizeTooBig,
50
    InvalidGlobalIdx(GlobalIdx),
51
    GlobalIsConst,
52
    RuntimeError(RuntimeError),
53
    FoundLabel(LabelKind),
54
    MemoryIsNotDefined(MemIdx),
55
    //           mem.align, wanted alignment
56
    ErroneousAlignment(u32, u32),
57
    NoDataSegments,
58
    DataSegmentNotFound(DataIdx),
59
}
60
61
impl Display for Error {
62
349
    fn fmt(&self, f: &mut Formatter<'_>) -> core::fmt::Result {
63
349
        match self {
64
            Error::InvalidMagic => {
65
0
                f.write_str("The magic number at the very start of the given WASM file is invalid.")
66
            }
67
0
            Error::InvalidVersion => f.write_str("The version in the WASM file header is invalid"),
68
0
            Error::MalformedUtf8String(err) => f.write_fmt(format_args!(
69
0
                "A name could not be parsed as it was invalid UTF8: {err}"
70
0
            )),
71
0
            Error::Eof => f.write_str(
72
0
                "A value was expected in the WASM binary but the end of file was reached instead",
73
0
            ),
74
8
            Error::InvalidSectionType(ty) => f.write_fmt(format_args!(
75
8
                "An invalid section type id was found in a section header: {ty}"
76
8
            )),
77
0
            Error::SectionOutOfOrder(ty) => {
78
0
                f.write_fmt(format_args!("The section {ty:?} is out of order"))
79
            }
80
            Error::InvalidNumType => {
81
0
                f.write_str("An invalid byte was read where a numtype was expected")
82
            }
83
            Error::InvalidVecType => {
84
0
                f.write_str("An invalid byte was read where a vectype was expected")
85
            }
86
            Error::InvalidFuncType => {
87
30
                f.write_str("An invalid byte was read where a functype was expected")
88
            }
89
            Error::InvalidRefType => {
90
6
                f.write_str("An invalid byte was read where a reftype was expected")
91
            }
92
            Error::InvalidValType => {
93
53
                f.write_str("An invalid byte was read where a valtype was expected")
94
            }
95
0
            Error::InvalidExportDesc(byte) => f.write_fmt(format_args!(
96
0
                "An invalid byte `{byte:#x?}` was read where an exportdesc was expected"
97
0
            )),
98
0
            Error::InvalidImportDesc(byte) => f.write_fmt(format_args!(
99
0
                "An invalid byte `{byte:#x?}` was read where an importdesc was expected"
100
0
            )),
101
0
            Error::ExprMissingEnd => f.write_str("An expr is missing an end byte"),
102
112
            Error::InvalidInstr(byte) => f.write_fmt(format_args!(
103
112
                "An invalid instruction opcode was found: `{byte:#x?}`"
104
112
            )),
105
1
            Error::InvalidMultiByteInstr(byte1, byte2) => f.write_fmt(format_args!(
106
1
                "An invalid multi-byte instruction opcode was found: `{byte1:#x?} {byte2:#x?}`"
107
1
            )),
108
2
            Error::EndInvalidValueStack => f.write_str(
109
2
                "Different value stack types were expected at the end of a block/function.",
110
2
            ),
111
0
            Error::InvalidLocalIdx => f.write_str("An invalid localidx was used"),
112
0
            Error::InvalidValidationStackValType(ty) => f.write_fmt(format_args!(
113
0
                "An unexpected type was found on the stack when trying to pop another: `{ty:?}`"
114
0
            )),
115
17
            Error::InvalidLimitsType(ty) => {
116
17
                f.write_fmt(format_args!("An invalid limits type was found: {ty:#x?}"))
117
            }
118
0
            Error::InvalidMutType(byte) => f.write_fmt(format_args!(
119
0
                "An invalid mut/const byte was found: {byte:#x?}"
120
0
            )),
121
            Error::MoreThanOneMemory => {
122
72
                f.write_str("As of not only one memory is allowed per module.")
123
            }
124
0
            Error::InvalidLimit => f.write_str("Size minimum must not be greater than maximum"),
125
0
            Error::MemSizeTooBig => f.write_str("Memory size must be at most 65536 pages (4GiB)"),
126
0
            Error::InvalidGlobalIdx(idx) => f.write_fmt(format_args!(
127
0
                "An invalid global index `{idx}` was specified"
128
0
            )),
129
0
            Error::GlobalIsConst => f.write_str("A const global cannot be written to"),
130
48
            Error::RuntimeError(err) => err.fmt(f),
131
0
            Error::FoundLabel(lk) => f.write_fmt(format_args!(
132
0
                "Expecting a ValType, a Label was found: {lk:?}"
133
0
            )),
134
0
            Error::ExpectedAnOperand => f.write_str("Expected a ValType"), // Error => f.write_str("Expected an operand (ValType) on the stack")
135
0
            Error::MemoryIsNotDefined(memidx) => f.write_fmt(format_args!(
136
0
                "C.mems[{}] is NOT defined when it should be",
137
0
                memidx
138
0
            )),
139
0
            Error::ErroneousAlignment(mem_align, minimum_wanted_alignment) => {
140
0
                f.write_fmt(format_args!(
141
0
                    "Alignment ({}) is not less or equal to {}",
142
0
                    mem_align, minimum_wanted_alignment
143
0
                ))
144
            }
145
0
            Error::NoDataSegments => f.write_str("Data Count is None"),
146
0
            Error::DataSegmentNotFound(data_idx) => {
147
0
                f.write_fmt(format_args!("Data Segment {} not found", data_idx))
148
            }
149
        }
150
349
    }
151
}
152
153
impl Display for RuntimeError {
154
49
    fn fmt(&self, f: &mut Formatter<'_>) -> core::fmt::Result {
155
49
        match self {
156
0
            RuntimeError::DivideBy0 => f.write_str("Divide by zero is not permitted"),
157
45
            RuntimeError::UnrepresentableResult => f.write_str("Result is unrepresentable"),
158
3
            RuntimeError::FunctionNotFound => f.write_str("Function not found"),
159
0
            RuntimeError::StackSmash => f.write_str("Stack smashed"),
160
1
            RuntimeError::BadConversionToInteger => f.write_str("Bad conversion to integer"),
161
0
            RuntimeError::MemoryAccessOutOfBounds => f.write_str("Memory access out of bounds"),
162
        }
163
49
    }
164
}
165
166
pub type Result<T> = core::result::Result<T, Error>;
167
168
impl From<RuntimeError> for Error {
169
0
    fn from(value: RuntimeError) -> Self {
170
0
        Self::RuntimeError(value)
171
0
    }
172
}