Skip to main content

luaur_code_gen/functions/
execute_getglobal.rs

1use luaur_vm::functions::lua_v_gettable::lua_v_gettable;
2use luaur_vm::macros::clvalue::clvalue;
3use luaur_vm::macros::sethvalue::sethvalue;
4use luaur_vm::macros::ttisstring::ttisstring;
5use luaur_vm::type_aliases::stk_id::StkId;
6use luaur_vm::type_aliases::t_value::TValue;
7
8use crate::macros::vm_patch_c::VM_PATCH_C;
9use crate::macros::vm_protect::vm_protect;
10use crate::macros::vm_reg::VM_REG;
11use crate::type_aliases::instruction_ir_builder::Instruction;
12use crate::type_aliases::lua_state::lua_State;
13
14use luaur_common::macros::luau_assert::LUAU_ASSERT;
15use luaur_common::macros::luau_insn_a::LUAU_INSN_A;
16use luaur_common::macros::luau_insn_c::LUAU_INSN_C;
17
18pub unsafe fn execute_getglobal(
19    L: *mut lua_State,
20    pc: *const Instruction,
21    base: StkId,
22    k: *mut TValue,
23) -> *const Instruction {
24    let l_ptr = L as *mut luaur_vm::records::lua_state::lua_State;
25    let cl = clvalue!((*(*l_ptr).ci).func);
26
27    let mut pc_ptr = pc;
28    let insn = *pc_ptr;
29    pc_ptr = pc_ptr.add(1);
30
31    let ra = VM_REG!(LUAU_INSN_A(insn) as i32, l_ptr, base);
32    let aux = *pc_ptr;
33    pc_ptr = pc_ptr.add(1);
34
35    let kv = (k as *const TValue).add(aux as usize);
36    LUAU_ASSERT!(ttisstring!(kv));
37
38    // fast-path should already have been checked, so we skip checking for it here
39    let h = (*cl).env;
40    let slot = (LUAU_INSN_C(insn) as i32) & (*h).nodemask8 as i32;
41
42    // slow-path, may invoke Lua calls via __index metamethod
43    let mut g = TValue::default();
44    sethvalue!(l_ptr, &mut g, h);
45    (*l_ptr).cachedslot = slot;
46
47    let mut current_base = base;
48    vm_protect!(l_ptr, pc_ptr, current_base, {
49        lua_v_gettable(l_ptr, &g as *const TValue, kv as *mut TValue, ra);
50    });
51
52    // save cachedslot to accelerate future lookups; patches currently executing instruction since pc-2 rolls back two pc++
53    VM_PATCH_C(pc_ptr.offset(-2), (*l_ptr).cachedslot);
54
55    pc_ptr
56}
57
58#[no_mangle]
59pub unsafe extern "C" fn executeGETGLOBAL(
60    L: *mut lua_State,
61    pc: *const Instruction,
62    base: StkId,
63    k: *mut TValue,
64) -> *const Instruction {
65    execute_getglobal(L, pc, base, k)
66}