Skip to main content

luaur_code_gen/functions/
get_table_node_at_cached_slot.rs

1use crate::enums::size_x_64::SizeX64;
2use crate::functions::byte_reg::byte_reg;
3use crate::functions::dword_reg::dword_reg;
4use crate::macros::codegen_assert::CODEGEN_ASSERT;
5use crate::records::assembly_builder_x_64::AssemblyBuilderX64;
6use crate::records::operand_x_64::OperandX64;
7use crate::records::register_x_64::RegisterX64;
8use luaur_vm::records::lua_table::LuaTable;
9
10const K_STACK_OFFSET_TO_LOCALS: i32 = 16 + 32;
11const SIZEOF_INSTRUCTION: i32 = 4;
12// EmitCommon.h: kOffsetOfInstructionC = 3, kLuaNodeSizeLog2 = 5
13const K_OFFSET_OF_INSTRUCTION_C: i32 = 3;
14const K_LUA_NODE_SIZE_LOG2: i32 = 5;
15
16fn s_code() -> OperandX64 {
17    OperandX64::mem(
18        SizeX64::qword,
19        RegisterX64::noreg,
20        1,
21        RegisterX64::rsp,
22        K_STACK_OFFSET_TO_LOCALS + 8,
23    )
24}
25
26pub fn get_table_node_at_cached_slot(
27    build: &mut AssemblyBuilderX64,
28    tmp: RegisterX64,
29    node: RegisterX64,
30    table: RegisterX64,
31    pcpos: i32,
32) {
33    CODEGEN_ASSERT!(tmp != node);
34    CODEGEN_ASSERT!(table != node);
35
36    build.mov(
37        OperandX64::reg(node),
38        OperandX64::mem(
39            SizeX64::qword,
40            RegisterX64::noreg,
41            1,
42            table,
43            core::mem::offset_of!(LuaTable, node) as i32,
44        ),
45    );
46
47    // compute cached slot
48    build.mov(OperandX64::reg(tmp), s_code());
49    build.movzx(
50        dword_reg(tmp),
51        OperandX64::mem(
52            SizeX64::byte,
53            RegisterX64::noreg,
54            1,
55            tmp,
56            pcpos * SIZEOF_INSTRUCTION + K_OFFSET_OF_INSTRUCTION_C,
57        ),
58    );
59    build.and_(
60        OperandX64::reg(byte_reg(tmp)),
61        OperandX64::mem(
62            SizeX64::byte,
63            RegisterX64::noreg,
64            1,
65            table,
66            core::mem::offset_of!(LuaTable, nodemask8) as i32,
67        ),
68    );
69
70    // LuaNode* n = &h->node[slot];
71    build.shl(
72        OperandX64::reg(dword_reg(tmp)),
73        OperandX64::imm(K_LUA_NODE_SIZE_LOG2),
74    );
75    build.add(OperandX64::reg(node), OperandX64::reg(tmp));
76}