Skip to main content

luaur_vm/functions/
enumclass.rs

1use crate::functions::enumedge::enumedge;
2use crate::functions::enumnode::enumnode;
3use crate::macros::gcvalue::gcvalue;
4use crate::macros::getstr::getstr;
5use crate::macros::iscollectable::iscollectable;
6use crate::macros::lua_idsize::LUA_IDSIZE;
7use crate::macros::obj_2_gco::obj2gco;
8use crate::records::enum_context::EnumContext;
9use crate::records::gc_object::GCObject;
10use crate::records::luau_class::LuauClass;
11use core::ffi::{c_char, c_int};
12
13#[allow(non_snake_case)]
14pub(crate) unsafe fn enumclass(ctx: *mut EnumContext, lco: *mut LuauClass) {
15    let lco_ref = &*lco;
16    let mut buf = [0i8; LUA_IDSIZE as usize];
17    let obj = lco 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    snprintf(
24        buf.as_mut_ptr(),
25        buf.len(),
26        b"class object %s\0".as_ptr() as *const c_char,
27        getstr(lco_ref.name),
28    );
29
30    enumnode(ctx, obj, core::mem::size_of::<LuauClass>(), buf.as_ptr());
31    enumedge(
32        ctx,
33        obj,
34        lco_ref.name as *mut GCObject,
35        b"classname\0".as_ptr() as *const c_char,
36    );
37    enumedge(
38        ctx,
39        obj,
40        lco_ref.memberstooffset as *mut GCObject,
41        b"classoffsets\0".as_ptr() as *const c_char,
42    );
43
44    let numberofstaticmembers = lco_ref.numberofallmembers - lco_ref.numberofinstancemembers;
45    for i in 0..numberofstaticmembers {
46        let val_ptr = lco_ref.staticmembers.add(i as usize);
47        if !iscollectable!(val_ptr) {
48            continue;
49        }
50
51        let mut membername = [0i8; 32];
52        let name_ptr = *lco_ref
53            .offsettomember
54            .add((i + lco_ref.numberofinstancemembers) as usize);
55        snprintf(
56            membername.as_mut_ptr(),
57            membername.len(),
58            b"%s\0".as_ptr() as *const c_char,
59            getstr(name_ptr),
60        );
61        enumedge(ctx, obj, gcvalue!(val_ptr), membername.as_ptr());
62    }
63
64    for i in 0..lco_ref.numberofallmembers {
65        enumedge(
66            ctx,
67            obj,
68            *lco_ref.offsettomember.add(i as usize) as *mut GCObject,
69            b"membername\0".as_ptr() as *const c_char,
70        );
71    }
72
73    enumedge(
74        ctx,
75        obj,
76        lco_ref.metatable as *mut GCObject,
77        b"metatable\0".as_ptr() as *const c_char,
78    );
79}