Skip to main content

Crate luna_runtime_helpers

Crate luna_runtime_helpers 

Source
Expand description

luna-runtime-helpers — the static-link runtime entry for the binaries that luna-aot produces.

§Role in the v1.3 Phase AOT pipeline

luna-aot compile foo.lua --out foo walks:

  1. Parse + compile foo.lua to a luna bytecode dump (Stages 1-2).
  2. Emit a .luna.bytecode data section in a fresh .o (Stage 5).
  3. Build this crate as a staticliblibluna_runtime_helpers.a bundles the rust stdlib + luna-core + this thin C-ABI entry.
  4. Emit a tiny C main that calls into luna_aot_run passing the bracket-symbol bounds of the bytecode section (Stage 6).
  5. cc links bytecode.o + main.o + libluna_runtime_helpers.a
    • -lpthread -ldl -lm into the final executable.

The produced binary at run time:

  • the C main calls luna_aot_run(bytecode_ptr, len)
  • luna_aot_run constructs a Vm, allows bytecode loading, calls Vm::load(slice, b"=embedded") (which routes through luna_core::vm::dump::undump because the slice starts with \x1bLua), then Vm::call_value on the resulting root closure
  • normal print(...) from the script lands on stdout via std::io::stdout inside luna-core’s builtins (no surprises)
  • exit code 0 on success, 1 on load / runtime error

§Why a separate crate (not folded into luna-aot)

luna-aot is the build-time tool — it pulls object + clap and eventually all of cranelift. The deploy-side binary must not pull cranelift; it only needs the luna interp. Splitting this entry into its own crate keeps the deploy-side .a tight (rust stdlib + luna-core only) and lets luna-aot invoke cargo build -p luna-runtime-helpers --release without dragging its own dep tree into the link.

§luna-core 0-third-party-dep contract

Unchanged. cargo tree -p luna-core --prefix none | grep -cE " v[0-9]" continues to report 1. This crate sits above luna-core in the dep graph; nothing here flows back into luna-core.

Modules§

aot_inline_chain_resolver
v1.3 Phase AOT Stage 7 polish 6 — FrameMaterializeInfo chain pointer reloc resolver. See parent-module preamble for the full design rationale; this module owns the deploy-side walk + per-chain Rc materialization + slot write.
aot_strkey_resolver
v1.3 Phase AOT Stage 7 sub-piece 3 — deploy-side interned-string slot resolver.
aot_trace_registry
v1.3 Phase AOT Stage 7 sub-piece 4 — deploy-side trace-meta walker.

Functions§

force_link_aot_entry
Force-link the C-ABI symbol so a cargo build of a dependent rlib doesn’t dead-strip it. Without this, the symbol is technically reachable (no_mangle + extern “C”), but rustc / lld can be over- eager in some pipelines; calling this from lib.rs::pre_main or from a build.rs artifact ensures the staticlib export survives.
force_link_jit_helpers
v1.3 Stage 7 follow-on — pull all 27 luna_jit_* Cranelift trace-mcode helper symbols into the deploy-side staticlib’s linkmap. Called by the AOT-generated C main stub or by the integration tests to make sure the helper symbols are still resolvable after cargo build -p luna-runtime-helpers --release.
luna_aot_run
AOT-binary C-ABI entry. The auto-generated C main calls this once with a pointer + length pair derived from the bracket symbols __luna_bytecode_start / __luna_bytecode_end that luna-aot emits into the .luna.bytecode section.
luna_jit_materialize_sunk_table
P12-S5-C — materialize a Sinkable site’s virtual array slots into a heap Gc<Table> at a side-exit emit point. The JIT emit lays out two parallel stack buffers per site per exit (raws_ptr of cap × u64 and kinds_ptr of cap × u8, one entry per virt slot) and calls this helper. The caller writes the returned Value::Table raw bits into the slot’s reg_state cell + sets the per-exit-tags entry to ExitTag::Table so the dispatcher repacks correctly on deopt.
luna_jit_new_table
P11-S5c — allocate an empty Gc<Table> on the active Vm’s heap. Returns the Gc pointer pun’d to i64. The fresh table is rooted only through the Cranelift Variable the JIT writes it into; no maybe_collect_garbage runs inside the helper so the SSA-only rooting suffices for the duration of the JIT entry.
luna_jit_new_table_sized
P11-S5c.B — Heap::new_table_sized(n) variant. JIT emit reaches for this when the NewTable window is immediately followed by a counted for i = 1, N do … end with a compile-time-known N — pre-allocating the array part skips ~13 intermediate rehash rounds for N=10000, which dominates the hot loop’s wall-clock on table_alloc_10k. Negative or zero hints degrade to an empty table (matches new_table).
luna_jit_op_close
P12-S7-C — trace JIT helper for Op::Close A. Wraps Vm::jit_op_close which does the predict-and-deopt logic: returns 0 to continue the trace, 1 to deopt (handler would run or pre-existing pending_err).
luna_jit_op_closure
P12-S7-A — trace JIT helper for Op::Closure A Bx.
luna_jit_op_concat
P12-S12-C v1 — trace JIT helper for Op::Concat A B.
luna_jit_op_get_tab_up
v1.2 D3 Path B — read upvals[upval_idx][key_str] and return raw payload bits. Mirrors luna_jit_table_get_field but resolves the table via the trace head closure’s upvalue list first (the trace dispatcher’s enter_jit(vm, Some(cl)) pins JIT_CL).
luna_jit_op_tforcall
P12-S12-B-v2 — trace JIT helper for Op::TForCall A 0 C.
luna_jit_spill_to_stack
P12-S7-B — spill a trace’s per-register live value into the caller frame’s vm.stack[base + slot_offset]. Always called just before luna_jit_op_closure for each in_stack: true upval in the inner proto, so the open upval the helper creates points to a slot holding the right value.
luna_jit_stack_load
P12-S12-B-v2 — load the raw i64 payload of vm.stack[base + slot_offset] for the active trace’s head frame. Used to reload trace IR Variables after a helper (e.g. luna_jit_op_tforcall) has mutated vm.stack directly.
luna_jit_stack_tag
P12-S12-B-v2 — read the tag byte of vm.stack[base + slot_offset] for the active trace’s head frame. Used by Op::TForLoop emit to dispatch on the iterator’s return-key tag (Nil → loop end, Int → continue for ipairs, other → deopt for v2).
luna_jit_stack_update_raw
P12-S12-C v1 — update only the raw payload of vm.stack[base + slot_offset], preserving its existing tag. Used by Op::Concat body emit to spill trace-IR Variables back to vm.stack for operands whose current_kinds is Unset (e.g. Str slots that round-trip as pointer raw bits but have no RegKind::Str variant). The interp’s previous execution of the same op already wrote the right tag to that slot — the trace just needs to refresh the raw bits.
luna_jit_str_buf_acquire
P14-S14-B v2 — trace JIT helper:acquire a fresh accumulator buffer from the Vm’s pool. Returns a *mut Vec<u8> boxed-leaked pointer that the trace fn keeps in a stack slot through the loop.
luna_jit_str_buf_extend
P14-S14-B v2 — trace JIT helper:append a LuaStr’s bytes to a previously-acquired accumulator buffer. The trace IR calls this at each loop iter inside the s = s .. v idiom.
luna_jit_str_buf_intern
P14-S14-B v2 — trace JIT helper:drain the accumulator buffer into a fresh LuaStr via heap.intern, returning the raw ptr bits for the trace to write into the accumulator slot.
luna_jit_str_buf_release
P14-S14-B v2 — trace JIT helper:release a buffer back to the Vm’s pool.
luna_jit_table_get_field
P12-S11-A — read t[key_ptr_as_str] and return raw payload bits. String key is a Gc<LuaStr> raw pointer baked into IR. Caller (trace JIT GetField emit) infers exit_tag for the dst slot via infer_getx_exit; absent inference, dispatchable=false.
luna_jit_table_get_float
P11-S5d.E’ — t[k] where k is a Float key. luna 5.1 / 5.2’s OP_GETTABLE typically loads the key via LoadF (no Int subtype in those dialects); the emit hands k as f64::to_bits so the helper can reconstruct the Float value before calling Table::get. Table::get normalises integral Floats back to the Int slot, so t[1.0] lands on t[1] exactly like PUC does. Returns the raw 8-byte payload (same convention as luna_jit_table_get_int).
luna_jit_table_get_int
P11-S5c — t[key] where the JIT statically expects an Int result. Pulls the raw Value from the table and unpacks the Int payload. If the slot is anything but Int (Nil, Float, Str, …) the helper returns 0 — the JIT scan only admits chunks that store Ints, so the divergence is observable only when the user-facing semantics violate the static expectation.
luna_jit_table_len
P11-S5c — #t (table length).
luna_jit_table_set_field
P12-S11-A — write Value::pack(tag, raw) to t[key_ptr_as_str]. String key is a Gc<LuaStr> raw pointer (baked into IR at emit time from head_proto.consts[ins.b()]); value goes through the standard tag/raw round-trip. Used for Op::SetField trace JIT support (helper path; sunk emit is S11-B).
luna_jit_table_set_float_float
P11-S5c — Float-key, Float-value variant. luna 5.1 / 5.2 lower for i = 1, N do t[i] = i end with a Float loop var (no Int subtype in those dialects), so the SetTable’s key and value arguments arrive as f64 bit-patterns. Table::set normalizes integral Float keys back to Int slots so #t still reports the array length we’d expect — same shape PUC produces.
luna_jit_table_set_int
P11-S5c — t[key] = val where t is a Table Gc (i64 pun), key is an Int and val is an Int. Wraps Table::set_int(&mut Heap, i64, Value). Returns nothing (errors swallowed — luna’s set_int only returns Err on table-size pathology that the interpreter would also surface; JIT’d workloads bounded by N=10k don’t reach it). Future caller-visible error reporting would route through a deopt return path.
luna_jit_table_set_nil
P12-S6-A2 — write Value::Nil to t[key] (Int key). Used by trace JIT when a SetList/SetI/SetTable’s source register is a RegKind::Nil (e.g. Lua’s local t = {nil, nil} table constructor expands to NewTable; LoadNil×N; SetList and without a Nil-specific helper the existing _table_set_int would silently coerce the Nil to Value::Int(0)).
luna_jit_table_set_raw
P12-S7-C — write an arbitrary Value::pack(tag, raw_bits) to t[key] (Int key). Generalises _table_set_int / _table_set_nil: trace JIT emit dispatches Int/Nil to their specialized helpers (slightly less overhead) and Closure/Table/Float/etc. to this helper. Without it, a SetTable whose src is a Closure (post-S7 Op::Closure trace JIT) silently wraps the closure pointer as Value::Int(ptr_bits) — a number that later calls fail with “attempt to call a number value”.
luna_jit_trace_materialize_frames
P12-S4-step4b — frame materialization helper.
luna_jit_upval_get
P11-S5d.J — R[A] = upvals[idx] value-read variant. Reads the active closure’s upvalue cell, dispatching open/closed via the interpreter’s Vm::upval_get (so an open upvalue resolves to its current stack slot — matters when a closure is called from inside an enclosing function whose upvalues are still open). Returns the raw 8-byte payload (same convention as the table helpers): the JIT-emitted caller bitcasts to F64 if the slot’s declared kind is Float, leaves as I64 otherwise.
run_bytecode
Convenience entry for in-process Rust drivers (luna-aot’s integration tests, embedders that want to invoke the same code path without going through cc link).