Skip to main content

LuaState

Struct LuaState 

Source
pub struct LuaState {
Show 21 fields pub status: u8, pub allowhook: bool, pub nci: u32, pub top: StackIdx, pub stack_last: StackIdx, pub stack: Vec<StackValue>, pub ci: CallInfoIdx, pub call_info: Vec<CallInfo>, pub openupval: Vec<GcRef<UpVal>>, pub legacy_open_upval_touched: Cell<bool>, pub tbclist: Vec<StackIdx>, pub hook: Option<Box<dyn FnMut(&mut LuaState, &LuaDebug)>>, pub hookmask: u8, pub basehookcount: i32, pub hookcount: i32, pub errfunc: isize, pub n_ccalls: u32, pub oldpc: u32, pub marked: u8, pub cached_thread_id: u64, pub gc_check_needed: bool, /* private fields */
}
Expand description

Per-thread Lua execution state.

All stack-pointer fields in C (StkIdRel, StkId) become StackIdx (u32 index into stack: Vec<StackValue>). The C intrusive CallInfo linked list becomes call_info: Vec<CallInfo> indexed by CallInfoIdx.

No extra_space field: C’s LUA_EXTRASPACE reserves a small, fixed-size raw memory region immediately before lua_State for embedder bookkeeping, addressable via lua_getextraspace without a registry lookup — a niche embedding feature (issue #275 item 3). This port has no equivalent field or accessor; an embedder that needs per-thread scratch storage should use the registry (Lua::create_registry_value/set_named_registry_value) or a side table keyed by thread identity instead. Tracked as a known unsupported embedding feature in docs/EMBEDDING_API_IMPLEMENTATION.md’s Known Limits.

Fields§

§status: u8§allowhook: bool§nci: u32§top: StackIdx§stack_last: StackIdx

Redundant once the stack is a Vec (kept for parity with the C field).

§stack: Vec<StackValue>§ci: CallInfoIdx§call_info: Vec<CallInfo>

C’s base_ci is call_info[0] here; there is no separate field.

§openupval: Vec<GcRef<UpVal>>§legacy_open_upval_touched: Cell<bool>

Per-thread mirror of C 5.3’s per-open-upvalue touched flag (lfunc.h UpVal.u.open.touched). Set when this thread creates or writes an open upvalue; consulted only by the legacy (5.1/5.2/5.3) remarkupvals pass in [trace_reachable_threads]. In those versions an unmarked thread’s touched open upvalues have their values re-marked once during the atomic phase, then the flag is cleared (mirroring C clearing touched and dropping the thread from g->twups). This is what makes a cycle reachable only through a suspended thread survive one extra collection before being finalized. From 5.4 the C condition became !iswhite(uv) instead of touched, so this flag is never read for modern versions and the baked 5.4/5.5 behavior is unchanged.

§tbclist: Vec<StackIdx>§hook: Option<Box<dyn FnMut(&mut LuaState, &LuaDebug)>>§hookmask: u8§basehookcount: i32§hookcount: i32§errfunc: isize§n_ccalls: u32§oldpc: u32§marked: u8§cached_thread_id: u64

Owner thread id for this LuaState, cached as a plain u64 so the hot path of upvalue_get can compare against an open upvalue’s thread_id without taking a RefCell::borrow on the shared GlobalState.

Invariant: while this LuaState is the actively running thread, GlobalState::current_thread_id == self.cached_thread_id. This is maintained structurally by new_state/new_thread (which set cached_thread_id to the thread’s own id once at construction) combined with the coroutine resume protocol: coro_lib::resume writes co_state.global.current_thread_id = co_id before the coroutine runs, and restores parent_thread_id on yield/return. Because each thread caches its own id (not the global’s id), the invariant survives every context switch without an explicit refresh at the resume site.

§gc_check_needed: bool

Local GC gate.

Avoids borrowing GlobalState on every call edge when GC/finalizers are not currently due.

Implementations§

Source§

impl LuaState

Inherent push_copy so the LuaStateStubExt::push_copy default todo!() no longer fires. state.push_copy(idx) call-sites (base.rs, etc.) duplicate the value at idx onto the top of the stack — the same semantics as lua_pushvalue.

Source

pub fn push_copy(&mut self, idx: i32) -> Result<(), LuaError>

Source

pub fn push_value_at(&mut self, idx: i32) -> Result<(), LuaError>

Source

pub fn insert(&mut self, idx: i32) -> Result<(), LuaError>

Source

pub fn length_at(&mut self, idx: i32) -> Result<i64, LuaError>

Inherent length_at mirroring luaL_len from lauxlib.c: push the value’s length onto the stack (honouring __len), pop it as an integer, and error if the result is not an integer. Defined on LuaState so it overrides the LuaStateStubExt::length_at trait default todo!().

Source

pub fn write_output(&mut self, msg: &[u8]) -> Result<(), LuaError>

Write msg bytes verbatim to standard output. Mirrors the C macro lua_writestring(s, l) = fwrite(s, 1, l, stdout) from lauxlib.h, used by print and friends. A failed write is propagated as a LuaError::runtime; this matches C-Lua’s behaviour where an I/O error during lua_writestring would surface through the host’s error handling.

Source

pub fn to_display_string(&mut self, idx: i32) -> Result<Vec<u8>, LuaError>

Convert the value at idx to a display string, push the result onto the stack, and return a copy of its bytes. Mirrors luaL_tolstring from lauxlib.c. The default Lua formatting is used for primitives ("true"/"false"/"nil", %I integers, %.14g floats); for other reference types the result is "<typename>: 0x<hex pointer>".

If the value has a __tostring metamethod, it is invoked first and its (string) result is used in place of the default formatting (matching

Source

pub fn top(&mut self) -> i32

(stack top minus the slot just after the frame’s func).

Receiver is &mut self to match the LuaStateStubExt::top trait signature exactly; with a different receiver shape (&self), Rust’s method-resolution picks the trait default and the program panics on todo!("phase-b-reconcile: top").

Source

pub fn get_top(&mut self) -> i32

LuaStateStubExt::get_top trait method. Inherent method shadows the trait default so the todo!("phase-b-reconcile: get_top") shim never fires.

Source

pub fn type_at(&mut self, idx: i32) -> LuaType

stack index idx, or LuaType::None if idx falls outside the active call frame. Inherent method shadows the LuaStateStubExt::type_at trait default so the todo!() shim never fires.

Source

pub fn check_arg_any(&mut self, arg: i32) -> Result<(), LuaError>

#N (value expected)error if the slot atargisLUA_TNONE` (i.e. beyond the active call frame’s top). Otherwise a no-op.

Inherent method on LuaState shadows the LuaStateStubExt::check_arg_any trait default so the todo!() shim never fires.

Source

pub fn check_arg_string(&mut self, arg: i32) -> Result<Vec<u8>, LuaError>

at arg to a string via lua_tolstring (which coerces numbers to their string form) and returns the bytes. Raises bad argument #N (string expected, got <type>) if the value is not a string and not number-coercible.

Inherent method on LuaState shadows the LuaStateStubExt::check_arg_string trait default so the todo!() shim never fires. Uses the free to_lua_string helper here rather than auxlib::check_lstring, which routes through state.to_lua_string / state.type_name — both still trait stubs.

Source

pub fn check_arg_integer(&mut self, arg: i32) -> Result<i64, LuaError>

arg to a lua_Integer (i64) via lua_tointegerx (which accepts ints, floats with exact integer value, and string-form integers). Raises bad argument #N (number has no integer representation) if the value is a number but not representable as an integer, or bad argument #N (number expected, got <type>) otherwise.

Inherent method on LuaState shadows the LuaStateStubExt::check_arg_integer trait default so the todo!() shim never fires. Uses the free to_integer_x / is_number helpers in this file rather than auxlib::check_integer, which routes through state.to_integer_x and state.type_name — both still trait stubs.

Source

pub fn check_number(&mut self, arg: i32) -> Result<f64, LuaError>

arg to an f64 via lua_tonumberx (which accepts ints, floats, and number-shaped strings) and raises bad argument #N (number expected, got <type>) if the value is not number-coercible.

Inherent method on LuaState shadows the LuaStateStubExt::check_number trait default so the todo!() shim never fires. Uses the free to_number_x helper here rather than auxlib::check_number, which routes through state.to_number_x and state.type_name — both still trait stubs.

Source

pub fn opt_arg_integer(&mut self, arg: i32, def: i64) -> Result<i64, LuaError>

arg is absent (LUA_TNONE) or nil, return def; otherwise convert it to an integer (with the same string-to-number coercion lua_tointegerx applies) and raise on failure.

Inherent method on LuaState shadows the LuaStateStubExt::opt_arg_integer trait default so the todo!() shim never fires. Implemented with the free-function helpers in this file rather than auxlib::opt_integer because the latter routes through state.is_none_or_nil and state.to_integer_x, which are themselves stubbed.

Source

pub fn protected_call( &mut self, nargs: i32, nresults: i32, msgh: i32, ) -> Result<(), LuaError>

lua_pcallk with no continuation. Defers to the existing pcall_k free function, which routes through protected_call_raw and surfaces any runtime / syntax error as Err(LuaError::Runtime|Syntax).

Inherent method on LuaState shadows the LuaStateStubExt::protected_call trait default so the todo!() shim never fires.

Source

pub fn protected_call_k( &mut self, nargs: i32, nresults: i32, msgh: i32, ctx: isize, k: Option<fn(&mut LuaState, i32, isize) -> Result<usize, LuaError>>, ) -> Result<(), LuaError>

protected call. When k is set and the thread is yieldable, an inner yield propagates as LuaError::Yield and the continuation fires on resume via finishCcallfinishpcallk.

Source

pub fn push_string(&mut self, s: &[u8]) -> Result<(), LuaError>

Source

pub fn push_c_closure( &mut self, f: fn(&mut LuaState) -> Result<usize, LuaError>, n: i32, ) -> Result<(), LuaError>

Source

pub fn raw_seti(&mut self, idx: i32, n: i64) -> Result<(), LuaError>

Source

pub fn table_set_i(&mut self, idx: i32, n: i64) -> Result<(), LuaError>

Source

pub fn table_get_i_value( &mut self, t: &LuaValue, n: i64, ) -> Result<LuaType, LuaError>

Get t[n] where t is a pre-resolved LuaValue, bypassing stack-index resolution. Use this in tight loops that operate on the same table repeatedly to avoid the index_to_value call per iteration.

Source

pub fn table_set_i_value( &mut self, t: &LuaValue, n: i64, ) -> Result<(), LuaError>

Set t[n] = stack_top (then pop) where t is a pre-resolved LuaValue, bypassing stack-index resolution. Use this in tight loops that operate on the same table repeatedly to avoid the index_to_value call per iteration.

Source

pub fn create_table(&mut self, narr: i32, nrec: i32) -> Result<(), LuaError>

Source

pub fn registry_set(&mut self, key: &[u8]) -> Result<(), LuaError>

Pop the value on top of the stack and store it in the registry under the string key.

Source

pub fn new_metatable(&mut self, tname: &[u8]) -> Result<bool, LuaError>

Create a new metatable in the registry under key tname. Leaves the new metatable on top of the stack and returns true when newly created. If registry[tname] already exists, leaves it on top of the stack and returns false.

Source

pub fn new_lib( &mut self, funcs: &[(&[u8], fn(&mut LuaState) -> Result<usize, LuaError>)], ) -> Result<(), LuaError>

Create a new library table sized for funcs and register each entry as a closure field on it. Leaves the table on the top of the stack.

luaL_checkversion(L), luaL_newlibtable(L,l), luaL_setfuncs(L,l,0). luaL_checkversion is a no-op here (no ABI-version mismatch is possible inside the Rust port).

Source

pub fn register_lib( &mut self, _name: &[u8], funcs: &[(&[u8], fn(&mut LuaState) -> Result<usize, LuaError>)], ) -> Result<(), LuaError>

Create and populate a library table for funcs, leaving it on top of the stack. The _name argument is informational and matches the luaL_register-style call sites in the Phase-A stdlib; the actual global binding for the library happens later via luaL_requiref.

Source

pub fn new_lib_table( &mut self, funcs: &[(&[u8], fn(&mut LuaState) -> Result<usize, LuaError>)], ) -> Result<(), LuaError>

Create a new empty table presized to hold every entry in funcs, and leave it on top of the stack. No registration is performed — callers typically follow up with set_funcs / set_funcs_with_upvalues to populate the table.

lua_createtable(L, 0, sizeof(l)/sizeof((l)[0]) - 1). The C macro’s - 1 discounts the sentinel {NULL, NULL} entry; the Rust slice has no sentinel, so we use funcs.len() directly.

Source

pub fn set_funcs_with_upvalues( &mut self, funcs: &[(&[u8], fn(&mut LuaState) -> Result<usize, LuaError>)], nup: i32, ) -> Result<(), LuaError>

Register each entry in funcs as a C closure on the table at index -(nup + 2), sharing the nup values currently on top of the stack as upvalues. The upvalues are popped at the end.

Source

pub fn set_metatable(&mut self, objindex: i32) -> Result<(), LuaError>

Source

pub fn set_metatable_by_name(&mut self, name: &[u8]) -> Result<(), LuaError>

Fetch the metatable registered under name in the registry and assign it as the metatable of the value currently on top of the stack. The fetched metatable is popped after assignment, leaving the original top value in place.

Source

pub fn get_subtable_registry(&mut self, name: &[u8]) -> Result<bool, LuaError>

Ensure registry[name] is a table; push it onto the stack. Returns true if the table already existed, false if newly created.

Source

pub fn new_userdata_typed( &mut self, _name: &[u8], size: usize, nuvalue: i32, ) -> Result<GcRef<LuaUserData>, LuaError>

Allocate a fresh full-userdata block of size bytes with nuvalue nil-initialised user-value slots, push it on the stack, and return a GcRef to it. The _name parameter is advisory — callers typically follow up with set_metatable_by_name(name) to attach the registered metatable.

C-correspondent: lua_newuserdatauv(L, size, nuvalue) (no name parameter on the C side; the Rust signature carries it for callers’ convenience).

Source§

impl LuaState

This impl block contains no public items.

LuaState methods this module depends on, implemented here by delegating to their home modules (do_.rs, debug.rs).

Source§

impl LuaState

Source

pub fn global(&self) -> Ref<'_, GlobalState>

Access the process-wide GlobalState immutably.

Returns std::cell::Ref<GlobalState> because GlobalState is held in Rc<RefCell<...>>. Call sites that do state.global().field work fine via Deref. Callers must not hold the Ref across a global_mut() call.

Source

pub fn global_mut(&self) -> RefMut<'_, GlobalState>

Access the process-wide GlobalState mutably.

Source

pub fn global_rc(&self) -> Rc<RefCell<GlobalState>>

Clone the Rc handle to the GlobalState for sharing with a new coroutine.

Used in new_thread to give the child thread access to the same GlobalState.

Source

pub fn v51_thread_lgt(&self, id: u64) -> LuaValue

Lua 5.1 global table of the thread id (lua_State.l_gt).

The main thread’s l_gt is the shared GlobalState::globals field; a coroutine’s lives in GlobalState::thread_globals under its id, seeded at creation in new_thread. A coroutine id that is missing from the map is a new_thread seeding bug, not a recoverable state.

5.1 only. Other versions never call this — they share one global table.

Source

pub fn v51_set_thread_lgt(&self, id: u64, t: LuaValue)

Set the Lua 5.1 global table of thread id (lua_State.l_gt).

Writes the main thread’s l_gt through GlobalState::globals and a coroutine’s through GlobalState::thread_globals. 5.1 only.

Source

pub fn enable_test_warning_handler(&mut self) -> Result<(), LuaError>

Enable the ltests-style warning sink used by LUA_RS_TESTC.

Source

pub fn c_calls(&self) -> u32

Return the current C-call recursion depth (lower 16 bits of n_ccalls).

Source

pub fn inc_nny(&mut self)

Increment the non-yieldable call count (upper 16 bits of n_ccalls).

Source

pub fn dec_nny(&mut self)

Decrement the non-yieldable call count.

Source

pub fn is_yieldable(&self) -> bool

Returns true if the thread can yield (no non-yieldable frames on the stack).

Source

pub fn reset_hook_count(&mut self)

Reset the hook countdown to the baseline.

Source

pub fn install_sandbox_limits( &mut self, interval: i32, instr_limit: Option<u64>, mem_limit: Option<usize>, )

Activate the per-runtime sandbox budget and arm the current thread.

Stores the budget in GlobalState (shared across every thread) and sets the count-hook mask on this thread so the dispatch loop traps every interval instructions. Coroutines created afterwards inherit the mask via preinit_thread, so metering spans all threads — closing the coroutine-escape that a per-thread closure could not. Pass None for a limit to leave that dimension unbounded.

Source

pub fn sandbox_charge_interval(&self) -> Option<LuaError>

Charge the shared budget for one count-hook interval. Returns the abort error if a limit has been crossed (and records why in tripped). Called from trace_exec on every thread, once per interval instructions — never on the budget-disabled hot path.

Source

pub fn sandbox_charge(&self, amount: u64) -> Option<LuaError>

Charge amount instructions against the runtime-wide budget and sample the memory ceiling. Returns the uncatchable abort error if a limit is crossed (recording the reason and arming the sticky aborting flag), or None otherwise. No-op when no sandbox is active.

Used both by the per-interval VM charge and by loop-heavy stdlib functions (the pattern matcher) so a single native call cannot run for longer than the instruction budget allows.

Source

pub fn sandbox_reserve(&self, additional: usize) -> Option<LuaError>

Reject a size-known-upfront allocation that would push GC-tracked memory past the ceiling, before the buffer is built. Returns the uncatchable memory abort if total_bytes() + additional exceeds the limit. Used by stdlib functions that allocate a large buffer of a computed size in one instruction (e.g. string.rep, string.pack, table.concat), where the per-instruction sandbox_check_memory would only fire after the allocation already happened.

Source

pub fn sandbox_match_step_limit(&self) -> u64

Upper bound on the work a single pattern-match call may do before it must stop and let the caller charge the budget. Equal to the remaining instruction budget when an instruction limit is active, else 0 meaning “unlimited” (preserving non-sandboxed behavior exactly).

Source

pub fn sandbox_aborting(&self) -> bool

Whether a sandbox abort is in flight. While true, protected-call builtins (pcall/xpcall/coroutine.resume) must re-raise rather than catch, so the budget trip is uncatchable. Set on trip, cleared by sandbox_reset.

Source

pub fn sandbox_instr_limited(&self) -> bool

Whether an instruction budget is active (vs. only a memory limit / none).

Source

pub fn sandbox_instr_remaining(&self) -> u64

Instructions left before the budget trips (meaningful only when sandbox_instr_limited).

Source

pub fn sandbox_instr_limit(&self) -> u64

The configured instruction limit (for computing “used”).

Source

pub fn sandbox_tripped_code(&self) -> u8

The current trip code (one of the SANDBOX_TRIP_* constants).

Source

pub fn sandbox_reset(&self)

Refill the instruction budget to its configured limit and clear the trip flag, so the same runtime can run another chunk.

Source

pub fn stack_size(&self) -> usize

Returns the current stack capacity (slots between base and stack_last).

Source

pub fn push(&mut self, val: LuaValue)

Push a value onto the stack, incrementing top.

Source

pub fn pop(&mut self) -> LuaValue

Pop the top value from the stack, decrementing top.

Source

pub fn stack_val(&self, idx: StackIdx) -> &LuaValue

Retrieve the value at the given stack index without removing it.

Source

pub fn set_stack_val(&mut self, idx: StackIdx, val: LuaValue)

Write a value to a specific stack slot.

Source

pub fn gc(&mut self) -> GcHandle<'_>

Returns a handle for GC operations (checked/forced collection, barriers) implemented in lua-gc.

Source

pub fn external_root_value(&mut self, value: LuaValue) -> ExternalRootKey

Pin a Lua value in the external root set and return its stable key.

Source

pub fn external_rooted_value(&self, key: ExternalRootKey) -> Option<LuaValue>

Read a value currently pinned by an external root key.

Source

pub fn external_replace_root( &mut self, key: ExternalRootKey, value: LuaValue, ) -> Option<LuaValue>

Replace the value pinned by an external root key.

Source

pub fn external_unroot_value( &mut self, key: ExternalRootKey, ) -> Option<LuaValue>

Remove an external root. Returns None for stale or already-removed keys.

Source

pub fn try_external_unroot_value( &mut self, key: ExternalRootKey, ) -> Result<Option<LuaValue>, BorrowMutError>

Best-effort external root removal for destructors that may run while the collector holds an immutable GlobalState borrow.

Source

pub fn new_table(&mut self) -> GcRef<LuaTable>

Create a new empty table and register it with the GC.

Source

pub fn new_table_with_sizes( &mut self, array_size: u32, hash_size: u32, ) -> Result<GcRef<LuaTable>, LuaError>

Create a fresh table with pre-sized array/hash parts.

mirrors the luaH_new + luaH_resize pair in one call so we don’t pay an extra resize path for hot construction sites.

Source

pub fn intern_str(&mut self, bytes: &[u8]) -> Result<GcRef<LuaString>, LuaError>

Intern a byte string in the global string pool.

In C, short strings (≤ LUAI_MAXSHORTLEN = 40 bytes) are interned globally via luaS_newlstr, while long strings allocate a fresh TString each call so distinct long strings keep distinct object identity (observable via string.format("%p", s)). The parser separately deduplicates long-string literals within a single chunk through luaX_newstring’s ls->h anchor table.

Short-string interning, luaS_newlstr shape: one hash of the input bytes, a bucket walk on hit (zero allocation), and an insert that reuses the same hash on miss. See the InternedStringMap doc for why this replaced the owned-key HashMap entry API.

Source

pub fn top_idx(&self) -> StackIdx

Returns the current CallInfo index (the active call frame).

Source§

impl LuaState

Source

pub fn get_at(&self, idx: impl Into<StackIdxConv>) -> LuaValue

Source

pub fn set_at(&mut self, idx: impl Into<StackIdxConv>, v: LuaValue)

Source

pub fn clear_stack_range(&mut self, start: StackIdx, end: StackIdx)

Clear stack slots in [start, end) without changing top.

Under the exact-rooting model (abe2b52) the collector traces only the live window [0, top) and, per collect, nils the dead tail above top up to the high-water mark before tracing — so a reserved-but-unused tail is normally cleared by the collector itself, not by callers. This helper exists for the call-setup paths that raise ci.top above the live top (e.g. a tail call reserving its callee frame): on those paths the gap [live_top, new_ci_top) can be reached by the per-collect dead-tail clear and the trace within a single collect off the same raised top, so it must not retain stale collectable GcRefs left by a previous frame — retaining them is the #140 use-after-free class. Callers clear the gap here so the raised top is GC-safe before any allocation can collect.

Source

pub fn get_int_at(&self, idx: impl Into<StackIdxConv>) -> Option<i64>

Hot-path accessor: returns Some(i) only when the stack slot at idx holds a LuaValue::Int(i). Returns None for any other tag (including out-of-bounds, which behaves as Nil).

ttisinteger predicate that gates the integer arithmetic fast path in lvm.c’s op_arith_aux macro. Avoids the full LuaValue clone that get_at performs — the operand is only needed for its i64 payload.

Source

pub fn get_int_pair_at( &self, rb: impl Into<StackIdxConv>, rc: impl Into<StackIdxConv>, ) -> Option<(i64, i64)>

Hot-path accessor: returns Some((a, b)) only when both stack slots at rb and rc hold integers. Equivalent to two get_int_at calls but is shaped so the arithmetic opcode dispatch arms can pattern-match the common case with a single if let.

the op_arith_aux macro.

Source

pub fn get_num_at(&self, idx: impl Into<StackIdxConv>) -> Option<f64>

Hot-path accessor: returns Some(f) when the slot holds a Float(f) or coerces an Int(i) to f64. Returns None for any other tag. No LuaValue clone — only the primitive payload travels back.

Source

pub fn get_float_at(&self, idx: impl Into<StackIdxConv>) -> Option<f64>

Hot-path accessor: returns Some(f) only when the slot holds a LuaValue::Float(f). Does NOT coerce integers; the integer branch is the caller’s responsibility. Used by opcode arms that have already ruled out the integer fast path.

Source

pub fn get_num_pair_at( &self, rb: impl Into<StackIdxConv>, rc: impl Into<StackIdxConv>, ) -> Option<(f64, f64)>

Hot-path accessor: pair version of get_num_at — returns Some((a,b)) when both slots coerce to f64 (Float or Int), None if either does not. Used by the float fast path of the arith opcodes.

Source

pub fn set_top(&mut self, idx: impl Into<StackIdxConv>)

Set top to an absolute stack index. Grows the backing stack vector (filling new slots with Nil) when idx is past stack.len(), but never clobbers existing slots between the old top and the new top — VM opcodes (Call, ForPrep, etc.) write registers via set_at and then raise top to signal “these are now live”; nil-filling here would erase the just-written values.

The setnilvalue(s2v(L->top.p++)) clear loop in lua_settop (lapi.c) is part of the public API path and lives in api::set_top instead. Callers here pass an absolute StackIdx, not the relative idx of the public lua_settop. The to-be-closed (tbclist) close path lives in func.rs, not here.

Source

pub fn set_top_idx(&mut self, idx: impl Into<StackIdxConv>)

Primitive “set top index” — just writes self.top, no nil-fill.

Callers (api.rs::set_top, raw_set, etc.) pre-nil-fill or only shrink, so this routine intentionally does no clearing or resizing. The to-be-closed (tbclist) close path lives in func.rs, not here.

Source

pub fn dec_top(&mut self)

Decrement top by 1 (saturating at zero).

Source

pub fn pop_n(&mut self, n: usize)

Source

pub fn peek_at(&mut self, idx: impl Into<StackIdxConv>) -> LuaValue

Returns the value at the given stack index without removing it.

Source

pub fn peek_top(&mut self) -> LuaValue

Returns the value just below top (the topmost live slot) without removing it.

Source

pub fn peek_string_at_top(&mut self) -> GcRef<LuaString>

Returns the topmost slot interpreted as a string. Panics if the slot is not a LuaValue::Str. Callers (e.g. luaO_pushvfstring) guarantee the value has been pushed as an interned string immediately prior.

Source

pub fn stack_at(&mut self, idx: impl Into<StackIdxConv>) -> &mut LuaValue

Mutable reference to the value at the given stack slot.

Source

pub fn stack_set_nil(&mut self, idx: impl Into<StackIdxConv>)

Writes Nil to the given stack slot.

Source

pub fn stack_resize(&mut self, size: usize) -> Result<(), LuaError>

Resizes the underlying stack vector to size slots, padding new slots with StackValue::default() (which is Nil). Returns Ok(()) on success — Vec::resize_with in Rust does not have a fallible path the way luaM_reallocvector does in C, so the Result is here for signature parity with future fallible allocators.

newsize+EXTRA_STACK, StackValue)`.

Source

pub fn stack_available(&mut self) -> usize

Source

pub fn check_stack(&mut self, n: i32) -> Result<(), LuaError>

Source

pub fn grow_stack(&mut self, n: i32, raise_error: bool) -> Result<(), LuaError>

Inherent method wrapper around the free function do_::grow_stack, preserving the historical Result<(), LuaError> signature used by check_stack and other VM call sites. The bool returned by the underlying implementation distinguishes soft failure (when raise_error is false) from success; that distinction is dropped here because every current caller passes raise_error = true and only cares about error propagation.

Source

pub fn get_ci(&self, idx: CallInfoIdx) -> &CallInfo

Source

pub fn get_ci_mut(&mut self, idx: CallInfoIdx) -> &mut CallInfo

Source

pub fn current_call_info(&self) -> &CallInfo

Source

pub fn current_call_info_mut(&mut self) -> &mut CallInfo

Source

pub fn current_ci_idx(&self) -> CallInfoIdx

Source

pub fn call_stack_mut(&mut self) -> &mut Vec<CallInfo>

Source

pub fn next_ci(&mut self) -> Result<CallInfoIdx, LuaError>

Source

pub fn note_lua_tailcall(&mut self, ci: CallInfoIdx)

Records that a Lua tail call reused the frame at ci, so the 5.1 debug.getstack level walk can synthesize the (tail call) frames the 5.1 debug model exposes. Gated to 5.1: 5.2+ dropped synthetic tail frames for the istailcall flag and never read tailcalls, so on those versions this is a single version compare and return — the hot tail-call path is otherwise byte-identical.

Source

pub fn prev_ci(&self, idx: CallInfoIdx) -> Option<CallInfoIdx>

Source

pub fn get_prev_ci(&self, idx: CallInfoIdx) -> Option<&CallInfo>

Source

pub fn is_base_ci(&self, idx: CallInfoIdx) -> bool

Source

pub fn is_current_ci(&self, idx: CallInfoIdx) -> bool

Source

pub fn ci_next_func(&self, idx: CallInfoIdx) -> StackIdx

Source

pub fn ci_top(&self, idx: CallInfoIdx) -> StackIdx

Source

pub fn ci_trap(&mut self, idx: CallInfoIdx) -> bool

Hot-loop trap read: (callstatus & CIST_TRAP) != 0, one mask with no enum-discriminant branch. A C frame never has CIST_TRAP set, so this returns false for C frames identically to the pre-flatten fallback, without needing a frame-kind branch — that is the whole point of T2-C2.

Source

pub fn ci_savedpc(&self, idx: CallInfoIdx) -> u32

Source

pub fn set_ci_savedpc(&mut self, idx: CallInfoIdx, pc: u32)

Source

pub fn set_ci_previous(&mut self, idx: CallInfoIdx)

Source

pub fn ci_previous(&self, idx: CallInfoIdx) -> Option<CallInfoIdx>

Source

pub fn ci_adjust_func(&mut self, idx: CallInfoIdx, delta: i32)

Source

pub fn ci_base(&self, idx: CallInfoIdx) -> StackIdx

Source

pub fn ci_is_fresh(&self, idx: CallInfoIdx) -> bool

Source

pub fn ci_lua_closure(&self, idx: CallInfoIdx) -> Option<GcRef<LuaLClosure>>

Source

pub fn ci_nextraargs(&self, idx: CallInfoIdx) -> i32

Source

pub fn ci_nres(&self, idx: CallInfoIdx) -> i32

Source

pub fn ci_nres_set(&mut self, idx: CallInfoIdx, n: i32)

Source

pub fn ci_nresults(&self, idx: CallInfoIdx) -> i32

Source

pub fn ci_prev_instruction(&self, idx: CallInfoIdx) -> Instruction

Source

pub fn ci_prev2_instruction(&self, idx: CallInfoIdx) -> Instruction

Source

pub fn ci_skip_next_instruction(&mut self, idx: CallInfoIdx)

Source

pub fn ci_step_pc_back(&mut self, idx: CallInfoIdx)

Source

pub fn get_ci_pcrel(&mut self, idx: CallInfoIdx) -> u32

Source

pub fn get_ci_u2_funcidx(&mut self, idx: CallInfoIdx) -> i32

Source

pub fn get_ci_u2_nres(&mut self, idx: CallInfoIdx) -> i32

Source

pub fn get_ci_u2_nyield(&mut self, idx: CallInfoIdx) -> i32

Source

pub fn get_ci_vararg_info(&mut self, idx: CallInfoIdx) -> (bool, i32, i32)

Source

pub fn get_ci_lua_proto_numparams(&mut self, idx: CallInfoIdx) -> u8

Source

pub fn set_ci_u2_nres(&mut self, idx: CallInfoIdx, n: i32)

Source

pub fn set_ci_u2_nyield(&mut self, idx: CallInfoIdx, n: i32)

Source

pub fn set_ci_transfer_info( &mut self, idx: CallInfoIdx, ftransfer: u16, ntransfer: u16, )

Source

pub fn shrink_ci(&mut self)

Source

pub fn check_c_stack(&mut self) -> Result<(), LuaError>

Source

pub fn status(&mut self) -> LuaStatus

Source

pub fn errfunc(&mut self) -> isize

Source

pub fn old_pc(&mut self) -> u32

Source

pub fn set_old_pc(&mut self, pc: u32)

Source

pub fn set_oldpc(&mut self, pc: u32)

Source

pub fn _hook_call_noargs(&mut self)

Source

pub fn hook(&self) -> Option<&Box<dyn FnMut(&mut LuaState, &LuaDebug)>>

Source

pub fn has_hook(&mut self) -> bool

Source

pub fn hook_count(&mut self) -> i32

Source

pub fn set_hook_count(&mut self, n: i32)

Source

pub fn hook_mask(&self) -> u8

Source

pub fn set_hook_mask(&mut self, m: u8)

Source

pub fn base_hook_count(&self) -> i32

Source

pub fn set_base_hook_count(&mut self, n: i32)

Source

pub fn set_hook(&mut self, h: Option<Box<dyn FnMut(&mut LuaState, &LuaDebug)>>)

Source

pub fn call_hook_event(&mut self, event: i32, line: i32) -> Result<(), LuaError>

Fire a count or line hook on the currently executing frame.

C-Lua’s luaG_traceexec is the sole caller of luaD_hook for count and line events, and it relies on L->ci being the same Lua frame after the hook as before it: the bytecode dispatch loop in luaV_execute reads L->ci (via trace_exec) on the next instruction and writes its savedpc, which is only valid on a Lua frame. C maintains that invariant implicitly — the unprotected lua_call inside the hook restores L->ci via luaD_poscall on success, and on a hook error it longjmps straight to the nearest protected boundary, which resets L->ci, so a corrupted ci never re-enters the dispatch loop.

Our port reports hook-callback errors through a different path that can leave self.ci advanced to the hook’s own (C) frame instead of unwinding it, so the invariant the dispatch loop depends on would be broken. Saving self.ci here and restoring it after the hook reasserts exactly the invariant C guarantees, so the next trace_exec writes savedpc on the Lua frame it is actually executing rather than panicking on a C frame.

Source

pub fn registry_value(&self) -> LuaValue

Source

pub fn registry_get(&self, key: usize) -> LuaValue

Source

pub fn new_string(&mut self, bytes: &[u8]) -> Result<GcRef<LuaString>, LuaError>

Source

pub fn new_proto(&mut self) -> GcRef<LuaProto>

Allocate a new Lua function prototype.

The caller is expected to populate fields on the returned value while it has no other outstanding references (immediately after allocation).

Source

pub fn new_lclosure( &mut self, proto: GcRef<LuaProto>, nupvals: usize, ) -> GcRef<LuaLClosure>

Allocate a Lua-side closure (compiled function + upvalue slots).

Source

pub fn new_upval_closed(&mut self, v: LuaValue) -> GcRef<UpVal>

Allocate a closed upvalue holding the given value.

Source

pub fn new_upval_open( &mut self, thread_id: u64, level: StackIdx, ) -> GcRef<UpVal>

Allocate an open upvalue referring to a thread’s stack slot.

Source

pub fn intern_or_create_str( &mut self, bytes: &[u8], ) -> Result<GcRef<LuaString>, LuaError>

Mirrors luaS_newlstr: short strings are interned globally so equal content shares a single TString; long strings (> LUAI_MAXSHORTLEN = 40) always create a fresh TString without interning. This is what lets string.format("%p", "long" .. "concat") differ from a same-content literal — concat must produce a new object even when the literal already lives in the lexer’s constant pool.

Source

pub fn new_userdata( &mut self, size: usize, nuvalue: usize, ) -> Result<GcRef<LuaUserData>, LuaError>

Allocates a full userdata with size payload bytes and nuvalue nil user-value slots, returning the GcRef without pushing it. Mirrors C’s lua_newuserdatauv allocation step; the untyped counterpart of Self::new_userdata_typed (no __name-carrying metatable is attached). Callers such as api::new_userdata_uv push the result and run the GC step.

Source

pub fn register_c_function( &mut self, f: fn(&mut LuaState) -> Result<usize, LuaError>, dedup: bool, ) -> usize

Registers a C function pointer f in the per-state c_functions table and returns its LuaCFnPtr index. LuaClosure::LightC/LuaCClosure carry this index rather than a raw pointer because lua_types cannot reference LuaState. When dedup is set (upvalue-less light C functions) an already-registered identical f is reused; otherwise a fresh slot is always allocated, since closures with upvalues must not share identity.

Source

pub fn new_c_closure( &mut self, f: fn(&mut LuaState) -> Result<usize, LuaError>, n: i32, ) -> Result<LuaClosure, LuaError>

Creates a C closure over f with n (nil-initialised) upvalue slots and returns it without pushing. Mirrors lua_pushcclosure’s object step: n == 0 yields a light C function, n > 0 a full C closure. The stack filling of upvalues is the caller’s responsibility (see api::push_cclosure).

n is validated against 0..=MAX_UPVAL before anything is registered, so an out-of-range count errors without polluting the c_functions table.

Source

pub fn push_closure( &mut self, proto_idx: usize, ci: CallInfoIdx, base: StackIdx, ra: StackIdx, ) -> Result<(), LuaError>

Source

pub fn new_tbc_upval(&mut self, idx: StackIdx) -> Result<(), LuaError>

Source

pub fn upvalue_get(&self, cl: &GcRef<LuaLClosure>, n: usize) -> LuaValue

Read an open or closed upvalue.

Closed upvalues own their value and read trivially. Open upvalues point at a stack slot on the home thread that captured them.

Resolution order for an open upvalue whose home is not the current thread:

  1. If the home thread is registered in GlobalState::threads and its RefCell is currently borrowable, read straight from its stack. This is the path used when the main thread reads a closure created inside a now-suspended coroutine, or when one coroutine reads an upvalue homed on a sibling suspended coroutine.
  2. Otherwise fall back to GlobalState::cross_thread_upvals. This is the path used while inside a coroutine.resume: the parent thread’s LuaState is held by an outer &mut and is not reachable through any Rc<RefCell<_>>, so aux_resume snapshots the parent’s open upvalues into the mirror across the resume boundary.
Source

pub fn upvalue_set( &mut self, cl: &GcRef<LuaLClosure>, n: usize, val: LuaValue, ) -> Result<(), LuaError>

Write an open or closed upvalue.

Mirrors [upvalue_get]: open upvalues homed on the current thread write through self.stack. For cross-thread open upvalues, the home thread’s stack is written directly when its RefCell is borrowable, otherwise the write lands in GlobalState::cross_thread_upvals (the active-resume case where the home thread is borrow-locked further up the call stack).

Source

pub fn protected_call_raw( &mut self, func: StackIdx, nresults: i32, errfunc: StackIdx, ) -> Result<(), LuaError>

Source

pub fn protected_parser( &mut self, z: ZIO, name: &[u8], mode: Option<&[u8]>, ) -> LuaStatus

Source

pub fn do_call(&mut self, func: StackIdx, nresults: i32) -> Result<(), LuaError>

Source

pub fn do_call_no_yield( &mut self, func: StackIdx, nresults: i32, ) -> Result<(), LuaError>

Source

pub fn call_no_yield( &mut self, func: StackIdx, nresults: i32, ) -> Result<(), LuaError>

Source

pub fn call_at(&mut self, func: StackIdx, nresults: i32) -> Result<(), LuaError>

Source

pub fn call_known_c_at( &mut self, func: StackIdx, nresults: i32, ) -> Result<bool, LuaError>

Source

pub fn precall( &mut self, func: StackIdx, nresults: i32, ) -> Result<Option<CallInfoIdx>, LuaError>

Source

pub fn pretailcall( &mut self, ci: CallInfoIdx, func: StackIdx, narg1: i32, delta: i32, ) -> Result<i32, LuaError>

Source

pub fn poscall<N>(&mut self, ci: CallInfoIdx, nres: N) -> Result<(), LuaError>
where N: TryInto<i32>, <N as TryInto<i32>>::Error: Debug,

Source

pub fn adjust_results(&mut self, nresults: i32)

Source

pub fn adjust_varargs( &mut self, ci: CallInfoIdx, nfixparams: i32, cl: &GcRef<LuaLClosure>, ) -> Result<(), LuaError>

Source

pub fn get_varargs( &mut self, ci: CallInfoIdx, ra: StackIdx, n: i32, ) -> Result<i32, LuaError>

Source

pub fn close_upvals(&mut self, level: StackIdx) -> Result<(), LuaError>

Source

pub fn close_upvals_status( &mut self, level: StackIdx, _status: i32, ) -> Result<(), LuaError>

Source

pub fn close_upvals_from_base( &mut self, ci: CallInfoIdx, ) -> Result<(), LuaError>

Source

pub fn arith_op( &mut self, op: i32, p1: &LuaValue, p2: &LuaValue, ) -> Result<LuaValue, LuaError>

Source

pub fn concat(&mut self, n: i32) -> Result<(), LuaError>

Source

pub fn less_than( &mut self, l: &LuaValue, r: &LuaValue, ) -> Result<bool, LuaError>

Source

pub fn less_equal( &mut self, l: &LuaValue, r: &LuaValue, ) -> Result<bool, LuaError>

Source

pub fn equal_obj( &self, _ctx: Option<&LuaValue>, l: &LuaValue, r: &LuaValue, ) -> bool

Source

pub fn equal_obj_with_tm( &mut self, l: &LuaValue, r: &LuaValue, ) -> Result<bool, LuaError>

Source

pub fn obj_len(&mut self, v: &LuaValue) -> Result<LuaValue, LuaError>

Source

pub fn obj_to_string(&mut self, idx: i32) -> Result<GcRef<LuaString>, LuaError>

Source

pub fn coerce_to_string( &mut self, idx: StackIdx, ) -> Result<GcRef<LuaString>, LuaError>

Source

pub fn str_to_num(&mut self, s: &[u8]) -> Option<(LuaValue, usize)>

Parses s as a Lua number, returning (value, consumed) on success.

object::str2num is number-model-blind and yields an integer whenever the text parses as one. The float-only versions (5.1/5.2) have no integer subtype, so a string coercion there is normalised to a float: otherwise tonumber("10") would carry an integer payload that diverges from the reference on any path that inspects the subtype.

Source

pub fn fast_get( &mut self, t: &LuaValue, k: &LuaValue, ) -> Result<Option<LuaValue>, LuaError>

Source

pub fn fast_get_int( &mut self, t: &LuaValue, k: i64, ) -> Result<Option<LuaValue>, LuaError>

Source

pub fn fast_get_short_str( &mut self, t: &LuaValue, k: &LuaValue, ) -> Result<Option<LuaValue>, LuaError>

Source

pub fn fast_tm_table( &mut self, t: Option<&GcRef<LuaTable>>, tm: TagMethod, ) -> LuaValue

Source

pub fn fast_tm_ud(&mut self, u: &GcRef<LuaUserData>, tm: TagMethod) -> LuaValue

Source

pub fn table_get_with_tm( &mut self, t: &LuaValue, k: &LuaValue, ) -> Result<LuaValue, LuaError>

Source

pub fn table_set_with_tm( &mut self, t: &LuaValue, k: LuaValue, v: LuaValue, ) -> Result<(), LuaError>

Set t[k] = v with __newindex metamethod awareness.

Fast path: when the table has no metatable, __newindex can never fire, so the existence check via fast_get is pure waste — try_raw_set handles both “key exists” and “key absent” cases via a single lookup internally. Removing the fast_get halves the lookups per set on the metamethod-free path (table.remove/insert hot loops, most user code).

The GC backward barrier is invoked before the store (with &v) instead of after; the barrier only inspects the value’s color, not its location, so the order is semantically equivalent to upstream C-Lua and lets us move v straight into table_raw_set without the extra v.clone() that the post-store ordering forced.

Source

pub fn table_raw_set( &mut self, t: &LuaValue, k: LuaValue, v: LuaValue, ) -> Result<(), LuaError>

Source

pub fn table_array_set( &mut self, t: &LuaValue, idx: usize, v: LuaValue, ) -> Result<(), LuaError>

Source

pub fn table_ensure_array( &mut self, t: &LuaValue, n: usize, ) -> Result<(), LuaError>

Source

pub fn table_length(&mut self, t: &LuaValue) -> Result<i64, LuaError>

Source

pub fn table_metatable(&mut self, v: &LuaValue) -> Option<GcRef<LuaTable>>

Source

pub fn table_resize( &mut self, t: &GcRef<LuaTable>, na: usize, nh: usize, ) -> Result<(), LuaError>

Source

pub fn table_getn(&self, t: &GcRef<LuaTable>) -> i64

Source

pub fn try_bin_tm( &mut self, p1: &LuaValue, p1_idx: Option<StackIdx>, p2: &LuaValue, p2_idx: Option<StackIdx>, res: StackIdx, tm: TagMethod, ) -> Result<(), LuaError>

Source

pub fn try_bin_i_tm( &mut self, p1: &LuaValue, p1_idx: Option<StackIdx>, imm: i64, flip: bool, res: StackIdx, tm: TagMethod, ) -> Result<(), LuaError>

Source

pub fn try_bin_assoc_tm( &mut self, p1: &LuaValue, p1_idx: Option<StackIdx>, p2: &LuaValue, p2_idx: Option<StackIdx>, flip: bool, res: StackIdx, tm: TagMethod, ) -> Result<(), LuaError>

Source

pub fn try_concat_tm( &mut self, _p1: &LuaValue, _p2: &LuaValue, ) -> Result<(), LuaError>

Source

pub fn call_tm( &mut self, f: LuaValue, p1: &LuaValue, p2: &LuaValue, p3: &LuaValue, ) -> Result<(), LuaError>

Source

pub fn call_tm_res( &mut self, f: LuaValue, p1: &LuaValue, p2: &LuaValue, res: StackIdx, ) -> Result<(), LuaError>

Source

pub fn call_tm_res_bool( &mut self, f: LuaValue, p1: &LuaValue, p2: &LuaValue, ) -> Result<bool, LuaError>

Source

pub fn call_order_tm( &mut self, p1: &LuaValue, p2: &LuaValue, tm: TagMethod, ) -> Result<bool, LuaError>

Source

pub fn call_order_i_tm( &mut self, p1: &LuaValue, v2: i64, flip: bool, isfloat: bool, tm: TagMethod, ) -> Result<bool, LuaError>

Source

pub fn proto_code(&self, cl: &GcRef<LuaLClosure>, pc: u32) -> Instruction

Source

pub fn proto_const(&self, cl: &GcRef<LuaLClosure>, idx: usize) -> LuaValue

Source

pub fn proto_const_int( &self, cl: &GcRef<LuaLClosure>, idx: usize, ) -> Option<i64>

Hot-path accessor: returns Some(i) only when the constant pool entry at idx is an Int. Avoids the full LuaValue clone that proto_const performs.

arithmetic opcode macros (op_arithK).

Source

pub fn proto_const_num( &self, cl: &GcRef<LuaLClosure>, idx: usize, ) -> Option<f64>

Hot-path accessor: returns Some(f) for Float(f) or Int(i) (coerced) constants. Avoids the full LuaValue clone. Used by the float fast path of OP_ADDK/OP_SUBK/OP_MULK/OP_DIVK/OP_POWK.

Source

pub fn get_proto_instr(&self, ci: CallInfoIdx, pc: u32) -> Instruction

Source

pub fn trace_call(&mut self, _idx: CallInfoIdx) -> Result<bool, LuaError>

flag as bool (C returns int 0/1).

The C function reads L->ci directly, so the _idx argument is unused; the VM passes its locally tracked ci for symmetry with trace_exec.

Source

pub fn trace_exec( &mut self, _idx: CallInfoIdx, pc: u32, ) -> Result<bool, LuaError>

returning bool for the trap flag. _idx is unused for the same reason as trace_call; pc is the 0-based index of the next instruction.

Source

pub fn hook_call(&mut self, idx: CallInfoIdx) -> Result<(), LuaError>

Fires the call hook for the frame at idx.

On Lua 5.1 a tail call reuses the caller’s frame but still fires an ordinary "call" hook for the callee (the synthetic call event is on the return side, as a "tail return"). 5.2+ instead report the call as a "tail call" event, which do_::hookcall derives from the CIST_TAIL callstatus bit. To get the 5.1 naming without disturbing CIST_TAIL (which debug.getinfo still reads to report what == "tail"), the bit is masked off across the hookcall call and restored afterwards, so on 5.1 the event is always LUA_HOOKCALL. 5.2+ takes the unchanged delegation.

Source

pub fn gc_trace_bound(&self) -> usize

The stack prefix the GC must treat as live: [0 .. gc_trace_bound()).

C’s traversethread walks exactly [stack .. top) (lgc.c). The companion invariant is that top covers every live slot at every point a collect can run: C functions keep top exact at all times, and lvm.c’s Protect sites raise it (savestate: top = ci->top) before any mid-opcode operation that can collect. Checkpoints whose C original runs under Protect must therefore do the same top fixup at the call site (e.g. get_varargs). Widening the bound here to ci.top instead was tried and rejected: every suspended frame’s reserved slice stays traced forever, and the over-retention drives the generational pacer into permanent re-collection (db.lua’s line-hook section went from seconds to timeout).

Source

pub fn clear_dead_stack_tail(&mut self)

Nil this thread’s dead stack slice [gc_trace_bound() .. stack.len()). C clears the equivalent slice in traversethread’s atomic phase (lgc.c: setnilvalue from top to stack_last + EXTRA_STACK). Without the clear, a slot that was above the bound at one collect (its object swept) and drifts back under a raised bound later feeds a dangling GcRef to the marker — #140 bug B.

Source

pub fn gc_clear_dead_stack_tails(&mut self)

Clear the dead stack slice of this thread and of every registered coroutine whose state is borrowable. Threads held by a resume chain or a debug-API guard are rooted via suspended_parent_stacks snapshots and skipped here; their tails are cleared at their next reachable collect. Call before any collection runs (C parity: traversethread’s atomic clear).

Source

pub fn gc_pre_collect_clear(&mut self)

gc_clear_dead_stack_tails gated on would_collect — the one-line companion for call sites that invoke gc().check_step() directly. Zero cost when no collection is due.

Source

pub fn gc_check_step(&mut self)

Source

pub fn gc_cond_step(&mut self)

Source

pub fn gc_barrier_back(&mut self, t: &(dyn Any + 'static), v: &LuaValue)

Source

pub fn gc_value_barrier_back(&mut self, t: &LuaValue, v: &LuaValue)

Source

pub fn gc_table_barrier_back(&mut self, t: &GcRef<LuaTable>, v: &LuaValue)

Source

pub fn gc_barrier_upval(&mut self, uv: &GcRef<UpVal>, v: &LuaValue)

Source

pub fn is_main_thread(&mut self) -> bool

Compares GlobalState::current_thread_id against main_thread_id; false while a coroutine resume has swapped current_thread_id to the child’s id.

Source

pub fn obj_type_name<'v>(&self, v: &'v LuaValue) -> Cow<'static, [u8]>

Source

pub fn full_type_name(&mut self, v: &LuaValue) -> Result<Vec<u8>, LuaError>

Source

pub fn emit_warning(&mut self, _msg: &[u8], _to_cont: bool)

Trait Implementations§

Source§

impl Collectable for LuaState

Source§

impl Debug for LuaState

Source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), Error>

Formats the value using the given formatter. Read more
Source§

impl LuaStateStubExt for LuaState

Source§

fn load_with_reader<F, M>( &mut self, reader: F, name: &[u8], mode: &M, ) -> Result<bool, LuaError>
where F: FnMut(&mut LuaState) -> Result<Option<Vec<u8>>, LuaError> + 'static, M: AsRef<[u8]> + ?Sized,

Forward a state-aware reader straight to lua_vm::api::load, which pulls chunks lazily during the parse.

reader (e.g. generic_reader, which calls a Lua function per chunk) is the reentrant ChunkReader the lexer drives byte by byte. C-Lua streams chunks through lua_load the same way, so an early syntax error stops the reader instead of draining it to EOF — the loader pulls only what the parser actually needs. A reader error propagates into the protected parse and surfaces as a failed load with the error on the stack, matching C’s lua_load.

Source§

fn hook_is_set(&mut self) -> bool

Approximate “is a debug hook installed?” using the hook event mask. lua_sethook clears the mask whenever the hook is uninstalled, so a non-zero mask is equivalent to a non-NULL L->hook for the debug.gethook call site. Avoids invoking state.hook(), which is still a Phase-B todo! on LuaState.

Source§

fn hook_is_internal_lua_hook(&mut self) -> bool

Hooks installed through the debug library use the Lua hook trampoline and store the real Lua callback in registry[HOOKKEY].

Source§

fn close(&mut self)

lua_close(L) destroys a Lua state. In Rust the state’s resources are released by Drop when the owning value goes out of scope, so the in-place &mut self form is a no-op. The consuming free function lua_vm::state::close(state) is reserved for the top-level shutdown path in lua-cli.

Source§

fn set_hook_full( &mut self, f: Option<lua_CFunction>, mask: u32, count: i32, ) -> Result<(), LuaError>

Install (or clear) a debug hook on this thread. C: lua_sethook (ldebug.c).

The LuaStateStubExt signature uses lua_CFunction (the stdlib C-function shape: fn(&mut LuaState) -> Result<usize, LuaError>) for f, whereas the canonical lua_vm::debug::set_hook takes a Box<dyn FnMut(&mut LuaState, &LuaDebug)> (a true Lua hook, which has access to the active lua_Debug). To bridge the two, an installed lua_CFunction is wrapped in a trampoline closure that calls it with state and discards both the activation record and the Result<usize, LuaError> (a hook’s return value is ignored by C-Lua).

Source§

fn write_output(&mut self, msg: &[u8]) -> Result<(), LuaError>

Write msg to the host’s standard output stream. C: lua_writestring (fwrite(s, 1, l, stdout)).

Delegates to the canonical inherent LuaState::write_output. UFCS is used to disambiguate from the trait method (this method) which would otherwise recurse.

Source§

fn table_set_i(&mut self, idx: i32, n: i64) -> Result<(), LuaError>

t[n] = v, where t is the value at idx and v is popped from the stack top. Honours __newindex.

Source§

fn new_userdata_typed( &mut self, name: &[u8], size: usize, nuvalue: i32, ) -> Result<GcRef<LuaUserData>, LuaError>

Allocate a fresh full-userdata, push it on the stack, and return a GcRef to it. name is advisory (callers typically follow up with set_metatable_by_name(name)).

C-correspondent: lua_newuserdatauv(L, size, nuvalue) plus the auxiliary luaL_setmetatable pattern. The Rust signature carries name for caller convenience as documented on the inherent method.

Source§

fn require_lib( &mut self, name: &[u8], openf: lua_CFunction, glb: bool, ) -> Result<(), LuaError>

Source§

fn get_field(&mut self, idx: i32, k: &[u8]) -> Result<LuaType, LuaError>

Source§

fn abs_index(&mut self, idx: i32) -> i32

Source§

fn push_value(&mut self, idx: i32) -> Result<(), LuaError>

Source§

fn set_field(&mut self, idx: i32, k: &[u8]) -> Result<(), LuaError>

Source§

fn set_global(&mut self, name: &[u8]) -> Result<(), LuaError>

Source§

fn to_boolean(&mut self, idx: i32) -> bool

Source§

fn top(&mut self) -> i32

Source§

fn push_c_function(&mut self, f: lua_CFunction) -> Result<(), LuaError>

Source§

fn push_bytes(&mut self, s: &[u8]) -> Result<(), LuaError>

Source§

fn call(&mut self, nargs: i32, nresults: i32) -> Result<(), LuaError>

Source§

fn call_k( &mut self, nargs: i32, nresults: i32, ctx: isize, k: Option<fn(&mut LuaState, i32, isize) -> Result<usize, LuaError>>, ) -> Result<(), LuaError>

Source§

fn remove(&mut self, idx: i32) -> Result<(), LuaError>

Source§

fn get_upvalue( &mut self, fidx: i32, n: i32, ) -> Result<Option<Vec<u8>>, LuaError>

Source§

fn set_upvalue( &mut self, fidx: i32, n: i32, ) -> Result<Option<Vec<u8>>, LuaError>

Source§

fn load( &mut self, chunk: &[u8], name: &[u8], mode: Option<&[u8]>, ) -> Result<bool, LuaError>

Source§

fn push_globals(&mut self) -> Result<(), LuaError>

Source§

fn set_funcs( &mut self, funcs: &[(&[u8], lua_CFunction)], nup: i32, ) -> Result<(), LuaError>

Source§

fn arg_to_bool(&mut self, arg: i32) -> bool

Source§

fn value_at(&mut self, idx: i32) -> LuaValue

Source§

fn check_arg_type(&mut self, arg: i32, t: LuaType) -> Result<(), LuaError>

Source§

fn opt_arg_string(&mut self, arg: i32, def: &[u8]) -> Result<Vec<u8>, LuaError>

Source§

fn get_metafield(&mut self, idx: i32, name: &[u8]) -> Result<LuaType, LuaError>

Source§

fn table_get_i(&mut self, idx: i32, n: i64) -> Result<LuaType, LuaError>

Source§

fn table_get_i_value( &mut self, t: &LuaValue, n: i64, ) -> Result<LuaType, LuaError>

Source§

fn table_set_i_value(&mut self, t: &LuaValue, n: i64) -> Result<(), LuaError>

Source§

fn compare_lt(&mut self, idx1: i32, idx2: i32) -> Result<bool, LuaError>

Source§

fn check_arg_any(&mut self, arg: i32) -> Result<(), LuaError>

Source§

fn check_arg_integer(&mut self, arg: i32) -> Result<i64, LuaError>

Source§

fn check_arg_string(&mut self, arg: i32) -> Result<Vec<u8>, LuaError>

Source§

fn check_arg_number(&mut self, arg: i32) -> Result<f64, LuaError>

Source§

fn check_number(&mut self, arg: i32) -> Result<f64, LuaError>

Source§

fn check_integer(&mut self, arg: i32) -> Result<i64, LuaError>

Source§

fn check_any(&mut self, arg: i32) -> Result<(), LuaError>

Source§

fn opt_arg_integer(&mut self, arg: i32, def: i64) -> Result<i64, LuaError>

Source§

fn opt_integer(&mut self, arg: i32, def: i64) -> Result<i64, LuaError>

Source§

fn opt_number(&mut self, arg: i32, def: f64) -> Result<f64, LuaError>

Source§

fn opt_arg_string_bytes(&mut self, arg: i32) -> Result<Vec<u8>, LuaError>

Source§

fn opt_arg_lstring( &mut self, arg: i32, def: Option<&[u8]>, ) -> Result<Option<Vec<u8>>, LuaError>

Source§

fn check_arg_option( &mut self, arg: i32, def: Option<&[u8]>, lst: &[&[u8]], ) -> Result<usize, LuaError>

Source§

fn arg(&mut self, n: i32) -> LuaValue

Source§

fn type_at(&mut self, idx: i32) -> LuaType

Source§

fn type_name(&mut self, t: LuaType) -> &'static [u8]

Source§

fn type_name_at(&mut self, idx: i32) -> &'static [u8]

Source§

fn is_integer(&mut self, idx: i32) -> bool

Source§

fn is_number(&mut self, idx: i32) -> bool

Source§

fn is_none_or_nil(&mut self, idx: i32) -> bool

Source§

fn to_integer_x(&mut self, idx: i32) -> Option<i64>

Source§

fn to_number_x(&mut self, idx: i32) -> Option<f64>

Source§

fn to_integer(&mut self, idx: i32) -> Option<i64>

Source§

fn to_integer_opt(&mut self, idx: i32) -> Option<i64>

Source§

fn to_number(&mut self, idx: i32) -> Option<f64>

Source§

fn to_lua_string(&mut self, idx: i32) -> Option<GcRef<LuaString>>

Source§

fn to_lua_string_bytes(&mut self, idx: i32) -> Option<Vec<u8>>

Source§

fn to_lua_string_len(&mut self, idx: i32) -> Option<usize>

Source§

fn to_bytes(&mut self, idx: i32) -> Option<Vec<u8>>

Source§

fn to_bytes_at(&mut self, idx: i32) -> Option<Vec<u8>>

Source§

fn raw_equal(&mut self, idx1: i32, idx2: i32) -> Result<bool, LuaError>

Source§

fn raw_geti(&mut self, idx: i32, n: i64) -> Result<LuaType, LuaError>

Source§

fn raw_get_i(&mut self, idx: i32, n: i64) -> Result<LuaType, LuaError>

Source§

fn raw_seti(&mut self, idx: i32, n: i64) -> Result<(), LuaError>

Source§

fn raw_set_i(&mut self, idx: i32, n: i64) -> Result<(), LuaError>

Source§

fn raw_len(&mut self, idx: i32) -> i64

Source§

fn get_i(&mut self, idx: i32, n: i64) -> Result<LuaType, LuaError>

Source§

fn get_metatable(&mut self, idx: i32) -> Result<bool, LuaError>

Source§

fn set_metatable(&mut self, idx: i32) -> Result<(), LuaError>

Source§

fn compare( &mut self, idx1: i32, idx2: i32, op: CompareOp, ) -> Result<bool, LuaError>

Source§

fn protected_call( &mut self, nargs: i32, nresults: i32, msgh: i32, ) -> Result<(), LuaError>

Source§

fn protected_call_k( &mut self, nargs: i32, nresults: i32, msgh: i32, ctx: isize, k: Option<fn(&mut LuaState, i32, isize) -> Result<usize, LuaError>>, ) -> Result<(), LuaError>

Source§

fn push_value_at(&mut self, idx: i32) -> Result<(), LuaError>

Source§

fn push_thread(&mut self) -> Result<bool, LuaError>

Source§

fn push_cclosure(&mut self, f: lua_CFunction, n: i32) -> Result<(), LuaError>

Source§

fn push_c_closure(&mut self, f: lua_CFunction, n: i32) -> Result<(), LuaError>

Source§

fn push_lstring(&mut self, s: &[u8]) -> Result<(), LuaError>

Source§

fn push_string(&mut self, s: &[u8]) -> Result<(), LuaError>

Source§

fn get_top(&mut self) -> i32

Source§

fn stack_top(&mut self) -> i32

Source§

fn top_count(&mut self) -> i32

Source§

fn check_stack_space(&mut self, n: i32) -> bool

Source§

fn rotate(&mut self, idx: i32, n: i32) -> Result<(), LuaError>

Source§

fn insert(&mut self, idx: i32) -> Result<(), LuaError>

Source§

fn copy_value(&mut self, from: i32, to: i32) -> Result<(), LuaError>

Source§

fn replace(&mut self, idx: i32) -> Result<(), LuaError>

Source§

fn len_op(&mut self, idx: i32) -> Result<(), LuaError>

Source§

fn table_next(&mut self, idx: i32) -> Result<bool, LuaError>

Source§

fn create_table(&mut self, narr: i32, nrec: i32) -> Result<(), LuaError>

Source§

fn to_userdata(&mut self, idx: i32) -> Option<GcRef<LuaUserData>>

Source§

fn to_light_userdata(&mut self, idx: i32) -> Option<*mut c_void>

Source§

fn to_thread(&mut self, idx: i32) -> Option<GcRef<LuaThread>>

Source§

fn to_thread_at(&mut self, idx: i32) -> Option<GcRef<LuaThread>>

Source§

fn len_at(&mut self, idx: i32) -> i64

Source§

fn length_at(&mut self, idx: i32) -> Result<i64, LuaError>

Source§

fn peek_bytes(&mut self, idx: i32) -> Option<Vec<u8>>

Source§

fn to_string_coerced(&mut self, idx: i32) -> Option<Vec<u8>>

Source§

fn raw_get(&mut self, idx: i32) -> Result<LuaType, LuaError>

Source§

fn raw_set(&mut self, idx: i32) -> Result<(), LuaError>

Source§

fn is_c_function_at(&mut self, idx: i32) -> bool

Source§

fn type_name_str_at(&mut self, idx: i32) -> &'static [u8]

Source§

fn push_fstring(&mut self, args: Arguments<'_>) -> Result<(), LuaError>

Source§

fn arith(&mut self, op: ArithOp) -> Result<(), LuaError>

Source§

fn lua_version(&mut self) -> f64

Source§

fn push_fail(&mut self) -> Result<(), LuaError>

Source§

fn push_registry(&mut self) -> Result<(), LuaError>

Source§

fn push_upvalue(&mut self, idx: i32) -> Result<(), LuaError>

Source§

fn pop_bytes(&mut self) -> Vec<u8>

Source§

fn push_where(&mut self, level: i32) -> Result<(), LuaError>

Source§

fn where_error(&mut self, level: i32, msg: &[u8]) -> LuaError

Source§

fn registry_get(&mut self, key: &[u8]) -> Result<LuaType, LuaError>

Source§

fn get_field_registry(&mut self, name: &[u8]) -> Result<LuaType, LuaError>

Source§

fn get_registry_field(&mut self, name: &[u8]) -> Result<LuaType, LuaError>

Source§

fn get_or_create_registry_subtable( &mut self, name: &[u8], ) -> Result<bool, LuaError>

Source§

fn registry_set(&mut self, key: &[u8]) -> Result<(), LuaError>

Source§

fn check_stack_growth(&mut self, n: i32) -> bool

Source§

fn ensure_stack<S: AsRef<[u8]> + ?Sized>( &mut self, n: i32, msg: &S, ) -> Result<(), LuaError>

Source§

fn push_copy(&mut self, idx: i32) -> Result<(), LuaError>

Source§

fn as_bytes(&mut self, idx: i32) -> Option<Vec<u8>>

Source§

fn as_bytes_or_coerce(&mut self, idx: i32) -> Option<Vec<u8>>

Source§

fn thread_status(&mut self) -> LuaStatus

Source§

fn new_thread( &mut self, initial_body: Option<LuaValue>, ) -> Result<GcRef<LuaThread>, LuaError>

Source§

fn is_same_thread(&mut self, other: &LuaState) -> bool

Source§

fn load_buffer( &mut self, buf: &[u8], name: &[u8], mode: Option<&[u8]>, ) -> Result<LuaStatus, LuaError>

Source§

fn load_buffer_ex<M>( &mut self, buf: &[u8], name: &[u8], mode: &M, ) -> Result<bool, LuaError>
where M: AsRef<[u8]> + ?Sized,

Source§

fn dump_function(&mut self, strip: bool) -> Result<Vec<u8>, LuaError>

Source§

fn warning(&mut self, msg: &[u8], to_cont: bool) -> Result<(), LuaError>

Source§

fn string_to_number(&mut self, idx: i32) -> Option<usize>

Source§

fn string_to_number_push<S: AsRef<[u8]> + ?Sized>( &mut self, s: &S, ) -> Result<usize, LuaError>

Source§

fn gc_count(&mut self) -> Result<i32, LuaError>

Source§

fn gc_count_b(&mut self) -> Result<i32, LuaError>

Source§

fn gc_step(&mut self, data: i32) -> Result<i32, LuaError>

Source§

fn gc_is_running(&mut self) -> Result<bool, LuaError>

Source§

fn gc_control_simple(&mut self, op: i32) -> Result<i32, LuaError>

Source§

fn gc_set_param(&mut self, op: i32, value: i32) -> Result<i32, LuaError>

Source§

fn gc_gen(&mut self, minor_mul: i32, major_mul: i32) -> Result<i32, LuaError>

Source§

fn gc_inc( &mut self, pause: i32, step_mul: i32, step_size: i32, ) -> Result<i32, LuaError>

Source§

fn gc_param(&mut self, param: usize, value: i64) -> Result<i64, LuaError>

Source§

fn get_meta_field(&mut self, idx: i32, name: &[u8]) -> Result<bool, LuaError>

Source§

fn to_display_string(&mut self, idx: i32) -> Result<Vec<u8>, LuaError>

Source§

fn get_subtable_registry(&mut self, name: &[u8]) -> Result<bool, LuaError>

Source§

fn new_metatable(&mut self, name: &[u8]) -> Result<bool, LuaError>

Source§

fn set_metatable_by_name(&mut self, name: &[u8]) -> Result<(), LuaError>

Source§

fn check_arg_userdata( &mut self, arg: i32, name: &[u8], ) -> Result<GcRef<LuaUserData>, LuaError>

Source§

fn test_arg_userdata( &mut self, arg: i32, name: &[u8], ) -> Option<GcRef<LuaUserData>>

Source§

fn get_table(&mut self, idx: i32) -> Result<LuaType, LuaError>

Source§

fn get_stack(&mut self, level: i32, ar: &mut LuaDebug) -> bool

Source§

fn get_stack_level(&mut self, level: i32, ar: &mut LuaDebug) -> bool

Source§

fn get_info(&mut self, what: &[u8], ar: &mut LuaDebug) -> Result<(), LuaError>

Source§

fn get_debug_info( &mut self, what: &[u8], ar: &mut LuaDebug, ) -> Result<(), LuaError>

Source§

fn get_local_at( &mut self, ar: &LuaDebug, n: i32, ) -> Result<Option<Vec<u8>>, LuaError>

Source§

fn set_local_at( &mut self, ar: &LuaDebug, n: i32, ) -> Result<Option<Vec<u8>>, LuaError>

Source§

fn get_param_name( &mut self, fidx: i32, n: i32, ) -> Result<Option<Vec<u8>>, LuaError>

Source§

fn has_frames(&mut self) -> bool

Source§

fn lua_traceback( &mut self, other: &mut LuaState, msg: Option<&[u8]>, level: i32, ) -> Result<(), LuaError>

Source§

fn upvalue_id(&mut self, fidx: i32, n: i32) -> Result<*mut c_void, LuaError>

Source§

fn join_upvalues( &mut self, fidx1: i32, n1: i32, fidx2: i32, n2: i32, ) -> Result<(), LuaError>

Source§

fn load_file_ex( &mut self, path: Option<&[u8]>, mode: Option<&[u8]>, ) -> Result<bool, LuaError>

Source§

fn load_file(&mut self, path: Option<&[u8]>) -> Result<bool, LuaError>

Source§

fn get_iuservalue(&mut self, idx: i32, n: i32) -> Result<LuaType, LuaError>

Source§

fn set_iuservalue(&mut self, idx: i32, n: i32) -> Result<bool, LuaError>

Source§

fn get_hook_mask(&mut self) -> u32

Source§

fn get_hook_count(&mut self) -> i32

Source§

fn set_c_stack_limit(&mut self, limit: i32) -> Result<i32, LuaError>

Source§

fn set_warn_fn( &mut self, f: Option<lua_CFunction>, ud: Option<LuaValue>, ) -> Result<(), LuaError>

Source§

fn new_lib<F: Copy>(&mut self, funcs: &[(&[u8], F)]) -> Result<(), LuaError>

Source§

fn new_lib_table<F: Copy>( &mut self, funcs: &[(&[u8], F)], ) -> Result<(), LuaError>

Source§

fn register_funcs<F: Copy>( &mut self, funcs: &[(&[u8], F)], ) -> Result<(), LuaError>

Source§

fn register_lib<F: Copy>( &mut self, name: &[u8], funcs: &[(&[u8], F)], ) -> Result<(), LuaError>

Source§

fn set_funcs_with_upvalues<F: Copy>( &mut self, funcs: &[(&[u8], F)], nup: i32, ) -> Result<(), LuaError>

Source§

fn upvalue_index(&mut self, i: i32) -> i32

Source§

impl Trace for LuaState

Source§

fn type_name(&self) -> &'static str

Concrete Rust type name for diagnostic/testC telemetry (Heap::type_name_count). Collector behavior must not branch on this. The default covers container blanket impls, which are never GC-boxed directly; concrete runtime types override it with std::any::type_name::<Self>().
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.