Skip to content

Commit f7c77a7

Browse files
authored
Add conversions between TrapCode and u8 (#1651)
* add TrapCode <-> u8 conversions * simplify From<TrapCode> for u8 impl
1 parent 392199e commit f7c77a7

File tree

1 file changed

+63
-18
lines changed

1 file changed

+63
-18
lines changed

crates/core/src/trap.rs

Lines changed: 63 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -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

296341
impl TrapCode {

0 commit comments

Comments
 (0)