hcb2lua_decompiler/
opcode.rs

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