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