luaur_vm/functions/
lua_debugtrace.rs1use 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}