luaur-code-gen 0.1.3

Native (A64/X64) code generation for Luau (Rust).
Documentation
use crate::enums::ir_op_kind::IrOpKind;
use crate::enums::ir_value_kind::IrValueKind;
use crate::functions::get_cmd_value_kind::get_cmd_value_kind;
use crate::functions::replace_ir_utils::replace_ir_function_ir_op_ir_op;
use crate::functions::replace_ir_utils_alt_b::replace_ir_function_ir_block_u32_ir_inst;
use crate::macros::op_a::op_a;
use crate::macros::op_b::op_b;
use crate::macros::op_e::op_e;
use crate::records::const_prop_state::ConstPropState;
use crate::records::ir_block::IrBlock;
use crate::records::ir_builder::IrBuilder;
use crate::records::ir_inst::IrInst;

impl ConstPropState {
    pub fn try_merge_buffer_range_check(
        &mut self,
        build: &mut IrBuilder,
        block: &mut IrBlock,
        inst: &mut IrInst,
        prev: &mut IrInst,
    ) -> bool {
        if op_a(inst) != op_a(prev) {
            return false;
        }

        let curr_index_op = op_b(inst.clone());
        let prev_index_op = op_b(prev.clone());
        let curr_index = unsafe { (*self.function).as_inst_op(curr_index_op) };
        let prev_index = unsafe { (*self.function).as_inst_op(prev_index_op) };
        if curr_index.is_null() || prev_index.is_null() {
            return false;
        }

        let curr_index = unsafe { &*curr_index };
        let prev_index = unsafe { &*prev_index };

        if curr_index.cmd == crate::enums::ir_cmd::IrCmd::NUM_TO_INT
            && prev_index.cmd == crate::enums::ir_cmd::IrCmd::NUM_TO_INT
        {
            let curr_index_source = op_a(&mut curr_index.clone());
            let prev_index_source = op_a(&mut prev_index.clone());
            let offset_base_curr = self.get_offset_base(curr_index_source);
            let offset_base_prev = self.get_offset_base(prev_index_source);
            if offset_base_curr.op == offset_base_prev.op
                && offset_base_curr.scale == offset_base_prev.scale
                && offset_base_curr.op.kind() != IrOpKind::Constant
            {
                let extra_offset = offset_base_curr.offset - offset_base_prev.offset;
                if extra_offset != 0 {
                    if prev_index_op.index() >= curr_index_op.index() {
                        return false;
                    }
                    let offset = build.const_int(extra_offset);
                    let mut ops = crate::type_aliases::ir_ops::IrOps::new();
                    ops.push(prev_index_op);
                    ops.push(offset);
                    unsafe {
                        replace_ir_function_ir_block_u32_ir_inst(
                            &mut *self.function,
                            block,
                            curr_index_op.index(),
                            IrInst {
                                cmd: crate::enums::ir_cmd::IrCmd::ADD_INT,
                                ops,
                                ..IrInst::default()
                            },
                        );
                    }
                }

                if op_e(prev.clone()).kind() == IrOpKind::Undef {
                    let replacement = op_a(&mut prev_index.clone());
                    unsafe {
                        replace_ir_function_ir_op_ir_op(
                            &mut *self.function,
                            &mut prev.ops[4],
                            replacement,
                        );
                    }
                }
                return self.try_merge_and_kill_buffer_length_check(
                    build,
                    block,
                    inst,
                    prev,
                    extra_offset,
                );
            }
        } else if get_cmd_value_kind(curr_index.cmd) == IrValueKind::Int
            && get_cmd_value_kind(prev_index.cmd) == IrValueKind::Int
        {
            let offset_base_curr = self.get_offset_base(curr_index_op);
            let offset_base_prev = self.get_offset_base(prev_index_op);
            if offset_base_curr.op == offset_base_prev.op
                && offset_base_curr.scale == offset_base_prev.scale
            {
                let extra_offset = offset_base_curr.offset - offset_base_prev.offset;
                return self.try_merge_and_kill_buffer_length_check(
                    build,
                    block,
                    inst,
                    prev,
                    extra_offset,
                );
            }
        }
        false
    }
}