Skip to main content

luaur_vm/functions/
lua_debugtrace.rs

1//! Node: `cxx:Function:Luau.VM:VM/src/ldebug.cpp:630:lua_debugtrace`
2//! Source: `VM/src/ldebug.cpp:630-677` (hand-ported)
3
4use crate::functions::append::append;
5use crate::functions::lua_getinfo::lua_getinfo;
6use crate::records::lua_debug::LuaDebug;
7use crate::type_aliases::lua_state::lua_State;
8
9static mut BUF: [core::ffi::c_char; 4096] = [0; 4096];
10
11#[allow(non_snake_case)]
12pub unsafe fn lua_debugtrace(L: *mut lua_State) -> *const core::ffi::c_char {
13    const LIMIT1: core::ffi::c_int = 10;
14    const LIMIT2: core::ffi::c_int = 10;
15
16    let depth: core::ffi::c_int = (*L).ci.offset_from((*L).base_ci) as core::ffi::c_int;
17    let mut offset: usize = 0;
18
19    let mut ar: LuaDebug = core::mem::zeroed();
20
21    extern "C" {
22        fn snprintf(
23            s: *mut core::ffi::c_char,
24            n: usize,
25            format: *const core::ffi::c_char,
26            ...
27        ) -> core::ffi::c_int;
28    }
29
30    let mut level: core::ffi::c_int = 0;
31    while lua_getinfo(L, level, c"sln".as_ptr(), &mut ar as *mut LuaDebug) != 0 {
32        if !ar.short_src.is_null() {
33            offset = append(BUF.as_mut_ptr(), BUF.len(), offset, ar.short_src);
34        }
35
36        if ar.currentline > 0 {
37            let mut line: [core::ffi::c_char; 32] = [0; 32];
38            snprintf(
39                line.as_mut_ptr(),
40                line.len(),
41                c":%d".as_ptr(),
42                ar.currentline,
43            );
44
45            offset = append(BUF.as_mut_ptr(), BUF.len(), offset, line.as_ptr());
46        }
47
48        if !ar.name.is_null() {
49            offset = append(BUF.as_mut_ptr(), BUF.len(), offset, c" function ".as_ptr());
50            offset = append(BUF.as_mut_ptr(), BUF.len(), offset, ar.name);
51        }
52
53        offset = append(BUF.as_mut_ptr(), BUF.len(), offset, c"\n".as_ptr());
54
55        if depth > LIMIT1 + LIMIT2 && level == LIMIT1 - 1 {
56            let mut skip: [core::ffi::c_char; 32] = [0; 32];
57            snprintf(
58                skip.as_mut_ptr(),
59                skip.len(),
60                c"... (+%d frames)\n".as_ptr(),
61                depth - LIMIT1 - LIMIT2,
62            );
63
64            offset = append(BUF.as_mut_ptr(), BUF.len(), offset, skip.as_ptr());
65
66            level = depth - LIMIT2 - 1;
67        }
68
69        level += 1;
70    }
71
72    luaur_common::macros::luau_assert::LUAU_ASSERT!(offset < BUF.len());
73    BUF[offset] = 0;
74
75    BUF.as_ptr()
76}