Lua.VM.Executor (Lua v1.0.0-rc.2)

View Source

Instruction executor for the Lua VM.

Fully tail-recursive CPS dispatch loop. The do_execute/8 function never grows the Erlang call stack for Lua-to-Lua function calls or control flow.

Signature: do_execute(instructions, registers, upvalues, proto, state, cont, frames, line)

cont — continuation stack: list of instruction lists or loop/CPS markers frames — call frame stack: saved caller context for each active Lua call line — current source line (threaded to avoid State struct allocation)

Summary

Functions

Calls a Lua function value with the given arguments.

Returns the current Lua source position recorded by the executor.

Executes instructions with the given register file and state.

Reads t[key] honoring the __index metamethod chain.

Returns the integer length of tref, honoring __len.

Writes t[key] = value honoring the __newindex metamethod chain.

Functions

call_function(other, args, state)

@spec call_function(term(), list(), Lua.VM.State.t()) :: {list(), Lua.VM.State.t()}

Calls a Lua function value with the given arguments.

Used by pcall/xpcall to invoke functions in protected mode. Returns {results, final_state}.

current_position()

@spec current_position() :: {nil | integer(), nil | binary()}

Returns the current Lua source position recorded by the executor.

Returns {line, source} if a native callback is executing inside a Lua chunk (or just was), or {nil, nil} outside any execution.

Used by raise sites in Lua.VM.Stdlib and other native helpers to attach line / source to runtime exceptions without threading them through every helper signature.

execute(instructions, registers, upvalues, proto, state)

@spec execute([tuple()], tuple(), list(), map(), Lua.VM.State.t()) ::
  {list(), tuple(), Lua.VM.State.t()}

Executes instructions with the given register file and state.

Returns {results, final_registers, final_state}.

Saves and restores any prior current_position/0 snapshot so nested executions (e.g. an Elixir callback that itself calls Lua.eval!) don't leak source positions into each other.

Likewise saves and restores state.open_upvalues so that a nested execution's upvalue cells — keyed by register index — cannot collide with the caller's. Without this, a require that runs a module body containing closures over its top-level locals would leak those cells back to the caller; the caller's later closures would then reuse the stale cells by register index, aliasing the caller's locals to unrelated inner values.

table_index(tref, key, state)

@spec table_index({:tref, non_neg_integer()}, term(), Lua.VM.State.t()) ::
  {term(), Lua.VM.State.t()}

Reads t[key] honoring the __index metamethod chain.

Returns {value, state}. Raises RuntimeError if the __index chain exceeds @metamethod_chain_limit to guard against cyclic metatables.

Public so that stdlib functions (e.g. table.concat, table.sort) can perform metamethod-aware reads without duplicating dispatch logic.

table_length(tref, state)

@spec table_length(
  {:tref, non_neg_integer()},
  Lua.VM.State.t()
) :: {integer(), Lua.VM.State.t()}

Returns the integer length of tref, honoring __len.

When __len is defined the metamethod is invoked and its result is coerced to an integer. Otherwise falls back to Value.sequence_length/1.

Returns {integer_length, state}. Raises TypeError when __len returns a value that cannot be coerced to an integer (matching ltablib.c's aux_getn/luaL_len semantics for the table library).

table_newindex(tref, key, value, state)

@spec table_newindex({:tref, non_neg_integer()}, term(), term(), Lua.VM.State.t()) ::
  Lua.VM.State.t()

Writes t[key] = value honoring the __newindex metamethod chain.

Returns the updated state. Raises RuntimeError if the __newindex chain exceeds @metamethod_chain_limit.

Public so that stdlib functions (e.g. table.insert, table.sort) can perform metamethod-aware writes without duplicating dispatch logic.