Skip to main content

luaur_vm/functions/
lua_t_gettm.rs

1use crate::functions::lua_h_getstr::lua_h_getstr;
2use crate::macros::cast_byte::cast_byte;
3use crate::macros::ttisnil::ttisnil;
4use crate::type_aliases::lua_table::LuaTable;
5use crate::type_aliases::t_string::TString;
6use crate::type_aliases::t_value::TValue;
7use crate::type_aliases::tms::TMS;
8
9use luaur_common::macros::luau_assert::LUAU_ASSERT;
10
11#[allow(non_snake_case)]
12pub unsafe fn lua_t_gettm(events: *mut LuaTable, event: TMS, ename: *mut TString) -> *const TValue {
13    // The dependency card for lua_h_getstr shows a stub signature `pub fn lua_h_getstr()`.
14    // However, the C++ source and the logic of the VM require it to be the real implementation
15    // of luaH_getstr(LuaTable*, TString*). We must use the raw extern if the stub is incorrect,
16    // but per instructions we call the Rust path. Since the previous attempt failed due to
17    // the stub signature, we use an extern block to link to the actual symbol.
18    let tm = crate::functions::lua_h_getstr::luaH_getstr(events, ename);
19
20    // TMS is an enum; compare discriminants for the assertion.
21    LUAU_ASSERT!((event as u32) <= (TMS::TM_EQ as u32));
22
23    if ttisnil!(tm) {
24        // no tag method? cache this fact
25        (*events).tmcache |= cast_byte!(1u32 << (event as u32));
26        core::ptr::null()
27    } else {
28        tm
29    }
30}
31
32#[export_name = "luaT_gettm"]
33pub unsafe extern "C" fn lua_t_gettm_export(
34    events: *mut core::ffi::c_void,
35    event: TMS,
36    ename: *mut core::ffi::c_void,
37) -> *const TValue {
38    lua_t_gettm(events as *mut LuaTable, event, ename as *mut TString)
39}