luaur_code_gen/functions/
call_barrier_object.rs1use crate::records::assembly_builder_x_64::AssemblyBuilderX64;
2use crate::records::ir_call_wrapper_x_64::IrCallWrapperX64;
3use crate::records::ir_op::IrOp;
4use crate::records::ir_reg_alloc_x_64::IrRegAllocX64;
5use crate::records::label::Label;
6use crate::records::native_context::NativeContext;
7use crate::records::operand_x_64::OperandX64;
8use crate::records::register_x_64::RegisterX64;
9use crate::records::scoped_reg_x_64::ScopedRegX64;
10use crate::records::scoped_spills::ScopedSpills;
11
12use crate::enums::size_x_64::SizeX64;
13
14use crate::functions::check_object_barrier_conditions::check_object_barrier_conditions;
15
16const fn r_state() -> RegisterX64 {
17 RegisterX64 {
18 bits: (15u8 << RegisterX64::INDEX_SHIFT) | SizeX64::qword as u8,
19 }
20}
21
22const fn r_native_context() -> RegisterX64 {
23 RegisterX64 {
24 bits: (13u8 << RegisterX64::INDEX_SHIFT) | SizeX64::qword as u8,
25 }
26}
27
28pub fn call_barrier_object(
29 regs: &mut IrRegAllocX64,
30 build: &mut AssemblyBuilderX64,
31 object: RegisterX64,
32 object_op: IrOp,
33 ra: RegisterX64,
34 ra_op: IrOp,
35 ratag: i32,
36) {
37 let mut skip = Label { id: 0, location: 0 };
38
39 let mut tmp = ScopedRegX64 {
40 owner: regs as *mut _,
41 reg: RegisterX64::noreg,
42 };
43 tmp.scoped_reg_x_64_ir_reg_alloc_x_64_size_x_64(regs, SizeX64::qword);
44
45 check_object_barrier_conditions(build, tmp.reg, object, ra, ra_op, ratag, &mut skip);
46
47 {
48 let _spill_guard = {
49 let mut guard = ScopedSpills {
50 owner: regs as *mut _,
51 start_spill_id: 0,
52 };
53 guard.scoped_spills_scoped_spills_ir_reg_alloc_x_64(regs);
54 guard
55 };
56
57 let mut call_wrap = IrCallWrapperX64::ir_call_wrapper_x_64_ir_call_wrapper_x_64(
58 regs,
59 build,
60 regs.curr_inst_idx,
61 );
62
63 call_wrap.add_argument_size_x_64_operand_x_64_ir_op(
64 SizeX64::qword,
65 OperandX64::reg(r_state()),
66 IrOp::ir_op(),
67 );
68
69 call_wrap.add_argument_size_x_64_operand_x_64_ir_op(
70 SizeX64::qword,
71 OperandX64::reg(object),
72 object_op,
73 );
74
75 call_wrap.add_argument_size_x_64_scoped_reg_x_64(SizeX64::qword, &mut tmp);
76
77 let barrierf_offset = core::mem::offset_of!(NativeContext, luaC_barrierf) as i32;
78 let target = OperandX64::mem(
79 SizeX64::qword,
80 RegisterX64::noreg,
81 1,
82 r_native_context(),
83 barrierf_offset,
84 );
85
86 call_wrap.call(&target);
87 }
88
89 build.set_label_label(&mut skip);
90}