Skip to main content

luaur_vm/functions/
lua_newstate.rs

1//! Node: `cxx:Function:Luau.VM:VM/src/lstate.cpp:184:lua_newstate`
2//! Source: `VM/src/lstate.cpp:184-290` (hand-ported)
3
4use crate::enums::lua_type::lua_Type;
5use crate::functions::close_state::close_state;
6use crate::functions::f_luaopen::f_luaopen;
7use crate::functions::lua_d_rawrunprotected_ldo::luaD_rawrunprotected;
8use crate::functions::preinit_state::preinit_state;
9use crate::macros::bit_2_mask::bit2mask;
10use crate::macros::fixedbit::FIXEDBIT;
11use crate::macros::lua_lutag_limit::LUA_LUTAG_LIMIT;
12use crate::macros::lua_memory_categories::LUA_MEMORY_CATEGORIES;
13use crate::macros::lua_sizeclasses::LUA_SIZECLASSES;
14use crate::macros::lua_utag_limit::LUA_UTAG_LIMIT;
15use crate::macros::registry::registry;
16use crate::macros::setnilvalue::setnilvalue;
17use crate::macros::utag_internal_limit::UTAG_INTERNAL_LIMIT;
18use crate::macros::white_0_bit::WHITE0BIT;
19use crate::records::lg::LG;
20use crate::type_aliases::lua_alloc::lua_Alloc;
21use crate::type_aliases::lua_state::lua_State;
22use crate::type_aliases::t_value::TValue;
23use luaur_common::macros::luau_assert::LUAU_ASSERT as _;
24
25#[allow(non_snake_case)]
26pub unsafe fn lua_newstate(f: lua_Alloc, ud: *mut core::ffi::c_void) -> *mut lua_State {
27    let Some(falloc) = f else {
28        return core::ptr::null_mut();
29    };
30    let l = falloc(ud, core::ptr::null_mut(), 0, core::mem::size_of::<LG>());
31    if l.is_null() {
32        return core::ptr::null_mut();
33    }
34    let L = l as *mut lua_State;
35    let g = &mut (*(l as *mut LG)).g as *mut crate::records::global_state::global_State;
36
37    (*L).hdr.tt = lua_Type::LUA_TTHREAD as u8;
38    (*g).currentwhite = bit2mask(WHITE0BIT, FIXEDBIT) as u8;
39    (*L).hdr.marked = (*g).currentwhite;
40    (*L).hdr.memcat = 0;
41    preinit_state(L, g);
42    (*g).frealloc = f;
43    (*g).ud = ud;
44    (*g).mainthread = L;
45    (*g).uvhead.u.open.prev = &mut (*g).uvhead;
46    (*g).uvhead.u.open.next = &mut (*g).uvhead;
47    (*g).GCthreshold = 0; // mark it as unfinished state
48    (*g).registryfree = 0;
49    (*g).errorjmp = core::ptr::null_mut();
50    (*g).rngstate = 0;
51    (*g).ptrenckey[0] = 1;
52    (*g).ptrenckey[1] = 0;
53    (*g).ptrenckey[2] = 0;
54    (*g).ptrenckey[3] = 0;
55    (*g).strt.size = 0;
56    (*g).strt.nuse = 0;
57    (*g).strt.hash = core::ptr::null_mut();
58    setnilvalue!(&mut (*g).pseudotemp as *mut TValue);
59    setnilvalue!(registry!(L) as *const TValue as *mut TValue);
60    (*g).gcstate = crate::macros::gc_spause::GCSpause as u8;
61    (*g).gray = core::ptr::null_mut();
62    (*g).grayagain = core::ptr::null_mut();
63    (*g).weak = core::ptr::null_mut();
64    (*g).totalbytes = core::mem::size_of::<LG>();
65    (*g).gcgoal = crate::macros::luai_gcgoal::LUAI_GCGOAL;
66    (*g).gcstepmul = crate::macros::luai_gcstepmul::LUAI_GCSTEPMUL;
67    (*g).gcstepsize = crate::macros::luai_gcstepsize::LUAI_GCSTEPSIZE << 10;
68
69    for i in 0..LUA_SIZECLASSES as usize {
70        (*g).freepages[i] = core::ptr::null_mut();
71        (*g).freegcopages[i] = core::ptr::null_mut();
72    }
73
74    (*g).allpages = core::ptr::null_mut();
75    (*g).allgcopages = core::ptr::null_mut();
76    (*g).sweepgcopage = core::ptr::null_mut();
77
78    for i in 0..(*g).mt.len() {
79        (*g).mt[i] = core::ptr::null_mut();
80    }
81
82    for i in 0..LUA_UTAG_LIMIT as usize {
83        (*g).udatagc[i] = None;
84        (*g).udatamt[i] = core::ptr::null_mut();
85    }
86
87    for i in 0..UTAG_INTERNAL_LIMIT as usize {
88        let udatadirect = &mut (*g).udatadirect[i];
89
90        setnilvalue!(&mut udatadirect.indextm as *mut TValue);
91        setnilvalue!(&mut udatadirect.newindextm as *mut TValue);
92        setnilvalue!(&mut udatadirect.namecalltm as *mut TValue);
93        udatadirect.index = None;
94        udatadirect.newindex = None;
95        udatadirect.namecall = None;
96    }
97
98    for i in 0..LUA_LUTAG_LIMIT as usize {
99        (*g).lightuserdataname[i] = core::ptr::null_mut();
100    }
101
102    if luaur_common::FFlag::LuauDirectFieldGet.get() {
103        for i in 0..UTAG_INTERNAL_LIMIT as usize {
104            (*g).udatadirectfields[i] = core::ptr::null_mut();
105        }
106    }
107
108    for i in 0..LUA_MEMORY_CATEGORIES as usize {
109        (*g).memcatbytes[i] = 0;
110    }
111
112    (*g).memcatbytes[0] = core::mem::size_of::<LG>();
113
114    (*g).cb = core::mem::zeroed(); // lua_Callbacks()
115    (*g).ecb = core::mem::zeroed(); // lua_ExecutionCallbacks()
116
117    (*g).ecbdata = core::mem::zeroed();
118
119    (*g).gcstats = Default::default(); // GCStats()
120    (*g).lastprotoid = 1;
121
122    if luaD_rawrunprotected(L, Some(f_luaopen), core::ptr::null_mut()) != 0 {
123        // memory allocation error: free partial state
124        close_state(L);
125        return core::ptr::null_mut();
126    }
127
128    luaur_common::LUAU_ASSERT!((*g).GCthreshold != 0);
129    L
130}