gbf_core/decompiler/handlers/
mod.rs1#![deny(missing_docs)]
2
3use std::{collections::HashMap, sync::OnceLock};
4
5use bin_op::BinaryOperationHandler;
6use identifier::IdentifierHandler;
7use literal::LiteralHandler;
8use nop::NopHandler;
9use variable_operand::VariableOperandHandler;
10
11use crate::{instruction::Instruction, opcode::Opcode};
12
13use super::{
14 ProcessedInstruction, function_decompiler::FunctionDecompilerError,
15 function_decompiler_context::FunctionDecompilerContext,
16};
17
18pub mod bin_op;
20pub mod builtins;
22pub mod general;
24pub mod identifier;
26pub mod jump;
28pub mod literal;
30pub mod nop;
32pub mod short_circuit;
34pub mod special_one_operand;
36pub mod special_three_operand;
38pub mod special_two_operand;
40pub mod un_op;
42pub mod variable_operand;
44
45pub trait OpcodeHandler: Send + Sync {
47 fn handle_instruction(
56 &self,
57 context: &mut FunctionDecompilerContext,
58 instruction: &Instruction,
59 ) -> Result<ProcessedInstruction, FunctionDecompilerError>;
60}
61
62static GLOBAL_OPCODE_HANDLERS: OnceLock<HashMap<Opcode, Box<dyn OpcodeHandler>>> = OnceLock::new();
63
64pub fn global_opcode_handlers() -> &'static HashMap<Opcode, Box<dyn OpcodeHandler>> {
66 GLOBAL_OPCODE_HANDLERS.get_or_init(|| {
67 let mut handlers: HashMap<Opcode, Box<dyn OpcodeHandler>> = HashMap::new();
68
69 handlers.insert(Opcode::Pop, Box::new(general::GeneralHandler));
71
72 handlers.insert(Opcode::Player, Box::new(IdentifierHandler));
76 handlers.insert(Opcode::PlayerO, Box::new(IdentifierHandler));
77 handlers.insert(Opcode::Temp, Box::new(IdentifierHandler));
78 handlers.insert(Opcode::Level, Box::new(IdentifierHandler));
79 handlers.insert(Opcode::This, Box::new(IdentifierHandler));
80 handlers.insert(Opcode::ThisO, Box::new(IdentifierHandler));
81 handlers.insert(Opcode::Params, Box::new(IdentifierHandler));
82 handlers.insert(Opcode::PushVariable, Box::new(IdentifierHandler));
83 handlers.insert(Opcode::Pi, Box::new(IdentifierHandler));
84
85 handlers.insert(Opcode::PushString, Box::new(LiteralHandler));
87 handlers.insert(Opcode::PushNumber, Box::new(LiteralHandler));
88 handlers.insert(Opcode::PushTrue, Box::new(LiteralHandler));
89 handlers.insert(Opcode::PushFalse, Box::new(LiteralHandler));
90 handlers.insert(Opcode::PushNull, Box::new(LiteralHandler));
91
92 handlers.insert(Opcode::LogicalNot, Box::new(un_op::UnaryOperationHandler));
94 handlers.insert(
95 Opcode::BitwiseInvert,
96 Box::new(un_op::UnaryOperationHandler),
97 );
98 handlers.insert(
99 Opcode::UnarySubtract,
100 Box::new(un_op::UnaryOperationHandler),
101 );
102
103 handlers.insert(Opcode::Add, Box::new(BinaryOperationHandler));
105 handlers.insert(Opcode::Subtract, Box::new(BinaryOperationHandler));
106 handlers.insert(Opcode::Multiply, Box::new(BinaryOperationHandler));
107 handlers.insert(Opcode::Divide, Box::new(BinaryOperationHandler));
108 handlers.insert(Opcode::Modulo, Box::new(BinaryOperationHandler));
109 handlers.insert(Opcode::BitwiseAnd, Box::new(BinaryOperationHandler));
110 handlers.insert(Opcode::BitwiseOr, Box::new(BinaryOperationHandler));
111 handlers.insert(Opcode::BitwiseXor, Box::new(BinaryOperationHandler));
112 handlers.insert(Opcode::ShiftLeft, Box::new(BinaryOperationHandler));
113 handlers.insert(Opcode::ShiftRight, Box::new(BinaryOperationHandler));
114 handlers.insert(Opcode::Equal, Box::new(BinaryOperationHandler));
115 handlers.insert(Opcode::NotEqual, Box::new(BinaryOperationHandler));
116 handlers.insert(Opcode::LessThan, Box::new(BinaryOperationHandler));
117 handlers.insert(Opcode::LessThanOrEqual, Box::new(BinaryOperationHandler));
118 handlers.insert(Opcode::GreaterThan, Box::new(BinaryOperationHandler));
119 handlers.insert(Opcode::GreaterThanOrEqual, Box::new(BinaryOperationHandler));
120 handlers.insert(Opcode::In, Box::new(BinaryOperationHandler));
121 handlers.insert(Opcode::Join, Box::new(BinaryOperationHandler));
122 handlers.insert(Opcode::Power, Box::new(BinaryOperationHandler));
123
124 handlers.insert(Opcode::ConvertToFloat, Box::new(NopHandler));
126 handlers.insert(Opcode::ConvertToObject, Box::new(NopHandler));
127 handlers.insert(Opcode::ConvertToString, Box::new(NopHandler));
128 handlers.insert(Opcode::ConvertToVariable, Box::new(NopHandler));
129 handlers.insert(Opcode::FunctionStart, Box::new(NopHandler));
130 handlers.insert(Opcode::IncreaseLoopCounter, Box::new(NopHandler));
131 handlers.insert(Opcode::Jmp, Box::new(NopHandler));
132 handlers.insert(Opcode::MarkRegisterVariable, Box::new(NopHandler));
133 handlers.insert(Opcode::WithEnd, Box::new(NopHandler));
134 handlers.insert(Opcode::ShortCircuitEnd, Box::new(NopHandler));
135
136 handlers.insert(
138 Opcode::AssignArray,
139 Box::new(special_three_operand::SpecialThreeOperandHandler),
140 );
141 handlers.insert(
142 Opcode::InRange,
143 Box::new(special_three_operand::SpecialThreeOperandHandler),
144 );
145 handlers.insert(
146 Opcode::AssignMultiDimensionalArrayIndex,
147 Box::new(special_three_operand::SpecialThreeOperandHandler),
148 );
149 handlers.insert(
150 Opcode::AssignMultiDimensionalArray,
151 Box::new(special_three_operand::SpecialThreeOperandHandler),
152 );
153
154 handlers.insert(
156 Opcode::AccessMember,
157 Box::new(special_two_operand::SpecialTwoOperandHandler),
158 );
159 handlers.insert(
160 Opcode::Assign,
161 Box::new(special_two_operand::SpecialTwoOperandHandler),
162 );
163 handlers.insert(
164 Opcode::ArrayAccess,
165 Box::new(special_two_operand::SpecialTwoOperandHandler),
166 );
167 handlers.insert(
168 Opcode::NewObject,
169 Box::new(special_two_operand::SpecialTwoOperandHandler),
170 );
171
172 handlers.insert(
174 Opcode::Ret,
175 Box::new(special_one_operand::SpecialOneOperandHandler),
176 );
177 handlers.insert(
178 Opcode::Copy,
179 Box::new(special_one_operand::SpecialOneOperandHandler),
180 );
181 handlers.insert(
182 Opcode::SetRegister,
183 Box::new(special_one_operand::SpecialOneOperandHandler),
184 );
185 handlers.insert(
186 Opcode::GetRegister,
187 Box::new(special_one_operand::SpecialOneOperandHandler),
188 );
189 handlers.insert(
190 Opcode::Inc,
191 Box::new(special_one_operand::SpecialOneOperandHandler),
192 );
193 handlers.insert(
194 Opcode::Dec,
195 Box::new(special_one_operand::SpecialOneOperandHandler),
196 );
197 handlers.insert(
198 Opcode::New,
199 Box::new(special_one_operand::SpecialOneOperandHandler),
200 );
201 handlers.insert(
202 Opcode::NewUninitializedArray,
203 Box::new(special_one_operand::SpecialOneOperandHandler),
204 );
205
206 handlers.insert(Opcode::Call, Box::new(VariableOperandHandler));
208 handlers.insert(Opcode::EndParams, Box::new(VariableOperandHandler));
209 handlers.insert(Opcode::EndArray, Box::new(VariableOperandHandler));
210
211 handlers.insert(Opcode::Char, Box::new(builtins::BuiltinsHandler));
213 handlers.insert(Opcode::Int, Box::new(builtins::BuiltinsHandler));
214 handlers.insert(Opcode::Random, Box::new(builtins::BuiltinsHandler));
215 handlers.insert(Opcode::Abs, Box::new(builtins::BuiltinsHandler));
216 handlers.insert(Opcode::Sin, Box::new(builtins::BuiltinsHandler));
217 handlers.insert(Opcode::Cos, Box::new(builtins::BuiltinsHandler));
218 handlers.insert(Opcode::VecX, Box::new(builtins::BuiltinsHandler));
219 handlers.insert(Opcode::VecY, Box::new(builtins::BuiltinsHandler));
220 handlers.insert(Opcode::Sleep, Box::new(builtins::BuiltinsHandler));
221 handlers.insert(Opcode::ArcTan, Box::new(builtins::BuiltinsHandler));
222 handlers.insert(Opcode::MakeVar, Box::new(builtins::BuiltinsHandler));
223 handlers.insert(Opcode::GetTranslation, Box::new(builtins::BuiltinsHandler));
224 handlers.insert(Opcode::Min, Box::new(builtins::BuiltinsHandler));
225 handlers.insert(Opcode::Max, Box::new(builtins::BuiltinsHandler));
226 handlers.insert(Opcode::WaitFor, Box::new(builtins::BuiltinsHandler));
227 handlers.insert(Opcode::GetAngle, Box::new(builtins::BuiltinsHandler));
228 handlers.insert(Opcode::GetDir, Box::new(builtins::BuiltinsHandler));
229 handlers.insert(Opcode::Format, Box::new(builtins::BuiltinsHandler));
230
231 handlers.insert(Opcode::ObjSubstring, Box::new(builtins::BuiltinsHandler));
232 handlers.insert(Opcode::ObjTokenize, Box::new(builtins::BuiltinsHandler));
233 handlers.insert(Opcode::ObjStarts, Box::new(builtins::BuiltinsHandler));
234 handlers.insert(Opcode::ObjEnds, Box::new(builtins::BuiltinsHandler));
235 handlers.insert(Opcode::ObjPos, Box::new(builtins::BuiltinsHandler));
236 handlers.insert(Opcode::ObjCharAt, Box::new(builtins::BuiltinsHandler));
237 handlers.insert(Opcode::ObjLength, Box::new(builtins::BuiltinsHandler));
238 handlers.insert(Opcode::ObjLink, Box::new(builtins::BuiltinsHandler));
239 handlers.insert(Opcode::ObjTrim, Box::new(builtins::BuiltinsHandler));
240 handlers.insert(Opcode::ObjSize, Box::new(builtins::BuiltinsHandler));
241 handlers.insert(Opcode::ObjIndex, Box::new(builtins::BuiltinsHandler));
242 handlers.insert(Opcode::ObjPositions, Box::new(builtins::BuiltinsHandler));
243 handlers.insert(Opcode::ObjAddString, Box::new(builtins::BuiltinsHandler));
244 handlers.insert(Opcode::ObjRemoveString, Box::new(builtins::BuiltinsHandler));
245 handlers.insert(Opcode::ObjDeleteString, Box::new(builtins::BuiltinsHandler));
246 handlers.insert(Opcode::ObjInsertString, Box::new(builtins::BuiltinsHandler));
247 handlers.insert(
248 Opcode::ObjReplaceString,
249 Box::new(builtins::BuiltinsHandler),
250 );
251 handlers.insert(Opcode::ObjSubArray, Box::new(builtins::BuiltinsHandler));
252 handlers.insert(Opcode::ObjType, Box::new(builtins::BuiltinsHandler));
253 handlers.insert(Opcode::ObjClear, Box::new(builtins::BuiltinsHandler));
254
255 handlers.insert(Opcode::Jne, Box::new(jump::JumpHandler));
257 handlers.insert(Opcode::Jeq, Box::new(jump::JumpHandler));
258 handlers.insert(Opcode::With, Box::new(jump::JumpHandler));
259 handlers.insert(Opcode::ForEach, Box::new(jump::JumpHandler));
260
261 handlers.insert(
263 Opcode::ShortCircuitAnd,
264 Box::new(short_circuit::ShortCircuitHandler),
265 );
266 handlers.insert(
267 Opcode::ShortCircuitOr,
268 Box::new(short_circuit::ShortCircuitHandler),
269 );
270
271 handlers
272 })
273}