luaur_vm/functions/
enumthread.rs1use crate::functions::enumedge::enumedge;
2use crate::functions::enumedges::enumedges;
3use crate::functions::enumnode::enumnode;
4use crate::macros::clvalue::clvalue;
5use crate::macros::getstr::getstr;
6use crate::macros::lua_idsize::LUA_IDSIZE;
7use crate::macros::obj_2_gco::obj2gco;
8use crate::macros::ttisfunction::ttisfunction;
9use crate::records::call_info::CallInfo;
10use crate::records::enum_context::EnumContext;
11use crate::records::gc_object::GCObject;
12use crate::records::lua_state::lua_State;
13use crate::records::proto::Proto;
14use crate::records::t_string::TString;
15use crate::type_aliases::closure::Closure;
16use crate::type_aliases::t_value::TValue;
17use core::ffi::{c_char, c_int};
18
19#[allow(non_snake_case)]
20pub unsafe fn enumthread(ctx: *mut EnumContext, th: *mut lua_State) {
21 let size = core::mem::size_of::<lua_State>()
22 + core::mem::size_of::<TValue>() * (*th).stacksize as usize
23 + core::mem::size_of::<CallInfo>() * (*th).size_ci as usize;
24
25 let mut tcl: *mut Closure = core::ptr::null_mut();
26 let mut ci: *mut CallInfo = (*th).base_ci;
27 while ci <= (*th).ci {
28 if ttisfunction!((*ci).func) {
29 tcl = clvalue!((*ci).func);
30 break;
31 }
32 ci = ci.wrapping_add(1);
33 }
34
35 if !tcl.is_null() && (*tcl).isC == 0 {
36 let tcl_l = core::ptr::addr_of!((*tcl).inner.l).cast::<crate::records::closure::LClosure>();
37 let p: *mut Proto = (*tcl_l).p;
38 if !p.is_null() {
39 let mut buf: [c_char; 256] = [0; 256];
40
41 let src_str = if !(*p).source.is_null() {
42 getstr((*p).source)
43 } else {
44 c"unnamed".as_ptr()
45 };
46 let debugname_str = if !(*p).debugname.is_null() {
47 getstr((*p).debugname)
48 } else {
49 c"unnamed".as_ptr()
50 };
51
52 let _ = snprintf(
53 buf.as_mut_ptr(),
54 buf.len() as u32,
55 c"thread at %s:%d %s".as_ptr(),
56 debugname_str,
57 (*p).linedefined,
58 src_str,
59 );
60
61 enumnode(ctx, obj2gco!(th as *mut GCObject), size, buf.as_ptr());
62 } else {
63 enumnode(ctx, obj2gco!(th as *mut GCObject), size, core::ptr::null());
64 }
65 } else {
66 enumnode(ctx, obj2gco!(th as *mut GCObject), size, core::ptr::null());
67 }
68
69 enumedge(
70 ctx,
71 obj2gco!(th as *mut GCObject),
72 obj2gco!((*th).gt as *mut GCObject),
73 c"globals".as_ptr(),
74 );
75
76 if (*th).top > (*th).stack {
77 enumedges(
78 ctx,
79 obj2gco!(th as *mut GCObject),
80 (*th).stack,
81 (*th).top.offset_from((*th).stack) as usize,
82 c"stack".as_ptr(),
83 );
84 }
85}
86
87extern "C" {
89 fn snprintf(s: *mut c_char, n: u32, format: *const c_char, ...) -> c_int;
90}