gbf_core/decompiler/handlers/
variable_operand.rs1#![deny(missing_docs)]
2
3use std::backtrace::Backtrace;
4
5use crate::{
6 decompiler::{
7 ProcessedInstruction, ProcessedInstructionBuilder,
8 ast::{new_assignment, new_fn_call, new_id_with_version},
9 function_decompiler::FunctionDecompilerError,
10 function_decompiler_context::FunctionDecompilerContext,
11 },
12 instruction::Instruction,
13 opcode::Opcode,
14};
15
16use super::OpcodeHandler;
17
18pub struct VariableOperandHandler;
20
21impl OpcodeHandler for VariableOperandHandler {
22 fn handle_instruction(
23 &self,
24 context: &mut FunctionDecompilerContext,
25 instruction: &Instruction,
26 ) -> Result<ProcessedInstruction, FunctionDecompilerError> {
27 let arr = context.pop_building_array()?;
28
29 match instruction.opcode {
30 Opcode::Call => {
31 let function_call_node = new_fn_call(arr);
33
34 let var = context.ssa_context.new_ssa_version_for("fn_call");
36 let ssa_id = new_id_with_version("fn_call", var);
37 let stmt = new_assignment(ssa_id.clone(), function_call_node);
38
39 Ok(ProcessedInstructionBuilder::new()
40 .ssa_id(ssa_id.into())
41 .push_to_region(stmt.into())
42 .build())
43 }
44 Opcode::EndParams => Ok(ProcessedInstructionBuilder::new()
45 .function_parameters(arr)
46 .build()),
47 Opcode::EndArray => {
48 context.push_one_node(arr.into())?;
49
50 Ok(ProcessedInstructionBuilder::new().build())
51 }
52 _ => Err(FunctionDecompilerError::UnimplementedOpcode {
53 opcode: instruction.opcode,
54 context: context.get_error_context(),
55 backtrace: Backtrace::capture(),
56 }),
57 }
58 }
59}