luaur_bytecode/methods/
call_inliner_replace_get_var_arg.rs1use crate::records::bc_get_var_args::BcGetVarArgs;
2use crate::records::bc_load_nil::BcLoadNil;
3use crate::records::bc_move::BcMove;
4use crate::records::bc_op::BcOp;
5use crate::records::call_inliner::CallInliner;
6use crate::type_aliases::reg::Reg;
7
8impl<'a> CallInliner<'a> {
9 pub fn replace_get_var_arg(&mut self, caller_block_op: BcOp, target_get_var_args_op: BcOp) {
10 let target = self.target as *mut crate::records::bc_function::BcFunction;
11 let target_get_var_args_ref = unsafe { (&*target).inst(target_get_var_args_op) };
12 let mut get_var_args = BcGetVarArgs::<crate::records::bc_function::VmConst>::from(
13 target,
14 target_get_var_args_ref,
15 );
16 let count = get_var_args.values_count();
17 let count = if count < 0 {
18 std::cmp::max(
19 0,
20 self.call_params.len() as i32 - self.target.numparams as i32,
21 ) as usize
22 } else {
23 count as usize
24 };
25
26 let mut moves = Vec::new();
27 for i in 0..count {
28 let target_reg = get_var_args.start_reg() as u32 + i as u32;
29 let caller_reg = self.map_to_caller_reg(target_reg as Reg) as Reg;
30
31 if (self.target.numparams as usize + i) < self.call_params.len() {
32 let mut move_op =
33 BcMove::<crate::records::bc_function::VmConst>::create(self.caller);
34 let src_op = self.call_params[self.target.numparams as usize + i];
35 move_op.set_src(src_op);
36 move_op.set_out_reg(caller_reg);
37 move_op.append_to(caller_block_op);
38 moves.push(move_op.op());
39 } else {
40 let mut load_nil =
41 BcLoadNil::<crate::records::bc_function::VmConst>::create(self.caller);
42 load_nil.set_out_reg(caller_reg);
43 load_nil.append_to(caller_block_op);
44 moves.push(load_nil.op());
45 }
46 }
47
48 self.var_arg_moves.try_insert(target_get_var_args_op, moves);
49 }
50}