Skip to main content

luaur_bytecode/methods/
call_inliner_replace_namecall.rs

1use crate::records::bc_block::BcBlock;
2use crate::records::bc_get_table_ks::BcGetTableKS;
3use crate::records::bc_inst_helper::BcInstHelper;
4use crate::records::bc_move::BcMove;
5use crate::records::bc_op::BcOp;
6use crate::records::bc_ref::BcRef;
7use crate::records::call_inliner::CallInliner;
8use crate::type_aliases::reg::Reg;
9use luaur_common::macros::luau_assert::LUAU_ASSERT;
10
11impl<'a> CallInliner<'a> {
12    pub fn replace_namecall(
13        &mut self,
14        namecall: BcOp,
15        prev_block: &mut BcRef<'a, BcBlock>,
16    ) -> BcOp {
17        // move LOP_NAMECALL to call block
18        let caller_ptr: *mut crate::records::bc_function::BcFunction = self.caller;
19        let inst_ref = unsafe { (&*caller_ptr).inst(namecall) };
20        let mut helper = BcInstHelper {
21            graph: unsafe { &mut *caller_ptr },
22            inst: inst_ref,
23        };
24        let table = helper.get_bc_op(0);
25        let hint_op = helper.get_bc_op(1);
26        let hint = unsafe { helper.graph.imm_op(hint_op).value.valueInt as u32 };
27        let key = helper.get_bc_op(2).index;
28        helper.prepend_to(self.call.base.operator_deref().block);
29        prev_block.operator_deref_mut().ops.pop_back();
30        LUAU_ASSERT!(self.target_reg == helper.get_out_reg());
31        let table_reg: Reg = helper.get_out_reg() + 1;
32        drop(helper);
33
34        // and replace it with LOP_MOVE + LOP_GETTABLEKS
35        let mut move_helper = BcMove::<crate::records::bc_function::VmConst>::create(self.caller);
36        move_helper.set_out_reg(table_reg);
37        move_helper.set_src(table);
38        move_helper.append_to(prev_block.op);
39        let move_op = move_helper.op();
40        drop(move_helper);
41
42        let mut get_table_ks_helper =
43            BcGetTableKS::<crate::records::bc_function::VmConst>::create(self.caller);
44        get_table_ks_helper.set_source(move_op);
45        get_table_ks_helper.set_hint(hint);
46        get_table_ks_helper.set_key(key);
47        get_table_ks_helper.set_out_reg(self.target_reg);
48        get_table_ks_helper.append_to(prev_block.op);
49
50        get_table_ks_helper.op()
51    }
52}