gbf_core/decompiler/handlers/
un_op.rs

1#![deny(missing_docs)]
2
3use std::backtrace::Backtrace;
4
5use crate::{
6    decompiler::{
7        ProcessedInstruction, ProcessedInstructionBuilder,
8        ast::{new_unary_op, unary_op::UnaryOpType},
9        function_decompiler::FunctionDecompilerError,
10        function_decompiler_context::FunctionDecompilerContext,
11    },
12    instruction::Instruction,
13    opcode::Opcode,
14};
15
16use super::OpcodeHandler;
17
18/// Handles unary operations.
19pub struct UnaryOperationHandler;
20
21impl OpcodeHandler for UnaryOperationHandler {
22    fn handle_instruction(
23        &self,
24        context: &mut FunctionDecompilerContext,
25        instruction: &Instruction,
26    ) -> Result<ProcessedInstruction, FunctionDecompilerError> {
27        let expr = context.pop_expression()?;
28
29        let op_type: UnaryOpType = match instruction.opcode {
30            Opcode::LogicalNot => UnaryOpType::LogicalNot,
31            Opcode::BitwiseInvert => UnaryOpType::BitwiseNot,
32            Opcode::UnarySubtract => UnaryOpType::Negate,
33            _ => {
34                return Err(FunctionDecompilerError::UnimplementedOpcode {
35                    opcode: instruction.opcode,
36                    context: context.get_error_context(),
37                    backtrace: Backtrace::capture(),
38                });
39            }
40        };
41
42        let op =
43            new_unary_op(expr, op_type).map_err(|e| FunctionDecompilerError::AstNodeError {
44                source: e,
45                context: context.get_error_context(),
46                backtrace: Backtrace::capture(),
47            })?;
48        // let var = context.ssa_context.new_ssa_version_for("bin_op");
49        // let ssa_id = new_id_with_version("bin_op", var);
50        // let stmt = new_assignment(ssa_id.clone(), op);
51        context.push_one_node(op.into())?;
52
53        Ok(ProcessedInstructionBuilder::new().build())
54    }
55}