Skip to main content

GlobalState

Struct GlobalState 

Source
pub struct GlobalState {
Show 55 fields pub parser_hook: Option<ParserHook>, pub file_loader_hook: Option<FileLoaderHook>, pub file_open_hook: Option<FileOpenHook>, pub popen_hook: Option<PopenHook>, pub file_remove_hook: Option<FileRemoveHook>, pub file_rename_hook: Option<FileRenameHook>, pub os_execute_hook: Option<OsExecuteHook>, pub dynlib_load_hook: Option<DynLibLoadHook>, pub dynlib_symbol_hook: Option<DynLibSymbolHook>, pub dynlib_unload_hook: Option<DynLibUnloadHook>, pub totalbytes: isize, pub gc_debt: isize, pub gc_estimate: usize, pub lastatomic: usize, pub strt: StringPool, pub l_registry: LuaValue, pub globals: LuaValue, pub loaded: LuaValue, pub nilvalue: LuaValue, pub seed: u32, pub currentwhite: u8, pub gcstate: u8, pub gckind: u8, pub gcstopem: bool, pub genminormul: u8, pub genmajormul: u8, pub gcstp: u8, pub gcemergency: bool, pub gcpause: u8, pub gcstepmul: u8, pub gcstepsize: u8, pub sweepgc_cursor: usize, pub weak_tables_registry: Vec<GcWeak<LuaTable>>, pub gc_tracked_long_strings: Vec<(GcWeak<LuaString>, usize)>, pub pending_finalizers: Vec<GcRef<LuaTable>>, pub to_be_finalized: Vec<GcRef<LuaTable>>, pub twups: Vec<GcRef<LuaState>>, pub panic: Option<LuaCFunction>, pub mainthread: Option<GcRef<LuaState>>, pub threads: HashMap<u64, ThreadRegistryEntry>, pub main_thread_value: GcRef<LuaThread>, pub current_thread_id: u64, pub main_thread_id: u64, pub next_thread_id: u64, pub memerrmsg: GcRef<LuaString>, pub tmname: Vec<GcRef<LuaString>>, pub mt: [Option<GcRef<LuaTable>>; 9], pub strcache: [[GcRef<LuaString>; 2]; 53], pub interned_lt: HashMap<Box<[u8]>, GcRef<LuaString>>, pub warnf: Option<Box<dyn FnMut(&[u8], bool)>>, pub c_functions: Vec<LuaCFunction>, pub heap: Heap, pub cross_thread_upvals: HashMap<(u64, StackIdx), LuaValue>, pub suspended_parent_stacks: Vec<Vec<LuaValue>>, pub suspended_parent_open_upvals: Vec<Vec<GcRef<UpVal>>>,
}
Expand description

Process-wide state shared by all Lua threads.

C: global_State in lstate.h. types.tsv: global_State → GlobalState

Not exposed directly at the API; accessed via state.global() / state.global_mut().

Fields§

§parser_hook: Option<ParserHook>

Phase-B hook for the Lua text parser. Set by the embedder (lua-cli or stdlib host) to bridge the cyclic crate split between lua-vm and lua-parse: when f_parser decides the chunk is text, it invokes this hook instead of the parser stub. None leaves the stub in place so unit tests that never load text still work.

§file_loader_hook: Option<FileLoaderHook>

Phase-B hook for reading a Lua source file from disk. Set by lua-cli (or any embedder that wants require/loadfile to reach the file system) since std::fs is banned in lua-stdlib. None makes loadfile and the Lua-file searcher report a file-not-found error.

§file_open_hook: Option<FileOpenHook>

Phase-B hook for opening a file handle for read/write/append. Set by lua-cli since std::fs is banned in lua-stdlib. None causes io.open and io.output(name) to return an error; the standard streams (io.stdin, io.stdout, io.stderr) remain functional.

§popen_hook: Option<PopenHook>

Phase-G hook for spawning a child process and connecting one stream (stdin or stdout) to a Lua file handle. Set by lua-cli since std::process::Command is banned in lua-stdlib. None causes io.popen to raise a Lua error rather than panic.

§file_remove_hook: Option<FileRemoveHook>

Phase-B hook for removing a file. Set by lua-cli since std::fs is banned in lua-stdlib. None causes os.remove to return an error.

§file_rename_hook: Option<FileRenameHook>

Phase-B hook for renaming a file. Set by lua-cli since std::fs is banned in lua-stdlib. None causes os.rename to return an error.

§os_execute_hook: Option<OsExecuteHook>

Phase-G hook for executing a shell command. Set by lua-cli since std::process is banned in lua-stdlib. None causes os.execute to report no shell available (matching C-Lua’s system(NULL) == 0).

§dynlib_load_hook: Option<DynLibLoadHook>

Phase-D-3.5 hook for loading a dynamic library (dlopen / LoadLibraryEx). Set by lua-cli since libloading is FFI and requires unsafe, which is banned in lua-stdlib. None causes package.loadlib to return the "absent" fallback shape.

§dynlib_symbol_hook: Option<DynLibSymbolHook>

Phase-D-3.5 hook for resolving a symbol in a previously loaded dynamic library (dlsym / GetProcAddress). Set by lua-cli. None is treated as “absent” by package.loadlib.

§dynlib_unload_hook: Option<DynLibUnloadHook>

Phase-D-3.5 hook for unloading a dynamic library (dlclose / FreeLibrary). Set by lua-cli. None keeps libraries loaded until process exit, which matches libloading’s safety model.

§totalbytes: isize§gc_debt: isize§gc_estimate: usize§lastatomic: usize§strt: StringPool§l_registry: LuaValue§globals: LuaValue§loaded: LuaValue§nilvalue: LuaValue§seed: u32§currentwhite: u8§gcstate: u8§gckind: u8§gcstopem: bool§genminormul: u8§genmajormul: u8§gcstp: u8§gcemergency: bool§gcpause: u8§gcstepmul: u8§gcstepsize: u8§sweepgc_cursor: usize§weak_tables_registry: Vec<GcWeak<LuaTable>>

Phase-B cross-table weak-sweep registry.

lua_types::value::sweep_weak_tables iterates this list at collectgarbage("collect") time to clear entries whose weak target is held only by other weak slots. Holds Weak<LuaTable> so the registry itself does not pin tables that the user has dropped. Replaced by the proper weak / ephemeron / allweak lists when Phase D’s incremental sweep lands.

§gc_tracked_long_strings: Vec<(GcWeak<LuaString>, usize)>

Phase-B long-string allocation tracker.

Each entry pairs a Weak<LuaString> with the byte count that was added to gc_debt at allocation time. collectgarbage("count") walks the list and reclaims gc_debt for entries whose weak target has been dropped, so the Lua-visible memory total tracks live long-string bytes. Short strings are interned and bounded in size, so they are not tracked individually. Replaced by Phase D’s real allocator accounting.

§pending_finalizers: Vec<GcRef<LuaTable>>

Phase-B pending-finalizer registry.

Each entry is a strong GcRef<LuaTable> to a table whose metatable carried __gc at the time setmetatable was called. The strong ref pins the table so a normal Rc::drop does not destroy it before its __gc metamethod runs. The Phase-B finalizer sweep (crate::api::run_pending_finalizers) scans this list, takes any entry whose strong count is 1 (only this list holds it — i.e. the user has dropped every reference), and invokes its __gc before releasing the ref. Replaced by finobj / tobefnz when the real incremental GC lands in Phase D.

§to_be_finalized: Vec<GcRef<LuaTable>>

Tables identified by the most recent collect_via_heap mark phase as reachable only through pending_finalizers (i.e. the user has dropped every reference). Their __gc runs the next time run_pending_finalizers executes; entries are then cleared. Traced as strong roots so they survive the sweep that scheduled them.

§twups: Vec<GcRef<LuaState>>§panic: Option<LuaCFunction>§mainthread: Option<GcRef<LuaState>>§threads: HashMap<u64, ThreadRegistryEntry>

Registry of all live coroutine threads, keyed by ThreadId. Phase E-1 replaces the thread_token placeholder with a real id-indexed map so coroutine.create allocates a fresh LuaState, registers it, and returns a value that resolves back to the same state on every coroutine.status / coroutine.resume call.

Each entry pairs the per-thread LuaState with the canonical GcRef<LuaThread> value, so two LuaValue::Thread pushes of the same id share GcRef::ptr_eq identity. The main thread is NOT stored here — its LuaState is owned externally by the embedder. main_thread_id is reserved as 0 and a LuaValue::Thread carrying id 0 is recognized as the main thread by lookup helpers.

§main_thread_value: GcRef<LuaThread>

Cached LuaValue::Thread payload for the main thread (id 0). Built once during new_state so every push_thread on the main thread shares the same GcRef<LuaThread> and thus compares pointer-equal under LuaValue::PartialEq.

§current_thread_id: u64

Identity of the currently-running thread. 0 (main) until a coroutine resume swaps it in slice 02b. The Phase E-1 slice always leaves this at main_thread_id because resume is not yet implemented.

§main_thread_id: u64

Identity of the main thread. Convention: 0. Held as a field so the lookup helpers can read it without hard-coding the constant.

§next_thread_id: u64

Monotonic counter handing out fresh ids in new_thread. Starts at 1 because 0 is reserved for the main thread.

§memerrmsg: GcRef<LuaString>§tmname: Vec<GcRef<LuaString>>§mt: [Option<GcRef<LuaTable>>; 9]§strcache: [[GcRef<LuaString>; 2]; 53]§interned_lt: HashMap<Box<[u8]>, GcRef<LuaString>>

Stable intern map for the public LuaString type. Distinct from strt (which keys internal LuaStringImpl) because the parser and stdlib need pointer-equality across intern_str calls so GcRef::ptr_eq can resolve variable identity. Without this map each call allocates a fresh GcRef and locals/upvalues fail to resolve.

§warnf: Option<Box<dyn FnMut(&[u8], bool)>>§c_functions: Vec<LuaCFunction>

Registry of native LuaCFunction pointers. Lua-types cannot reference LuaState, so LuaClosure::LightC carries a usize index into this vector instead of the real function pointer. push_c_function registers the function and stores the resulting index in the closure.

§heap: Heap

Phase-D heap. Owns the allgc intrusive list and runs collections. During Phase A-C this is paused=true, so allocations don’t auto- register and step is a no-op. Phase D-1d wires unpause() after state initialization, at which point step runs during VM dispatch.

§cross_thread_upvals: HashMap<(u64, StackIdx), LuaValue>

Phase E-3 cross-thread open-upvalue mirror. Maps (thread_id, stack_idx) to the live value of an open upvalue whose home thread is currently suspended while another thread runs. coroutine.resume snapshots the parent’s open upvalues into this map before yielding control to the child, and reads the (possibly mutated) values back into the parent’s stack when the child suspends or returns. From the running thread’s perspective, upvalue_get / upvalue_set consult the mirror whenever an open upvalue’s thread_id does not match current_thread_id.

This avoids a stack refactor: the parent’s LuaState is held by a &mut reference up the call stack during resume, so its stack cannot be reached directly through any Rc<RefCell<_>>. The mirror is the shared scratchpad that bridges the gap for the duration of a resume.

§suspended_parent_stacks: Vec<Vec<LuaValue>>

Phase F-1.a workaround for GC use-after-free across coroutine boundaries. When aux_resume switches to a child thread, the parent’s live stack values would otherwise become unreachable to the tracer for the duration of the resume (the parent LuaState is held only as a stack-borrowed &mut up the call chain and is not part of any traced root set). To keep those values alive, aux_resume pushes a snapshot of the parent stack here before transferring control, and pops it on suspension or completion. The tracer visits every snapshot as a GC root via the Trace for GlobalState impl in trace_impls.rs.

Phase F-2.b added a reachability-driven thread sweep that supersedes most of this, but the snapshot still guards values that live only on the parent’s stack (i.e. not yet rooted by any thread node).

§suspended_parent_open_upvals: Vec<Vec<GcRef<UpVal>>>

Open-upvalue handles belonging to the same suspended parent windows as suspended_parent_stacks. Stack snapshots keep the pointed-to values alive; this roots the UpVal objects themselves so a GC inside the child coroutine cannot sweep entries still present in the parent’s openupval list.

Implementations§

Source§

impl GlobalState

Source

pub fn total_bytes(&self) -> usize

Total live bytes allocated (GCdebt + totalbytes).

C: gettotalbytes(g) macro → cast(lu_mem, (g)->totalbytes + (g)->GCdebt) macros.tsv: gettotalbytes → g.total_bytes()

Source

pub fn get_thread(&self, id: u64) -> Option<&ThreadRegistryEntry>

Look up the coroutine LuaState registered under id. Returns None for the main-thread id (the main LuaState is owned by the embedder, not stored in threads) and for ids that were never issued or have already been closed.

Source

pub fn thread_value_for(&self, id: u64) -> Option<GcRef<LuaThread>>

Return the canonical GcRef<LuaThread> for id. For the main thread that’s main_thread_value; for a coroutine it’s the value stored in the registry. Returns None if id is unknown.

Source

pub fn is_complete(&self) -> bool

Returns true when the state has been fully initialized.

C: completestate(g) macro → ttisnil(&g->nilvalue) macros.tsv: completestate → g.is_complete()

PORT NOTE: C uses g->nilvalue being nil as the “complete” signal. We replicate the same logic: nilvalue == Nil means complete.

Source

pub fn current_white(&self) -> u8

Returns the “current white” GC color bitmask.

C: luaC_white(g) macro. macros.tsv: luaC_white → g.current_white()

PORT NOTE: GC color management deferred to Phase D; always returns the initial white bit.

Source

pub fn other_white(&self) -> u8

Returns the “other white” GC color bitmask.

C: otherwhite(g) macro. macros.tsv: otherwhite → g.other_white()

Source

pub fn is_gen_mode(&self) -> bool

Returns true if the GC is in generational mode.

C: isdecGCmodegen(g) macro. macros.tsv: isdecGCmodegen → g.is_gen_mode()

Source

pub fn gc_running(&self) -> bool

Returns true if the GC is currently running.

C: gcrunning(g) macro. macros.tsv: gcrunning → g.gc_running()

Source

pub fn keep_invariant(&self) -> bool

Returns true while the GC is in its propagation phase.

C: keepinvariant(g) macro. macros.tsv: keepinvariant → g.keep_invariant()

Source

pub fn is_sweep_phase(&self) -> bool

Returns true while the GC is in a sweep phase.

C: issweepphase(g) macro. macros.tsv: issweepphase → g.is_sweep_phase()

Source

pub fn gc_debt(&self) -> isize

Source

pub fn set_gc_debt(&mut self, d: isize)

Source

pub fn gc_at_pause(&self) -> bool

Source

pub fn gc_pause_param(&self) -> u8

Source

pub fn set_gc_pause_param(&mut self, p: u8)

Source

pub fn gc_stepmul_param(&self) -> u8

Source

pub fn set_gc_stepmul_param(&mut self, p: u8)

Source

pub fn set_gc_genmajormul(&mut self, p: u8)

Source

pub fn gc_stop_flags(&self) -> u8

Source

pub fn set_gc_stop_flags(&mut self, f: u8)

Source

pub fn stop_gc_internal(&mut self) -> u8

Source

pub fn set_gc_stop_user(&mut self)

Source

pub fn clear_gc_stop(&mut self)

Source

pub fn is_gc_running(&self) -> bool

C: gcrunning(g) in lgc.h.

Source

pub fn is_gc_stopped_internally(&self) -> bool

True when the GC has been disabled internally (state setup, mid-GC, or while closing); user-stop via collectgarbage("stop") does NOT set this bit, so lua_gc continues to honour Count/Step/etc.

C: g->gcstp & GCSTPGC (lapi.c:1137).

Source

pub fn tm_name<T: TmIndex>(&self, tm: T) -> Option<GcRef<LuaString>>

Returns the interned __xxx name string for tag method tm, or None if tmname has not yet been initialised (early bootstrap).

C: G(L)->tmname[tm] (lookup via macro in ltm.h). macros.tsv: getshrstr(G(L)->tmname[tm]) → g.tm_name(tm).

PORT NOTE: The lua-vm crate carries two distinct TagMethod enums (one in lua-types, one in crate::tagmethods) with identical #[repr(u8)] ordering. The TmIndex trait bridges them so callers from either side can index tmname uniformly.

Trait Implementations§

Source§

impl Trace for GlobalState

Source§

fn trace(&self, m: &mut Marker)

Auto Trait Implementations§

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = Infallible

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.