luaur_bytecode/methods/
call_inliner_map_to_caller_op.rs1use crate::enums::bc_op_kind::BcOpKind;
2use crate::records::bc_function::BcFunction;
3use crate::records::bc_inst::BcInst;
4use crate::records::bc_op::BcOp;
5use crate::records::bc_phi::BcPhi;
6use crate::records::bc_proj::BcProj;
7use crate::records::bc_vm_const::BcVmConst;
8use crate::records::call_inliner::CallInliner;
9use crate::type_aliases::reg::Reg;
10
11use luaur_common::enums::luau_opcode::LuauOpcode;
12use luaur_common::macros::luau_assert::LUAU_ASSERT;
13
14impl<'a> CallInliner<'a> {
15 pub fn map_to_caller_op(&mut self, target_op: BcOp) -> BcOp {
16 match target_op.kind {
17 BcOpKind::Inst => self.map_inst_op(target_op),
18 BcOpKind::Block => self.map_block_op(target_op),
19 BcOpKind::Imm => {
20 let imm = self.target.imm_op(target_op).clone();
21 self.caller.immediates.push(imm);
22 BcOp::bc_op_bc_op_kind_u32(
23 BcOpKind::Imm,
24 (self.caller.immediates.len() as u32).wrapping_sub(1),
25 )
26 }
27 BcOpKind::Phi => {
28 let phi_op = self.caller.add_phi();
29 let target_phi_ref = self.target.phi(target_op);
30 let ops_len = target_phi_ref.operator_deref().ops.len();
31
32 for i in 0..ops_len {
33 let target_phi_op = {
34 let target_phi = self.target.phi(target_op);
35 target_phi.operator_deref().ops[i]
36 };
37 let mapped = self.map_to_caller_op(target_phi_op);
38 let mut phi = self.caller.phi(phi_op);
39 phi.operator_deref_mut().ops.push_back(mapped);
40 }
41 phi_op
42 }
43 BcOpKind::Proj => {
44 let proj_ref = self.target.proj(target_op);
45 let proj = *proj_ref.operator_deref();
46 if self.target.is_vararg {
47 let inst_ref = self.target.inst(proj.op);
48 let inst = inst_ref.operator_deref();
49 if inst.op == LuauOpcode::LOP_GETVARARGS {
50 LUAU_ASSERT!(inst.ops.len() > 1);
54 return self.get_var_arg_param(proj.op, proj.index);
55 }
56 }
57 let mapped_op = self.map_to_caller_op(proj.op);
58 self.caller.add_proj(mapped_op, proj.index)
59 }
60 BcOpKind::VmReg => {
61 if target_op.index < self.target.numparams as u32 {
62 LUAU_ASSERT!(target_op.index < self.call_params.len() as u32);
63 self.call_params[target_op.index as usize]
64 } else {
65 BcOp::bc_op_bc_op_kind_u32(
66 BcOpKind::VmReg,
67 self.map_to_caller_reg(target_op.index as Reg) as u32,
68 )
69 }
70 }
71 BcOpKind::VmConst => {
72 crate::methods::call_inliner_map_vm_const_op::call_inliner_map_vm_const_op(
73 self.caller_vm_const_size_before_inline,
74 target_op,
75 )
76 }
77 BcOpKind::VmProto => self.map_proto_op(target_op),
78 BcOpKind::VmUpvalue => self.map_up_value_op(target_op),
79 _ => target_op,
80 }
81 }
82}