Skip to main content

luaur_vm/functions/
enumclosure.rs

1use crate::functions::enumedge::enumedge;
2use crate::functions::enumedges::enumedges;
3use crate::functions::enumnode::enumnode;
4use crate::macros::getstr::getstr;
5use crate::macros::lua_idsize::LUA_IDSIZE;
6use crate::macros::size_cclosure::size_cclosure;
7use crate::macros::size_lclosure::size_lclosure;
8use crate::records::closure::Closure;
9use crate::records::enum_context::EnumContext;
10use crate::records::gc_object::GCObject;
11use crate::records::proto::Proto;
12use core::ffi::{c_char, c_int};
13
14#[allow(non_snake_case)]
15pub(crate) unsafe fn enumclosure(ctx: *mut EnumContext, cl: *mut Closure) {
16    let cl_ref = &*cl;
17    let obj = cl as *mut GCObject;
18
19    extern "C" {
20        fn snprintf(s: *mut c_char, n: usize, format: *const c_char, ...) -> c_int;
21    }
22
23    if cl_ref.isC != 0 {
24        enumnode(
25            ctx,
26            obj,
27            size_cclosure(cl_ref.nupvalues as c_int),
28            cl_ref.inner.c.debugname,
29        );
30    } else {
31        let p: *mut Proto = cl_ref.inner.l.p;
32        let mut buf = [0i8; LUA_IDSIZE as usize];
33
34        let unnamed = c"unnamed".as_ptr();
35        let debug_name = if !(*p).debugname.is_null() {
36            getstr((*p).debugname)
37        } else {
38            unnamed
39        };
40
41        if !(*p).source.is_null() {
42            snprintf(
43                buf.as_mut_ptr(),
44                buf.len(),
45                c"%s:%d %s".as_ptr(),
46                debug_name,
47                (*p).linedefined,
48                getstr((*p).source),
49            );
50        } else {
51            snprintf(
52                buf.as_mut_ptr(),
53                buf.len(),
54                c"%s:%d".as_ptr(),
55                debug_name,
56                (*p).linedefined,
57            );
58        }
59
60        enumnode(
61            ctx,
62            obj,
63            size_lclosure(cl_ref.nupvalues as usize),
64            buf.as_ptr(),
65        );
66    }
67
68    enumedge(ctx, obj, cl_ref.env as *mut GCObject, c"env".as_ptr());
69
70    if cl_ref.isC != 0 {
71        if cl_ref.nupvalues > 0 {
72            enumedges(
73                ctx,
74                obj,
75                cl_ref.inner.c.upvals.as_ptr() as *mut _,
76                cl_ref.nupvalues as usize,
77                c"upvalue".as_ptr(),
78            );
79        }
80    } else {
81        enumedge(
82            ctx,
83            obj,
84            cl_ref.inner.l.p as *mut GCObject,
85            c"proto".as_ptr(),
86        );
87
88        if cl_ref.nupvalues > 0 {
89            enumedges(
90                ctx,
91                obj,
92                cl_ref.inner.l.uprefs.as_ptr() as *mut _,
93                cl_ref.nupvalues as usize,
94                c"upvalue".as_ptr(),
95            );
96        }
97    }
98}