1#[cfg(feature = "lua51")]
2const LUA_OP_SIZE: u32 = 6;
3#[cfg(feature = "lua51")]
4const LUA_OP_POSITION: u32 = 0;
5
6#[repr(u8)]
7#[derive(Copy, Clone, Debug, PartialEq, Eq)]
8#[cfg(feature = "lua51")]
9pub enum LuaOpcode {
10 Move,
11 LoadK,
12 LoadBool,
13 LoadNil,
14 GetUpval,
15
16 GetGlobal,
17 GetTable,
18
19 SetGlobal,
20 SetUpval,
21 SetTable,
22
23 NewTable,
24
25 Self_,
26
27 Add,
28 Sub,
29 Mul,
30 Div,
31 Mod,
32 Pow,
33 Unm,
34 Not,
35 Len,
36
37 Concat,
38
39 Jmp,
40
41 Eq,
42 Lt,
43 Le,
44
45 Test,
46 TestSet,
47
48 Call,
49 TailCall,
50 Return,
51
52 ForLoop,
53 ForPrep,
54
55 TForLoop,
56 SetList,
57
58 Close,
59 Closure,
60
61 Vararg,
62}
63
64#[repr(u8)]
65#[derive(Copy, Clone, Debug, PartialEq, Eq)]
66#[cfg(feature = "luau")]
67pub enum LuauOpcode {
68 Nop,
69 Break,
70 LoadNil,
71 LoadB,
72 LoadN,
73 LoadK,
74 Move,
75 GetGlobal,
76 SetGlobal,
77 GetUpval,
78 SetUpval,
79 CloseUpvals,
80 GetImport,
81 GetTable,
82 SetTable,
83 GetTableKs,
84 SetTableKs,
85 GetTableN,
86 SetTableN,
87 NewClosure,
88 NameCall,
89 Call,
90 Return,
91 Jump,
92 JumpBack,
93 JumpIf,
94 JumpIfNot,
95 JumpIfEq,
96 JumpIfLe,
97 JumpIfLt,
98 JumpIfNotEq,
99 JumpIfNotLe,
100 JumpIfNotLt,
101 Add,
102 Sub,
103 Mul,
104 Div,
105 Mod,
106 Pow,
107 AddK,
108 SubK,
109 MulK,
110 DivK,
111 ModK,
112 PowK,
113 And,
114 Or,
115 AndK,
116 OrK,
117 Concat,
118 Not,
119 Minus,
120 Length,
121 NewTable,
122 DupTable,
123 SetList,
124 ForNPrep,
125 ForNLoop,
126 ForGLoop,
127 ForGPrepInext,
128 FastCall3,
129 ForGPrepNext,
130 NativeCall,
131 GetVarargs,
132 DupClosure,
133 PrepVarargs,
134 LoadKx,
135 JumpX,
136 FastCall,
137 Coverage,
138 Capture,
139 SubRk,
140 DivRk,
141 FastCall1,
142 FastCall2,
143 FastCall2K,
144 ForGPrep,
145 JumpXeqkNil,
146 JumpXeqkB,
147 JumpXeqkN,
148 JumpXeqkS,
149 IDiv,
150 IDivK,
151}
152
153#[cfg(feature = "lua51")]
154impl LuaOpcode {
155 pub(crate) fn index(op: u8) -> LuaOpcode {
156 unsafe { std::mem::transmute(op) }
157 }
158}
159
160#[cfg(feature = "luau")]
161impl LuauOpcode {
162 pub(crate) fn index(op: u8) -> LuauOpcode {
163 unsafe { std::mem::transmute(op) }
164 }
165}
166
167#[derive(Clone, Copy, Debug, PartialEq, Eq)]
168pub enum OpCode {
169 #[cfg(feature = "lua51")]
170 LuaOpcode(LuaOpcode),
171 #[cfg(feature = "luau")]
172 LuauOpcode(LuauOpcode),
173}
174
175pub struct Instruction(pub u32);
176
177#[cfg(feature = "lua51")]
178pub trait LuaInstruction {
179 fn opcode(&self) -> OpCode;
180 fn mask_0(&self, n: u32, p: u32) -> u32;
182 fn mask_1(&self, n: u32, p: u32) -> u32;
184}
185
186#[cfg(feature = "luau")]
187pub trait LuauInstruction {
188 fn opcode(&self) -> OpCode;
189}
190
191#[cfg(feature = "lua51")]
192impl LuaInstruction for Instruction {
193 fn opcode(&self) -> OpCode {
194 let op = ((self.0 >> LUA_OP_POSITION) as u8) & self.mask_1(LUA_OP_SIZE, 0) as u8;
195 OpCode::LuaOpcode(LuaOpcode::index(op))
196 }
197
198 fn mask_1(&self, n: u32, p: u32) -> u32 {
199 ((1u32 << n) - 1) << p
200 }
201
202 fn mask_0(&self, n: u32, p: u32) -> u32 {
203 !self.mask_1(n, p)
204 }
205}
206
207#[cfg(feature = "luau")]
208impl LuauInstruction for Instruction {
209 fn opcode(&self) -> OpCode {
210 let op = (self.0 & 0xff) as u8;
211 OpCode::LuauOpcode(LuauOpcode::index(op))
212 }
213}
214
215impl Instruction {
216 pub fn from_bytes(bytes: &[u8]) -> Self {
217 Instruction(u32::from_le_bytes(bytes.try_into().unwrap()))
218 }
219}