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 UnknownImport,
24 RegistrySymbolAlreadyExists,
26 MoreThanOneMemory,
27 OutOfFuel,
29 ExternValsLenMismatch,
32 DuplicateExternDefinition,
35
36 UnableToResolveImport,
38}
39
40impl Display for RuntimeError {
41 fn fmt(&self, f: &mut Formatter<'_>) -> core::fmt::Result {
42 match self {
43 RuntimeError::Trap(trap_error) => write!(f, "{trap_error}"),
44 RuntimeError::FunctionNotFound => f.write_str("Function not found"),
45 RuntimeError::ModuleNotFound => f.write_str("No such module exists"),
46 RuntimeError::ResumableNotFound => f.write_str("No such resumable exists"),
47 RuntimeError::StackExhaustion => {
48 f.write_str("either the call stack or the value stack overflowed")
49 }
50 RuntimeError::HostFunctionSignatureMismatch => {
51 f.write_str("host function call did not respect its type signature")
52 }
53 RuntimeError::HostFunctionHaltedExecution => {
54 f.write_str("A host function requested execution to be halted.")
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::UnknownImport => f.write_str("Unknown Import"),
69 RuntimeError::MoreThanOneMemory => {
70 f.write_str("As of not only one memory is allowed per module.")
71 }
72
73 RuntimeError::WriteOnImmutableGlobal => f.write_str(
74 "A write operation on a global failed due to the global being immutable",
75 ),
76 RuntimeError::GlobalTypeMismatch => {
77 f.write_str("An alloc/write operation on a global failed due to a type mismatch")
78 }
79 RuntimeError::OutOfFuel => {
80 f.write_str("Fueled execution that is not resumable has ran out of fuel")
81 }
82 RuntimeError::ExternValsLenMismatch => {
83 f.write_str("The number of module exports did not match the number of extern values provided for instantiation.")
84 }
85 RuntimeError::DuplicateExternDefinition => {
86 f.write_str("Linking failed because of a duplicate definition of some extern value")
87 }
88 RuntimeError::UnableToResolveImport => {
89 f.write_str("Linking failed because an import could not be resolved")
90 }
91 }
92 }
93}
94
95#[derive(Debug, PartialEq, Eq, Clone)]
96pub enum TrapError {
97 DivideBy0,
98 UnrepresentableResult,
99 BadConversionToInteger,
101
102 MemoryOrDataAccessOutOfBounds,
107 TableOrElementAccessOutOfBounds,
112 UninitializedElement,
113 SignatureMismatch,
114 IndirectCallNullFuncRef,
115 TableAccessOutOfBounds,
116 ReachedUnreachable,
117}
118
119impl Display for TrapError {
120 fn fmt(&self, f: &mut Formatter<'_>) -> core::fmt::Result {
121 match self {
122 TrapError::DivideBy0 => f.write_str("Divide by zero is not permitted"),
123 TrapError::UnrepresentableResult => f.write_str("Result is unrepresentable"),
124 TrapError::BadConversionToInteger => f.write_str("Bad conversion to integer"),
125 TrapError::MemoryOrDataAccessOutOfBounds => {
126 f.write_str("Memory or data access out of bounds")
127 }
128 TrapError::TableOrElementAccessOutOfBounds => {
129 f.write_str("Table or element access out of bounds")
130 }
131 TrapError::UninitializedElement => f.write_str("Uninitialized element"),
132 TrapError::SignatureMismatch => f.write_str("Indirect call signature mismatch"),
133 TrapError::IndirectCallNullFuncRef => {
134 f.write_str("Indirect call targeted null reference")
135 }
136 TrapError::TableAccessOutOfBounds => {
137 f.write_str("Indirect call: table index out of bounds")
138 }
139 TrapError::ReachedUnreachable => {
140 f.write_str("an unreachable statement was reached, triggered a trap")
141 }
142 }
143 }
144}
145
146impl From<TrapError> for RuntimeError {
147 fn from(value: TrapError) -> Self {
148 Self::Trap(value)
149 }
150}