tinywasm_types/
instructions.rs

1use super::{FuncAddr, GlobalAddr, LabelAddr, LocalAddr, TableAddr, TypeAddr, ValType};
2use crate::{DataAddr, ElemAddr, MemAddr};
3
4/// Represents a memory immediate in a WebAssembly memory instruction.
5#[derive(Debug, Copy, Clone, PartialEq)]
6#[cfg_attr(feature = "archive", derive(rkyv::Archive, rkyv::Serialize, rkyv::Deserialize), archive(check_bytes))]
7pub struct MemoryArg {
8    pub offset: u64,
9    pub mem_addr: MemAddr,
10}
11
12type BrTableDefault = u32;
13type BrTableLen = u32;
14type EndOffset = u32;
15type ElseOffset = u32;
16
17#[derive(Debug, Clone, Copy, PartialEq)]
18#[cfg_attr(feature = "archive", derive(rkyv::Archive, rkyv::Serialize, rkyv::Deserialize), archive(check_bytes))]
19pub enum ConstInstruction {
20    I32Const(i32),
21    I64Const(i64),
22    F32Const(f32),
23    F64Const(f64),
24    GlobalGet(GlobalAddr),
25    RefNull(ValType),
26    RefFunc(FuncAddr),
27}
28
29/// A WebAssembly Instruction
30///
31/// These are our own internal bytecode instructions so they may not match the spec exactly.
32/// Wasm Bytecode can map to multiple of these instructions.
33///
34/// # Differences to the spec
35/// * `br_table` stores the jump labels in the following `br_label` instructions to keep this enum small.
36/// * Lables/Blocks: we store the label end offset in the instruction itself and use `EndBlockFrame` to mark the end of a block.
37///   This makes it easier to implement the label stack iteratively.
38///
39/// See <https://webassembly.github.io/spec/core/binary/instructions.html>
40#[derive(Debug, Clone, PartialEq)]
41#[cfg_attr(feature = "archive", derive(rkyv::Archive, rkyv::Serialize, rkyv::Deserialize), archive(check_bytes))]
42// should be kept as small as possible (16 bytes max)
43#[rustfmt::skip]
44pub enum Instruction {
45    // > Custom Instructions
46    // // LocalGet + I32Const + I32Add
47    // I32LocalGetConstAdd(LocalAddr, i32),
48    // // LocalGet + I32Const + I32Store
49    // I32ConstStoreLocal { local: LocalAddr, const_i32: i32, offset: u32, mem_addr: u8 },
50    // // LocalGet + LocalGet + I32Store
51    // I32StoreLocal { local_a: LocalAddr, local_b: LocalAddr, offset: u32, mem_addr: u8 },
52    // // I64Xor + I64Const + I64RotL 
53    // // Commonly used by a few crypto libraries
54    // I64XorConstRotl(i64),
55    // // LocalTee + LocalGet
56    // LocalTeeGet(LocalAddr, LocalAddr),
57    // LocalGet2(LocalAddr, LocalAddr),
58    // LocalGet3(LocalAddr, LocalAddr, LocalAddr),
59    // LocalGetSet(LocalAddr, LocalAddr),
60 
61    // LocalGetGet32(LocalAddr, LocalAddr), LocalGetGet64(LocalAddr, LocalAddr), LocalGetGet128(LocalAddr, LocalAddr),
62    // LocalTeeGet32(LocalAddr, LocalAddr), LocalTeeGet64(LocalAddr, LocalAddr), LocalTeeGet128(LocalAddr, LocalAddr),
63    LocalCopy32(LocalAddr, LocalAddr), LocalCopy64(LocalAddr, LocalAddr), LocalCopy128(LocalAddr, LocalAddr), LocalCopy128Ref(LocalAddr, LocalAddr), LocalCopyRef(LocalAddr, LocalAddr),
64    LocalsStore32(LocalAddr, LocalAddr, u32, MemAddr), LocalsStore64(LocalAddr, LocalAddr, u32, MemAddr), LocalsStore128(LocalAddr, LocalAddr, u32, MemAddr), LocalsStoreRef(LocalAddr, LocalAddr, u32, MemAddr),
65
66    // > Control Instructions
67    // See <https://webassembly.github.io/spec/core/binary/instructions.html#control-instructions>
68    Unreachable,
69    Nop,
70
71    Block(EndOffset), 
72    BlockWithType(ValType, EndOffset),
73    BlockWithFuncType(TypeAddr, EndOffset),
74 
75    Loop(EndOffset),
76    LoopWithType(ValType, EndOffset),
77    LoopWithFuncType(TypeAddr, EndOffset),
78
79    If(ElseOffset, EndOffset),
80    IfWithType(ValType, ElseOffset, EndOffset),
81    IfWithFuncType(TypeAddr, ElseOffset, EndOffset),
82
83    Else(EndOffset),
84    EndBlockFrame,
85    Br(LabelAddr),
86    BrIf(LabelAddr),
87    BrTable(BrTableDefault, BrTableLen), // has to be followed by multiple BrLabel instructions
88    BrLabel(LabelAddr),
89    Return,
90    Call(FuncAddr),
91    CallIndirect(TypeAddr, TableAddr),
92    ReturnCall(FuncAddr),
93    ReturnCallIndirect(TypeAddr, TableAddr),
94 
95    // > Parametric Instructions
96    // See <https://webassembly.github.io/spec/core/binary/instructions.html#parametric-instructions>
97    Drop32,
98    Drop64,
99    Drop128,
100    DropRef,
101
102    Select32,
103    Select64,
104    Select128,
105    SelectRef,
106
107    // > Variable Instructions
108    // See <https://webassembly.github.io/spec/core/binary/instructions.html#variable-instructions>
109    LocalGet32(LocalAddr),
110    LocalGet64(LocalAddr),
111    LocalGet128(LocalAddr),
112    LocalGetRef(LocalAddr),
113
114    LocalSet32(LocalAddr),
115    LocalSet64(LocalAddr),
116    LocalSet128(LocalAddr),
117    LocalSetRef(LocalAddr),
118
119    LocalTee32(LocalAddr),
120    LocalTee64(LocalAddr),
121    LocalTee128(LocalAddr),
122    LocalTeeRef(LocalAddr),
123
124    GlobalGet(GlobalAddr),
125    GlobalSet32(GlobalAddr),
126    GlobalSet64(GlobalAddr),
127    GlobalSet128(GlobalAddr),
128    GlobalSetRef(GlobalAddr),
129
130    // > Memory Instructions
131    I32Load { offset: u64, mem_addr: MemAddr },
132    I64Load { offset: u64, mem_addr: MemAddr },
133    F32Load { offset: u64, mem_addr: MemAddr },
134    F64Load { offset: u64, mem_addr: MemAddr },
135    I32Load8S { offset: u64, mem_addr: MemAddr },
136    I32Load8U { offset: u64, mem_addr: MemAddr },
137    I32Load16S { offset: u64, mem_addr: MemAddr },
138    I32Load16U { offset: u64, mem_addr: MemAddr },
139    I64Load8S { offset: u64, mem_addr: MemAddr },
140    I64Load8U { offset: u64, mem_addr: MemAddr },
141    I64Load16S { offset: u64, mem_addr: MemAddr },
142    I64Load16U { offset: u64, mem_addr: MemAddr },
143    I64Load32S { offset: u64, mem_addr: MemAddr },
144    I64Load32U { offset: u64, mem_addr: MemAddr },
145    I32Store { offset: u64, mem_addr: MemAddr },
146    I64Store { offset: u64, mem_addr: MemAddr },
147    F32Store { offset: u64, mem_addr: MemAddr },
148    F64Store { offset: u64, mem_addr: MemAddr },
149    I32Store8 { offset: u64, mem_addr: MemAddr },
150    I32Store16 { offset: u64, mem_addr: MemAddr },
151    I64Store8 { offset: u64, mem_addr: MemAddr },
152    I64Store16 { offset: u64, mem_addr: MemAddr },
153    I64Store32 { offset: u64, mem_addr: MemAddr },
154    MemorySize(MemAddr),
155    MemoryGrow(MemAddr),
156
157    // > Constants
158    I32Const(i32),
159    I64Const(i64),
160    F32Const(f32),
161    F64Const(f64),
162
163    // > Reference Types
164    RefNull(ValType),
165    RefFunc(FuncAddr),
166    RefIsNull,
167
168    // > Numeric Instructions
169    // See <https://webassembly.github.io/spec/core/binary/instructions.html#numeric-instructions>
170    I32Eqz, I32Eq, I32Ne, I32LtS, I32LtU, I32GtS, I32GtU, I32LeS, I32LeU, I32GeS, I32GeU,
171    I64Eqz, I64Eq, I64Ne, I64LtS, I64LtU, I64GtS, I64GtU, I64LeS, I64LeU, I64GeS, I64GeU,
172    // Comparisons
173    F32Eq, F32Ne, F32Lt, F32Gt, F32Le, F32Ge,
174    F64Eq, F64Ne, F64Lt, F64Gt, F64Le, F64Ge,
175    I32Clz, I32Ctz, I32Popcnt, I32Add, I32Sub, I32Mul, I32DivS, I32DivU, I32RemS, I32RemU,
176    I64Clz, I64Ctz, I64Popcnt, I64Add, I64Sub, I64Mul, I64DivS, I64DivU, I64RemS, I64RemU,
177    // Bitwise
178    I32And, I32Or, I32Xor, I32Shl, I32ShrS, I32ShrU, I32Rotl, I32Rotr,
179    I64And, I64Or, I64Xor, I64Shl, I64ShrS, I64ShrU, I64Rotl, I64Rotr,
180    // Floating Point
181    F32Abs, F32Neg, F32Ceil, F32Floor, F32Trunc, F32Nearest, F32Sqrt, F32Add, F32Sub, F32Mul, F32Div, F32Min, F32Max, F32Copysign,
182    F64Abs, F64Neg, F64Ceil, F64Floor, F64Trunc, F64Nearest, F64Sqrt, F64Add, F64Sub, F64Mul, F64Div, F64Min, F64Max, F64Copysign,
183    I32WrapI64, I32TruncF32S, I32TruncF32U, I32TruncF64S, I32TruncF64U, I32Extend8S, I32Extend16S,
184    I64Extend8S, I64Extend16S, I64Extend32S, I64ExtendI32S, I64ExtendI32U, I64TruncF32S, I64TruncF32U, I64TruncF64S, I64TruncF64U,
185    F32ConvertI32S, F32ConvertI32U, F32ConvertI64S, F32ConvertI64U, F32DemoteF64,
186    F64ConvertI32S, F64ConvertI32U, F64ConvertI64S, F64ConvertI64U, F64PromoteF32,
187    // Reinterpretations (noops at runtime)
188    I32ReinterpretF32, I64ReinterpretF64, F32ReinterpretI32, F64ReinterpretI64,
189    // Saturating Float-to-Int Conversions
190    I32TruncSatF32S, I32TruncSatF32U, I32TruncSatF64S, I32TruncSatF64U,
191    I64TruncSatF32S, I64TruncSatF32U, I64TruncSatF64S, I64TruncSatF64U,
192
193    // > Table Instructions
194    TableInit(ElemAddr, TableAddr),
195    TableGet(TableAddr),
196    TableSet(TableAddr),
197    TableCopy { from: TableAddr, to: TableAddr },
198    TableGrow(TableAddr),
199    TableSize(TableAddr),
200    TableFill(TableAddr),
201
202    // > Bulk Memory Instructions
203    MemoryInit(MemAddr, DataAddr),
204    MemoryCopy(MemAddr, MemAddr),
205    MemoryFill(MemAddr),
206    DataDrop(DataAddr),
207    ElemDrop(ElemAddr),
208}