1use core::fmt::{Display, Formatter};
2
3#[derive(Debug, PartialEq, Eq, Clone)]
4pub enum RuntimeError {
5 Trap(TrapError),
6
7 ModuleNotFound,
8 FunctionNotFound,
9 ResumableNotFound,
10 StackExhaustion,
11 HostFunctionSignatureMismatch,
12 WriteOnImmutableGlobal,
13 GlobalTypeMismatch,
14 TableAccessOutOfBounds,
16 UnknownExport,
17 TableTypeMismatch,
18
19 InvalidImportType,
21 RegistrySymbolAlreadyExists,
23 MoreThanOneMemory,
24 OutOfFuel,
26 ExternValsLenMismatch,
29 DuplicateExternDefinition,
32 FunctionInvocationSignatureMismatch,
34 UnexpectedHostCall,
38 UnsupportedHostCallDuringInstantiation,
41}
42
43impl Display for RuntimeError {
44 fn fmt(&self, f: &mut Formatter<'_>) -> core::fmt::Result {
45 match self {
46 RuntimeError::Trap(trap_error) => write!(f, "Execution trapped: {trap_error}"),
47 RuntimeError::FunctionNotFound => f.write_str("Function not found"),
48 RuntimeError::ModuleNotFound => f.write_str("No such module exists"),
49 RuntimeError::ResumableNotFound => f.write_str("No such resumable exists"),
50 RuntimeError::StackExhaustion => {
51 f.write_str("either the call stack or the value stack overflowed")
52 }
53 RuntimeError::HostFunctionSignatureMismatch => {
54 f.write_str("host function call did not respect its type signature")
55 }
56 RuntimeError::InvalidImportType => f.write_str("Invalid import type"),
57 RuntimeError::TableAccessOutOfBounds => f.write_str("A table access was out of bounds"),
58 RuntimeError::RegistrySymbolAlreadyExists => f.write_str(
59 "It was attempted to register a symbol under a name for which a symbol already exists.",
60 ),
61 RuntimeError::UnknownExport => {
62 f.write_str("An unknown export was referenced by its name.")
63 }
64 RuntimeError::TableTypeMismatch => {
65 f.write_str("An alloc/write operation failed on a table due to a type mismatch.")
66 }
67 RuntimeError::MoreThanOneMemory => {
68 f.write_str("As of not only one memory is allowed per module.")
69 }
70
71 RuntimeError::WriteOnImmutableGlobal => f.write_str(
72 "A write operation on a global failed due to the global being immutable",
73 ),
74 RuntimeError::GlobalTypeMismatch => {
75 f.write_str("An alloc/write operation on a global failed due to a type mismatch")
76 }
77 RuntimeError::OutOfFuel => {
78 f.write_str("Fueled execution that is not resumable has ran out of fuel")
79 }
80 RuntimeError::ExternValsLenMismatch => {
81 f.write_str("The number of module exports did not match the number of extern values provided for instantiation.")
82 }
83 RuntimeError::DuplicateExternDefinition => {
84 f.write_str("Linking failed because of a duplicate definition of some extern value")
85 }
86 RuntimeError::FunctionInvocationSignatureMismatch => {
87 f.write_str("A function was invoked with incorrect parameters or return types")
88 }
89 RuntimeError::UnexpectedHostCall => f.write_str(" The Store::invoke_simple method was used to execute some Wasm code but this resulted a host call, which is not supported in this mode"),
90 RuntimeError::UnsupportedHostCallDuringInstantiation => f.write_str("A host function was called from a start function during module instantiation"),
91 }
92 }
93}
94
95impl core::error::Error for RuntimeError {}
96
97#[derive(Debug, PartialEq, Eq, Clone)]
98pub enum TrapError {
99 DivideBy0,
100 UnrepresentableResult,
101 BadConversionToInteger,
103
104 MemoryOrDataAccessOutOfBounds,
109 TableOrElementAccessOutOfBounds,
114 UninitializedElement,
115 SignatureMismatch,
116 IndirectCallNullFuncRef,
117 TableAccessOutOfBounds,
118 ReachedUnreachable,
119}
120
121impl Display for TrapError {
122 fn fmt(&self, f: &mut Formatter<'_>) -> core::fmt::Result {
123 match self {
124 TrapError::DivideBy0 => f.write_str("Divide by zero is not permitted"),
125 TrapError::UnrepresentableResult => f.write_str("Result is unrepresentable"),
126 TrapError::BadConversionToInteger => f.write_str("Bad conversion to integer"),
127 TrapError::MemoryOrDataAccessOutOfBounds => {
128 f.write_str("Memory or data access out of bounds")
129 }
130 TrapError::TableOrElementAccessOutOfBounds => {
131 f.write_str("Table or element access out of bounds")
132 }
133 TrapError::UninitializedElement => f.write_str("Uninitialized element"),
134 TrapError::SignatureMismatch => f.write_str("Indirect call signature mismatch"),
135 TrapError::IndirectCallNullFuncRef => {
136 f.write_str("Indirect call targeted null reference")
137 }
138 TrapError::TableAccessOutOfBounds => {
139 f.write_str("Indirect call: table index out of bounds")
140 }
141 TrapError::ReachedUnreachable => f.write_str("An unreachable statement was reached"),
142 }
143 }
144}
145
146impl core::error::Error for TrapError {}
147
148impl From<TrapError> for RuntimeError {
149 fn from(value: TrapError) -> Self {
150 Self::Trap(value)
151 }
152}