Skip to main content

luaur_vm/functions/
lua_getinfo.rs

1//! Node: `cxx:Function:Luau.VM:VM/src/ldebug.cpp:185:lua_getinfo`
2//!
3//! `lua_getinfo` — resolve a stack `level` (negative = relative to top, else a
4//! call-info depth) to its closure, fill `ar` via `auxgetinfo`, and (when the
5//! `f` option pushed the function) place it on the stack. Returns 1 if a
6//! function was found at that level, else 0.
7
8use crate::functions::auxgetinfo::auxgetinfo;
9use crate::macros::clvalue::clvalue;
10use crate::macros::incr_top::incr_top;
11use crate::macros::lua_c_threadbarrier::luaC_threadbarrier;
12use crate::macros::setclvalue::setclvalue;
13use crate::macros::ttisfunction::ttisfunction;
14use crate::records::call_info::CallInfo;
15use crate::records::closure::Closure;
16use crate::records::lua_debug::LuaDebug;
17use crate::type_aliases::lua_state::lua_State;
18use core::ffi::{c_char, c_int};
19use luaur_common::LUAU_ASSERT;
20
21#[allow(non_snake_case)]
22pub unsafe fn lua_getinfo(
23    L: *mut lua_State,
24    level: c_int,
25    what: *const c_char,
26    ar: *mut LuaDebug,
27) -> c_int {
28    let mut f: *mut Closure = core::ptr::null_mut();
29    let mut ci: *mut CallInfo = core::ptr::null_mut();
30
31    if level < 0 {
32        // element has to be within stack
33        if (-level) as isize > (*L).top.offset_from((*L).base) {
34            return 0;
35        }
36
37        let func = (*L).top.offset(level as isize);
38
39        // and it has to be a function
40        if !ttisfunction!(func) {
41            return 0;
42        }
43
44        f = clvalue!(func);
45    } else if (level as u32) < (*L).ci.offset_from((*L).base_ci) as u32 {
46        ci = (*L).ci.offset(-(level as isize));
47        LUAU_ASSERT!(ttisfunction!((*ci).func));
48        f = clvalue!((*ci).func);
49    }
50
51    if !f.is_null() {
52        // auxgetinfo fills ar and optionally requests to put closure on stack
53        let fcl = auxgetinfo(L, what, ar, f, ci);
54        if !fcl.is_null() {
55            luaC_threadbarrier!(L);
56            setclvalue!(L, (*L).top, fcl);
57            incr_top!(L);
58        }
59    }
60
61    if f.is_null() {
62        0
63    } else {
64        1
65    }
66}