luaur_code_gen/methods/
ir_builder_clone.rs1use crate::enums::ir_cmd::IrCmd;
2use crate::enums::ir_op_kind::IrOpKind;
3use crate::functions::add_use::add_use;
4use crate::functions::is_pseudo::is_pseudo;
5use crate::functions::kill_ir_utils::kill_ir_function_ir_inst;
6use crate::macros::codegen_assert::CODEGEN_ASSERT;
7use crate::records::ir_builder::IrBuilder;
8use luaur_common::records::dense_hash_map::DenseHashMap;
9
10impl IrBuilder {
11 pub fn clone(&mut self, source_idxs: Vec<u32>, remove_current_terminator: bool) {
12 let mut inst_redir: DenseHashMap<u32, u32> = DenseHashMap::new(!0u32);
13
14 for source_idx in source_idxs {
15 let source = self.function.blocks[source_idx as usize];
16
17 if remove_current_terminator && self.in_terminated_block {
18 let finish = self.function.blocks[self.active_block_idx as usize].finish;
19 let term = &mut self.function.instructions[finish as usize] as *mut _;
20 unsafe {
21 kill_ir_function_ir_inst(&mut self.function, &mut *term);
22 }
23 self.in_terminated_block = false;
24 }
25
26 const K_BLOCK_FLAG_SAFE_ENV_CHECK: u8 = 1 << 0;
27 if (source.flags & K_BLOCK_FLAG_SAFE_ENV_CHECK) != 0 {
28 CODEGEN_ASSERT!(source.startpc != crate::records::ir_block::kBlockNoStartPc);
29 let exit = self.vm_exit(source.startpc);
30 self.inst_ir_cmd_ir_op(IrCmd::CHECK_SAFE_ENV, exit);
31 }
32
33 for index in source.start..=source.finish {
34 CODEGEN_ASSERT!((index as usize) < self.function.instructions.len());
35 let mut clone = self.function.instructions[index as usize].clone();
36
37 if is_pseudo(clone.cmd) {
38 CODEGEN_ASSERT!(clone.use_count == 0);
39 continue;
40 }
41
42 for op in clone.ops.as_mut_slice() {
43 if op.kind() == IrOpKind::Inst {
44 if let Some(&new_index) = inst_redir.find(&op.index()) {
45 *op = crate::records::ir_op::IrOp::ir_op_ir_op_kind_u32(
46 IrOpKind::Inst,
47 new_index,
48 );
49 } else {
50 CODEGEN_ASSERT!(false);
51 }
52 }
53 }
54
55 for &op in clone.ops.as_slice() {
56 add_use(&mut self.function, op);
57 }
58
59 *inst_redir.get_or_insert(index) = self.function.instructions.len() as u32;
60 self.inst_ir_cmd_ir_ops(clone.cmd, &clone.ops);
61 }
62 }
63 }
64}