Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
bytecodealliance
GitHub Repository: bytecodealliance/wasmtime
Path: blob/main/pulley/src/opcode.rs
1691 views
1
//! Pulley opcodes (without operands).
2
3
macro_rules! define_opcode {
4
(
5
$(
6
$( #[$attr:meta] )*
7
$snake_name:ident = $name:ident $( {
8
$(
9
$( #[$field_attr:meta] )*
10
$field:ident : $field_ty:ty
11
),*
12
} )? ;
13
)*
14
) => {
15
/// An opcode without its immediates and operands.
16
#[repr(u8)]
17
#[derive(Clone, Copy, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)]
18
pub enum Opcode {
19
$(
20
$( #[$attr] )*
21
$name,
22
)*
23
/// The extended-op opcode. An `ExtendedOpcode` follows this opcode.
24
ExtendedOp,
25
}
26
27
impl Opcode {
28
/// The value of the maximum defined opcode.
29
pub const MAX: u8 = Opcode::ExtendedOp as u8;
30
}
31
}
32
}
33
for_each_op!(define_opcode);
34
35
impl Opcode {
36
/// Create a new `Opcode` from the given byte.
37
///
38
/// Returns `None` if `byte` is not a valid opcode.
39
pub fn new(byte: u8) -> Option<Self> {
40
if byte <= Self::MAX {
41
Some(unsafe { Self::unchecked_new(byte) })
42
} else {
43
None
44
}
45
}
46
47
/// Like `new` but does not check whether `byte` is a valid opcode.
48
///
49
/// # Safety
50
///
51
/// It is unsafe to pass a `byte` that is not a valid opcode.
52
pub unsafe fn unchecked_new(byte: u8) -> Self {
53
debug_assert!(byte <= Self::MAX);
54
unsafe { core::mem::transmute(byte) }
55
}
56
}
57
58
macro_rules! define_extended_opcode {
59
(
60
$(
61
$( #[$attr:meta] )*
62
$snake_name:ident = $name:ident $( { $( $field:ident : $field_ty:ty ),* } )? ;
63
)*
64
) => {
65
/// An extended opcode.
66
#[repr(u16)]
67
#[derive(Clone, Copy, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)]
68
pub enum ExtendedOpcode {
69
$(
70
$( #[$attr] )*
71
$name,
72
)*
73
}
74
75
impl ExtendedOpcode {
76
/// The value of the maximum defined extended opcode.
77
pub const MAX: u16 = $(
78
if true { 1 } else { ExtendedOpcode::$name as u16 } +
79
)* 0;
80
}
81
};
82
}
83
for_each_extended_op!(define_extended_opcode);
84
85
impl ExtendedOpcode {
86
/// Create a new `ExtendedOpcode` from the given bytes.
87
///
88
/// Returns `None` if `bytes` is not a valid extended opcode.
89
pub fn new(bytes: u16) -> Option<Self> {
90
if bytes <= Self::MAX {
91
Some(unsafe { Self::unchecked_new(bytes) })
92
} else {
93
None
94
}
95
}
96
97
/// Like `new` but does not check whether `bytes` is a valid opcode.
98
///
99
/// # Safety
100
///
101
/// It is unsafe to pass `bytes` that is not a valid opcode.
102
pub unsafe fn unchecked_new(byte: u16) -> Self {
103
debug_assert!(byte <= Self::MAX);
104
unsafe { core::mem::transmute(byte) }
105
}
106
}
107
108