Skip to main content

hcb2lua_decompiler/
opcode.rs

1pub enum Opcode {
2    Nop = 0,
3    InitStack = 1,
4    Call = 2,
5    Syscall,
6    Ret,
7    RetV,
8    Jmp,
9    Jz,
10    PushNil,
11    PushTrue,
12    PushI32,
13    PushI16,
14    PushI8,
15    PushF32,
16    PushString,
17    PushGlobal,
18    PushStack,
19    PushGlobalTable,
20    PushLocalTable,
21    PushTop,
22    PushReturn,
23    PopGlobal,
24    PopStack,
25    PopGlobalTable,
26    PopLocalTable,
27    Neg,
28    Add,
29    Sub,
30    Mul,
31    Div,
32    Mod,
33    BitTest,
34    And,
35    Or,
36    SetE,
37    SetNE,
38    SetG,
39    SetLE,
40    SetL,
41    SetGE,
42}
43
44impl TryFrom<i32> for Opcode {
45    type Error = ();
46
47    fn try_from(v: i32) -> core::result::Result<Self, Self::Error> {
48        match v {
49            x if x == Opcode::Nop as i32 => Ok(Opcode::Nop),
50            x if x == Opcode::InitStack as i32 => Ok(Opcode::InitStack),
51            x if x == Opcode::Call as i32 => Ok(Opcode::Call),
52            x if x == Opcode::Syscall as i32 => Ok(Opcode::Syscall),
53            x if x == Opcode::Ret as i32 => Ok(Opcode::Ret),
54            x if x == Opcode::RetV as i32 => Ok(Opcode::RetV),
55            x if x == Opcode::Jmp as i32 => Ok(Opcode::Jmp),
56            x if x == Opcode::Jz as i32 => Ok(Opcode::Jz),
57            x if x == Opcode::PushNil as i32 => Ok(Opcode::PushNil),
58            x if x == Opcode::PushTrue as i32 => Ok(Opcode::PushTrue),
59            x if x == Opcode::PushI32 as i32 => Ok(Opcode::PushI32),
60            x if x == Opcode::PushI16 as i32 => Ok(Opcode::PushI16),
61            x if x == Opcode::PushI8 as i32 => Ok(Opcode::PushI8),
62            x if x == Opcode::PushF32 as i32 => Ok(Opcode::PushF32),
63            x if x == Opcode::PushString as i32 => Ok(Opcode::PushString),
64            x if x == Opcode::PushGlobal as i32 => Ok(Opcode::PushGlobal),
65            x if x == Opcode::PushStack as i32 => Ok(Opcode::PushStack),
66            x if x == Opcode::PushGlobalTable as i32 => Ok(Opcode::PushGlobalTable),
67            x if x == Opcode::PushLocalTable as i32 => Ok(Opcode::PushLocalTable),
68            x if x == Opcode::PushTop as i32 => Ok(Opcode::PushTop),
69            x if x == Opcode::PushReturn as i32 => Ok(Opcode::PushReturn),
70            x if x == Opcode::PopGlobal as i32 => Ok(Opcode::PopGlobal),
71            x if x == Opcode::PopStack as i32 => Ok(Opcode::PopStack),
72            x if x == Opcode::PopGlobalTable as i32 => Ok(Opcode::PopGlobalTable),
73            x if x == Opcode::PopLocalTable as i32 => Ok(Opcode::PopLocalTable),
74            x if x == Opcode::Neg as i32 => Ok(Opcode::Neg),
75            x if x == Opcode::Add as i32 => Ok(Opcode::Add),
76            x if x == Opcode::Sub as i32 => Ok(Opcode::Sub),
77            x if x == Opcode::Mul as i32 => Ok(Opcode::Mul),
78            x if x == Opcode::Div as i32 => Ok(Opcode::Div),
79            x if x == Opcode::Mod as i32 => Ok(Opcode::Mod),
80            x if x == Opcode::BitTest as i32 => Ok(Opcode::BitTest),
81            x if x == Opcode::And as i32 => Ok(Opcode::And),
82            x if x == Opcode::Or as i32 => Ok(Opcode::Or),
83            x if x == Opcode::SetE as i32 => Ok(Opcode::SetE),
84            x if x == Opcode::SetNE as i32 => Ok(Opcode::SetNE),
85            x if x == Opcode::SetG as i32 => Ok(Opcode::SetG),
86            x if x == Opcode::SetLE as i32 => Ok(Opcode::SetLE),
87            x if x == Opcode::SetL as i32 => Ok(Opcode::SetL),
88            x if x == Opcode::SetGE as i32 => Ok(Opcode::SetGE),
89            _ => Err(()),
90        }
91    }
92}
93
94impl TryFrom<u8> for Opcode {
95    type Error = ();
96
97    fn try_from(v: u8) -> core::result::Result<Self, Self::Error> {
98        match v {
99            x if x == Opcode::Nop as u8 => Ok(Opcode::Nop),
100            x if x == Opcode::InitStack as u8 => Ok(Opcode::InitStack),
101            x if x == Opcode::Call as u8 => Ok(Opcode::Call),
102            x if x == Opcode::Syscall as u8 => Ok(Opcode::Syscall),
103            x if x == Opcode::Ret as u8 => Ok(Opcode::Ret),
104            x if x == Opcode::RetV as u8 => Ok(Opcode::RetV),
105            x if x == Opcode::Jmp as u8 => Ok(Opcode::Jmp),
106            x if x == Opcode::Jz as u8 => Ok(Opcode::Jz),
107            x if x == Opcode::PushNil as u8 => Ok(Opcode::PushNil),
108            x if x == Opcode::PushTrue as u8 => Ok(Opcode::PushTrue),
109            x if x == Opcode::PushI32 as u8 => Ok(Opcode::PushI32),
110            x if x == Opcode::PushI16 as u8 => Ok(Opcode::PushI16),
111            x if x == Opcode::PushI8 as u8 => Ok(Opcode::PushI8),
112            x if x == Opcode::PushF32 as u8 => Ok(Opcode::PushF32),
113            x if x == Opcode::PushString as u8 => Ok(Opcode::PushString),
114            x if x == Opcode::PushGlobal as u8 => Ok(Opcode::PushGlobal),
115            x if x == Opcode::PushStack as u8 => Ok(Opcode::PushStack),
116            x if x == Opcode::PushGlobalTable as u8 => Ok(Opcode::PushGlobalTable),
117            x if x == Opcode::PushLocalTable as u8 => Ok(Opcode::PushLocalTable),
118            x if x == Opcode::PushTop as u8 => Ok(Opcode::PushTop),
119            x if x == Opcode::PushReturn as u8 => Ok(Opcode::PushReturn),
120            x if x == Opcode::PopGlobal as u8 => Ok(Opcode::PopGlobal),
121            x if x == Opcode::PopStack as u8 => Ok(Opcode::PopStack),
122            x if x == Opcode::PopGlobalTable as u8 => Ok(Opcode::PopGlobalTable),
123            x if x == Opcode::PopLocalTable as u8 => Ok(Opcode::PopLocalTable),
124            x if x == Opcode::Neg as u8 => Ok(Opcode::Neg),
125            x if x == Opcode::Add as u8 => Ok(Opcode::Add),
126            x if x == Opcode::Sub as u8 => Ok(Opcode::Sub),
127            x if x == Opcode::Mul as u8 => Ok(Opcode::Mul),
128            x if x == Opcode::Div as u8 => Ok(Opcode::Div),
129            x if x == Opcode::Mod as u8 => Ok(Opcode::Mod),
130            x if x == Opcode::BitTest as u8 => Ok(Opcode::BitTest),
131            x if x == Opcode::And as u8 => Ok(Opcode::And),
132            x if x == Opcode::Or as u8 => Ok(Opcode::Or),
133            x if x == Opcode::SetE as u8 => Ok(Opcode::SetE),
134            x if x == Opcode::SetNE as u8 => Ok(Opcode::SetNE),
135            x if x == Opcode::SetG as u8 => Ok(Opcode::SetG),
136            x if x == Opcode::SetLE as u8 => Ok(Opcode::SetLE),
137            x if x == Opcode::SetL as u8 => Ok(Opcode::SetL),
138            x if x == Opcode::SetGE as u8 => Ok(Opcode::SetGE),
139            _ => Err(()),
140        }
141    }
142}
143
144impl TryFrom<&str> for Opcode {
145    type Error = ();
146
147    fn try_from(v: &str) -> core::result::Result<Self, Self::Error> {
148        match v {
149            x if x == "nop" => Ok(Opcode::Nop),
150            x if x == "init_stack" => Ok(Opcode::InitStack),
151            x if x == "call" => Ok(Opcode::Call),
152            x if x == "syscall" => Ok(Opcode::Syscall),
153            x if x == "ret" => Ok(Opcode::Ret),
154            x if x == "retv" => Ok(Opcode::RetV),
155            x if x == "jmp" => Ok(Opcode::Jmp),
156            x if x == "jz" => Ok(Opcode::Jz),
157            x if x == "push_nil" => Ok(Opcode::PushNil),
158            x if x == "push_true" => Ok(Opcode::PushTrue),
159            x if x == "push_i32" => Ok(Opcode::PushI32),
160            x if x == "push_i16" => Ok(Opcode::PushI16),
161            x if x == "push_i8" => Ok(Opcode::PushI8),
162            x if x == "push_f32" => Ok(Opcode::PushF32),
163            x if x == "push_string" => Ok(Opcode::PushString),
164            x if x == "push_global" => Ok(Opcode::PushGlobal),
165            x if x == "push_stack" => Ok(Opcode::PushStack),
166            x if x == "push_global_table" => Ok(Opcode::PushGlobalTable),
167            x if x == "push_local_table" => Ok(Opcode::PushLocalTable),
168            x if x == "push_top" => Ok(Opcode::PushTop),
169            x if x == "push_return" => Ok(Opcode::PushReturn),
170            x if x == "pop_global" => Ok(Opcode::PopGlobal),
171            x if x == "pop_stack" => Ok(Opcode::PopStack),
172            x if x == "pop_global_table" => Ok(Opcode::PopGlobalTable),
173            x if x == "pop_local_table" => Ok(Opcode::PopLocalTable),
174            x if x == "neg" => Ok(Opcode::Neg),
175            x if x == "add" => Ok(Opcode::Add),
176            x if x == "sub" => Ok(Opcode::Sub),
177            x if x == "mul" => Ok(Opcode::Mul),
178            x if x == "div" => Ok(Opcode::Div),
179            x if x == "mod" => Ok(Opcode::Mod),
180            x if x == "bit_test" => Ok(Opcode::BitTest),
181            x if x == "and" => Ok(Opcode::And),
182            x if x == "or" => Ok(Opcode::Or),
183            x if x == "set_e" => Ok(Opcode::SetE),
184            x if x == "set_ne" => Ok(Opcode::SetNE),
185            x if x == "set_g" => Ok(Opcode::SetG),
186            x if x == "set_le" => Ok(Opcode::SetLE),
187            x if x == "set_l" => Ok(Opcode::SetL),
188            x if x == "set_ge" => Ok(Opcode::SetGE),
189            _ => Err(()),
190        }
191    }
192}
193
194impl ToString for Opcode {
195    fn to_string(&self) -> String {
196        match self {
197            Opcode::Nop => "nop",
198            Opcode::InitStack => "init_stack",
199            Opcode::Call => "call",
200            Opcode::Syscall => "syscall",
201            Opcode::Ret => "ret",
202            Opcode::RetV => "retv",
203            Opcode::Jmp => "jmp",
204            Opcode::Jz => "jz",
205            Opcode::PushNil => "push_nil",
206            Opcode::PushTrue => "push_true",
207            Opcode::PushI32 => "push_i32",
208            Opcode::PushI16 => "push_i16",
209            Opcode::PushI8 => "push_i8",
210            Opcode::PushF32 => "push_f32",
211            Opcode::PushString => "push_string",
212            Opcode::PushGlobal => "push_global",
213            Opcode::PushStack => "push_stack",
214            Opcode::PushGlobalTable => "push_global_table",
215            Opcode::PushLocalTable => "push_local_table",
216            Opcode::PushTop => "push_top",
217            Opcode::PushReturn => "push_return",
218            Opcode::PopGlobal => "pop_global",
219            Opcode::PopStack => "pop_stack",
220            Opcode::PopGlobalTable => "pop_global_table",
221            Opcode::PopLocalTable => "pop_local_table",
222            Opcode::Neg => "neg",
223            Opcode::Add => "add",
224            Opcode::Sub => "sub",
225            Opcode::Mul => "mul",
226            Opcode::Div => "div",
227            Opcode::Mod => "mod",
228            Opcode::BitTest => "bit_test",
229            Opcode::And => "and",
230            Opcode::Or => "or",
231            Opcode::SetE => "set_e",
232            Opcode::SetNE => "set_ne",
233            Opcode::SetG => "set_g",
234            Opcode::SetLE => "set_le",
235            Opcode::SetL => "set_l",
236            Opcode::SetGE => "set_ge",
237        }
238        .to_string()
239    }
240}
241
242pub trait OpcodeBase {
243    fn opcode(&self) -> Opcode;
244    fn address(&self) -> u32;
245    fn mnemonic(&self) -> &'static str;
246    fn disassemble(&self) -> String;
247}