luaur-code-gen 0.1.3

Native (A64/X64) code generation for Luau (Rust).
Documentation
use crate::enums::ir_block_kind::IrBlockKind;
use crate::functions::build_bytecode_blocks::build_bytecode_blocks;
use crate::functions::get_jump_target::get_jump_target;
use crate::functions::get_op_length::get_op_length;
use crate::functions::is_fast_call::is_fast_call;
use crate::records::ir_builder::IrBuilder;
use crate::type_aliases::instruction_ir_builder::Instruction;
use alloc::vec::Vec;
use luaur_common::enums::luau_opcode::LuauOpcode;
use luaur_common::macros::luau_insn_op::LUAU_INSN_OP;

impl IrBuilder {
    pub fn rebuild_bytecode_basic_blocks(&mut self, proto: *mut luaur_vm::records::proto::Proto) {
        unsafe {
            let sizecode = (*proto).sizecode as usize;
            let code = (*proto).code;

            self.inst_index_to_block.resize(sizecode, u32::MAX);

            let mut jump_targets = Vec::with_capacity(sizecode);
            jump_targets.resize(sizecode, 0u8);

            let mut i: usize = 0;
            while i < sizecode {
                let pc: *const Instruction = code.add(i);
                let op = LuauOpcode::from(LUAU_INSN_OP(*pc) as u8);

                let target = get_jump_target(*pc, i as u32);

                if target >= 0 && !is_fast_call(op) {
                    jump_targets[target as usize] = 1;
                }

                i += get_op_length(op) as usize;
                debug_assert!(i <= sizecode);
            }

            jump_targets[0] = 1;

            for j in 0..sizecode {
                if jump_targets[j] != 0 {
                    let b = self.block(IrBlockKind::Bytecode);
                    self.inst_index_to_block[j] = b.index();
                }
            }

            build_bytecode_blocks(&mut self.function, &jump_targets);
        }
    }
}