/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 | | } |