luaur_code_gen/methods/
ir_builder_rebuild_bytecode_basic_blocks.rs1use crate::enums::ir_block_kind::IrBlockKind;
2use crate::functions::build_bytecode_blocks::build_bytecode_blocks;
3use crate::functions::get_jump_target::get_jump_target;
4use crate::functions::get_op_length::get_op_length;
5use crate::functions::is_fast_call::is_fast_call;
6use crate::records::ir_builder::IrBuilder;
7use crate::type_aliases::instruction_ir_builder::Instruction;
8use alloc::vec::Vec;
9use luaur_common::enums::luau_opcode::LuauOpcode;
10use luaur_common::macros::luau_insn_op::LUAU_INSN_OP;
11
12impl IrBuilder {
13 pub fn rebuild_bytecode_basic_blocks(&mut self, proto: *mut luaur_vm::records::proto::Proto) {
14 unsafe {
15 let sizecode = (*proto).sizecode as usize;
16 let code = (*proto).code;
17
18 self.inst_index_to_block.resize(sizecode, u32::MAX);
19
20 let mut jump_targets = Vec::with_capacity(sizecode);
21 jump_targets.resize(sizecode, 0u8);
22
23 let mut i: usize = 0;
24 while i < sizecode {
25 let pc: *const Instruction = code.add(i);
26 let op = LuauOpcode::from(LUAU_INSN_OP(*pc) as u8);
27
28 let target = get_jump_target(*pc, i as u32);
29
30 if target >= 0 && !is_fast_call(op) {
31 jump_targets[target as usize] = 1;
32 }
33
34 i += get_op_length(op) as usize;
35 debug_assert!(i <= sizecode);
36 }
37
38 jump_targets[0] = 1;
39
40 for j in 0..sizecode {
41 if jump_targets[j] != 0 {
42 let b = self.block(IrBlockKind::Bytecode);
43 self.inst_index_to_block[j] = b.index();
44 }
45 }
46
47 build_bytecode_blocks(&mut self.function, &jump_targets);
48 }
49 }
50}