gbf_core/decompiler/handlers/
variable_operand.rs

1#![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
18/// Handles other instructions.
19pub 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                // Now build the function call node.
32                let function_call_node = new_fn_call(arr);
33
34                // Create a new SSA id for this function call.
35                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}