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