1 /**
2  * \file wasmtime/trap.h
3  *
4  * Wasmtime APIs for interacting with traps and extensions to #wasm_trap_t.
5  */
6 
7 #ifndef WASMTIME_TRAP_H
8 #define WASMTIME_TRAP_H
9 
10 #include <wasm.h>
11 
12 #ifdef __cplusplus
13 extern "C" {
14 #endif
15 
16 /**
17  * \brief Code of an instruction trap.
18  *
19  * See #wasmtime_trap_code_enum for possible values.
20  */
21 typedef uint8_t wasmtime_trap_code_t;
22 
23 /**
24  * \brief Trap codes for instruction traps.
25  */
26 enum wasmtime_trap_code_enum {
27   /// The current stack space was exhausted.
28   WASMTIME_TRAP_CODE_STACK_OVERFLOW = 0,
29   /// An out-of-bounds memory access.
30   WASMTIME_TRAP_CODE_MEMORY_OUT_OF_BOUNDS = 1,
31   /// A wasm atomic operation was presented with a not-naturally-aligned
32   /// linear-memory address.
33   WASMTIME_TRAP_CODE_HEAP_MISALIGNED = 2,
34   /// An out-of-bounds access to a table.
35   WASMTIME_TRAP_CODE_TABLE_OUT_OF_BOUNDS = 3,
36   /// Indirect call to a null table entry.
37   WASMTIME_TRAP_CODE_INDIRECT_CALL_TO_NULL = 4,
38   /// Signature mismatch on indirect call.
39   WASMTIME_TRAP_CODE_BAD_SIGNATURE = 5,
40   /// An integer arithmetic operation caused an overflow.
41   WASMTIME_TRAP_CODE_INTEGER_OVERFLOW = 6,
42   /// An integer division by zero.
43   WASMTIME_TRAP_CODE_INTEGER_DIVISION_BY_ZERO = 7,
44   /// Failed float-to-int conversion.
45   WASMTIME_TRAP_CODE_BAD_CONVERSION_TO_INTEGER = 8,
46   /// Code that was supposed to have been unreachable was reached.
47   WASMTIME_TRAP_CODE_UNREACHABLE_CODE_REACHED = 9,
48   /// Execution has potentially run too long and may be interrupted.
49   WASMTIME_TRAP_CODE_INTERRUPT = 10,
50   /// Execution has run out of the configured fuel amount.
51   WASMTIME_TRAP_CODE_OUT_OF_FUEL = 11,
52   /// Used to indicate that a trap was raised by atomic wait operations on non
53   /// shared memory.
54   WASMTIME_TRAP_CODE_ATOMIC_WAIT_NON_SHARED_MEMORY = 12,
55   /// Call to a null reference.
56   WASMTIME_TRAP_CODE_NULL_REFERENCE = 13,
57   /// Attempt to access beyond the bounds of an array.
58   WASMTIME_TRAP_CODE_ARRAY_OUT_OF_BOUNDS = 14,
59   /// Attempted an allocation that was too large to succeed.
60   WASMTIME_TRAP_CODE_ALLOCATION_TOO_LARGE = 15,
61   /// Attempted to cast a reference to a type that it is not an instance of.
62   WASMTIME_TRAP_CODE_CAST_FAILURE = 16,
63   /// When the `component-model` feature is enabled this trap represents a
64   /// scenario where one component tried to call another component but it
65   /// would have violated the reentrance rules of the component model,
66   /// triggering a trap instead.
67   WASMTIME_TRAP_CODE_CANNOT_ENTER_COMPONENT = 17,
68   /// Async-lifted export failed to produce a result by calling `task.return`
69   /// before returning `STATUS_DONE` and/or after all host tasks completed.
70   WASMTIME_TRAP_CODE_NO_ASYNC_RESULT = 18,
71   /// We are suspending to a tag for which there is no active handler.
72   WASMTIME_TRAP_CODE_UNHANDLED_TAG = 19,
73   /// Attempt to resume a continuation twice.
74   WASMTIME_TRAP_CODE_CONTINUATION_ALREADY_CONSUMED = 20,
75   /// A Pulley opcode was executed at runtime when the opcode was disabled at
76   /// compile time.
77   WASMTIME_TRAP_CODE_DISABLED_OPCODE = 21,
78   /// Async event loop deadlocked; i.e. it cannot make further progress given
79   /// that all host tasks have completed and any/all host-owned stream/future
80   /// handles have been dropped.
81   WASMTIME_TRAP_CODE_ASYNC_DEADLOCK = 22,
82   /// When the `component-model` feature is enabled this trap represents a
83   /// scenario where a component instance tried to call an import or intrinsic
84   /// when it wasn't allowed to, e.g. from a post-return function.
85   WASMTIME_TRAP_CODE_CANNOT_LEAVE_COMPONENT = 23,
86   /// A synchronous task attempted to make a potentially blocking call prior
87   /// to returning.
88   WASMTIME_TRAP_CODE_CANNOT_BLOCK_SYNC_TASK = 24,
89   /// A component tried to lift a `char` with an invalid bit pattern.
90   WASMTIME_TRAP_CODE_INVALID_CHAR = 25,
91   /// Debug assertion generated for a fused adapter regarding the expected
92   /// completion of a string encoding operation.
93   WASMTIME_TRAP_CODE_DEBUG_ASSERT_STRING_ENCODING_FINISHED = 26,
94   /// Debug assertion generated for a fused adapter regarding a string
95   /// encoding operation.
96   WASMTIME_TRAP_CODE_DEBUG_ASSERT_EQUAL_CODE_UNITS = 27,
97   /// Debug assertion generated for a fused adapter regarding the alignment of
98   /// a pointer.
99   WASMTIME_TRAP_CODE_DEBUG_ASSERT_POINTER_ALIGNED = 28,
100   /// Debug assertion generated for a fused adapter regarding the upper bits
101   /// of a 64-bit value.
102   WASMTIME_TRAP_CODE_DEBUG_ASSERT_UPPER_BITS_UNSET = 29,
103   /// A component tried to lift or lower a string past the end of its memory.
104   WASMTIME_TRAP_CODE_STRING_OUT_OF_BOUNDS = 30,
105   /// A component tried to lift or lower a list past the end of its memory.
106   WASMTIME_TRAP_CODE_LIST_OUT_OF_BOUNDS = 31,
107   /// A component used an invalid discriminant when lowering a variant value.
108   WASMTIME_TRAP_CODE_INVALID_DISCRIMINANT = 32,
109   /// A component passed an unaligned pointer when lifting or lowering a
110   /// value.
111   WASMTIME_TRAP_CODE_UNALIGNED_POINTER = 33,
112   /// `task.cancel` invoked in an invalid way.
113   WASMTIME_TRAP_CODE_TASK_CANCEL_NOT_CANCELLED = 34,
114   /// `task.cancel` or `task.return` called too many times
115   WASMTIME_TRAP_CODE_TASK_CANCEL_OR_RETURN_TWICE = 35,
116   /// `subtask.cancel` invoked after it already finished.
117   WASMTIME_TRAP_CODE_SUBTASK_CANCEL_AFTER_TERMINAL = 36,
118   /// `task.return` invoked with an invalid type.
119   WASMTIME_TRAP_CODE_TASK_RETURN_INVALID = 37,
120   /// `waitable-set.drop` invoked on a waitable set with waiters.
121   WASMTIME_TRAP_CODE_WAITABLE_SET_DROP_HAS_WAITERS = 38,
122   /// `subtask.drop` invoked on a subtask that hasn't resolved yet.
123   WASMTIME_TRAP_CODE_SUBTASK_DROP_NOT_RESOLVED = 39,
124   /// `thread.new-indirect` invoked with a function that has an invalid type.
125   WASMTIME_TRAP_CODE_THREAD_NEW_INDIRECT_INVALID_TYPE = 40,
126   /// `thread.new-indirect` invoked with an uninitialized function reference.
127   WASMTIME_TRAP_CODE_THREAD_NEW_INDIRECT_UNINITIALIZED = 41,
128   /// Backpressure-related intrinsics overflowed the built-in counter.
129   WASMTIME_TRAP_CODE_BACKPRESSURE_OVERFLOW = 42,
130   /// Invalid code returned from `callback` of `async`-lifted function.
131   WASMTIME_TRAP_CODE_UNSUPPORTED_CALLBACK_CODE = 43,
132   /// Cannot resume a thread which is not suspended.
133   WASMTIME_TRAP_CODE_CANNOT_RESUME_THREAD = 44,
134   /// Cannot issue a read/write on a future/stream while there is a
135   /// pending operation already.
136   WASMTIME_TRAP_CODE_CONCURRENT_FUTURE_STREAM_OP = 45,
137 };
138 
139 /**
140  * \brief Creates a new trap with the given message.
141  *
142  * \param msg the message to associate with this trap
143  * \param msg_len the byte length of `msg`
144  *
145  * The #wasm_trap_t returned is owned by the caller.
146  */
147 WASM_API_EXTERN wasm_trap_t *wasmtime_trap_new(const char *msg, size_t msg_len);
148 
149 /**
150  * \brief Creates a new trap from the given trap code.
151  *
152  * \param code the trap code to associate with this trap
153  *
154  * The #wasm_trap_t returned is owned by the caller.
155  */
156 WASM_API_EXTERN wasm_trap_t *wasmtime_trap_new_code(wasmtime_trap_code_t code);
157 
158 /**
159  * \brief Attempts to extract the trap code from this trap.
160  *
161  * Returns `true` if the trap is an instruction trap triggered while
162  * executing Wasm. If `true` is returned then the trap code is returned
163  * through the `code` pointer. If `false` is returned then this is not
164  * an instruction trap -- traps can also be created using wasm_trap_new,
165  * or occur with WASI modules exiting with a certain exit code.
166  */
167 WASM_API_EXTERN bool wasmtime_trap_code(const wasm_trap_t *,
168                                         wasmtime_trap_code_t *code);
169 
170 /**
171  * \brief Returns a human-readable name for this frame's function.
172  *
173  * This function will attempt to load a human-readable name for function this
174  * frame points to. This function may return `NULL`.
175  *
176  * The lifetime of the returned name is the same as the #wasm_frame_t itself.
177  */
178 WASM_API_EXTERN const wasm_name_t *
179 wasmtime_frame_func_name(const wasm_frame_t *);
180 
181 /**
182  * \brief Returns a human-readable name for this frame's module.
183  *
184  * This function will attempt to load a human-readable name for module this
185  * frame points to. This function may return `NULL`.
186  *
187  * The lifetime of the returned name is the same as the #wasm_frame_t itself.
188  */
189 WASM_API_EXTERN const wasm_name_t *
190 wasmtime_frame_module_name(const wasm_frame_t *);
191 
192 #ifdef __cplusplus
193 } // extern "C"
194 #endif
195 
196 #endif // WASMTIME_TRAP_H
197