@@ -211,25 +211,70 @@ impl StdError for Trap {
211211 }
212212}
213213
214- /// Error type which can be thrown by wasm code or by host environment.
215- ///
216- /// See [`Trap`] for details.
217- ///
218- /// [`Trap`]: struct.Trap.html
219- #[ derive( Debug , Copy , Clone , PartialEq , Eq ) ]
220- pub enum TrapCode {
214+ /// An invalid [`TrapCode`] integer value.
215+ #[ derive( Debug , Copy , Clone ) ]
216+ pub struct InvalidTrapCode ;
217+
218+ macro_rules! generate_trap_code {
219+ (
220+ $( $( #[ $attr: meta] ) * $ident: ident = $discr: literal ) ,* $( , ) ?
221+ ) => {
222+ /// Error type which can be thrown by wasm code or by host environment.
223+ ///
224+ /// See [`Trap`] for details.
225+ ///
226+ /// [`Trap`]: struct.Trap.html
227+ #[ derive( Debug , Copy , Clone , PartialEq , Eq ) ]
228+ #[ repr( u8 ) ]
229+ pub enum TrapCode {
230+ $(
231+ $( #[ $attr] ) *
232+ $ident = $discr
233+ ) ,*
234+ }
235+
236+ impl From <TrapCode > for u8 {
237+ fn from( trap_code: TrapCode ) -> Self {
238+ trap_code as _
239+ }
240+ }
241+
242+ impl TryFrom <u8 > for TrapCode {
243+ type Error = InvalidTrapCode ;
244+
245+ fn try_from( value: u8 ) -> Result <Self , Self :: Error > {
246+ match value {
247+ $( $discr => Ok ( TrapCode :: $ident) , ) *
248+ _ => Err ( InvalidTrapCode ) ,
249+ }
250+ }
251+ }
252+
253+ #[ test]
254+ fn trap_code_conversion( ) {
255+ $(
256+ assert_eq!(
257+ TrapCode :: try_from( TrapCode :: $ident as u8 ) . unwrap( ) ,
258+ TrapCode :: $ident,
259+ ) ;
260+ ) *
261+ assert!( TrapCode :: try_from( u8 :: MAX ) . is_err( ) ) ;
262+ }
263+ } ;
264+ }
265+ generate_trap_code ! {
221266 /// Wasm code executed `unreachable` opcode.
222267 ///
223268 /// This indicates that unreachable Wasm code was actually reached.
224269 /// This opcode have a similar purpose as `ud2` in x86.
225- UnreachableCodeReached ,
270+ UnreachableCodeReached = 0 ,
226271
227272 /// Attempt to load or store at the address which
228273 /// lies outside of bounds of the memory.
229274 ///
230275 /// Since addresses are interpreted as unsigned integers, out of bounds access
231276 /// can't happen with negative addresses (i.e. they will always wrap).
232- MemoryOutOfBounds ,
277+ MemoryOutOfBounds = 1 ,
233278
234279 /// Attempt to access table element at index which
235280 /// lies outside of bounds.
@@ -239,58 +284,58 @@ pub enum TrapCode {
239284 ///
240285 /// Since indexes are interpreted as unsigned integers, out of bounds access
241286 /// can't happen with negative indexes (i.e. they will always wrap).
242- TableOutOfBounds ,
287+ TableOutOfBounds = 2 ,
243288
244289 /// Indicates that a `call_indirect` instruction called a function at
245290 /// an uninitialized (i.e. `null`) table index.
246- IndirectCallToNull ,
291+ IndirectCallToNull = 3 ,
247292
248293 /// Attempt to divide by zero.
249294 ///
250295 /// This trap typically can happen if `div` or `rem` is executed with
251296 /// zero as divider.
252- IntegerDivisionByZero ,
297+ IntegerDivisionByZero = 4 ,
253298
254299 /// An integer arithmetic operation caused an overflow.
255300 ///
256301 /// This can happen when trying to do signed division (or get the remainder)
257302 /// -2<sup>N-1</sup> over -1. This is because the result +2<sup>N-1</sup>
258303 /// isn't representable as a N-bit signed integer.
259- IntegerOverflow ,
304+ IntegerOverflow = 5 ,
260305
261306 /// Attempted to make an invalid conversion to an integer type.
262307 ///
263308 /// This can for example happen when trying to truncate NaNs,
264309 /// infinity, or value for which the result is out of range into an integer.
265- BadConversionToInteger ,
310+ BadConversionToInteger = 6 ,
266311
267312 /// Stack overflow.
268313 ///
269314 /// This is likely caused by some infinite or very deep recursion.
270315 /// Extensive inlining might also be the cause of stack overflow.
271- StackOverflow ,
316+ StackOverflow = 7 ,
272317
273318 /// Attempt to invoke a function with mismatching signature.
274319 ///
275320 /// This can happen with indirect calls as they always
276321 /// specify the expected signature of function. If an indirect call is executed
277322 /// with an index that points to a function with signature different of what is
278323 /// expected by this indirect call, this trap is raised.
279- BadSignature ,
324+ BadSignature = 8 ,
280325
281326 /// This trap is raised when a WebAssembly execution ran out of fuel.
282327 ///
283328 /// The Wasmi execution engine can be configured to instrument its
284329 /// internal bytecode so that fuel is consumed for each executed instruction.
285330 /// This is useful to deterministically halt or yield a WebAssembly execution.
286- OutOfFuel ,
331+ OutOfFuel = 9 ,
287332
288333 /// This trap is raised when a growth operation was attempted and an
289334 /// installed `wasmi::ResourceLimiter` returned `Err(...)` from the
290335 /// associated `table_growing` or `memory_growing` method, indicating a
291336 /// desire on the part of the embedder to trap the interpreter rather than
292337 /// merely fail the growth operation.
293- GrowthOperationLimited ,
338+ GrowthOperationLimited = 10 ,
294339}
295340
296341impl TrapCode {
0 commit comments