lua_bytecode/
opcode.rs

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    /* creates a mask with `n' 0 bits at position `p' */
181    fn mask_0(&self, n: u32, p: u32) -> u32;
182    /* creates a mask with `n' 1 bits at position `p' */
183    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}