Opcode reference

The Lua compiler in this library lowers source to a flat stream of register-based opcodes. There are no labels and no PC-relative jumps; control flow is threaded through an explicit continuation list inside the executor. The full set of opcodes the disassembler emits is documented below.

Loads & moves

Get values into registers: constants, nil, booleans, and register-to-register copies.

load_constant rD, K

Put a literal value — a number, string, `nil`, or boolean — into a register. Constants are baked into the bytecode at compile time.

# permalink
load_nil rD, N

Set a run of registers to `nil` in one shot (used when declaring locals without values).

# permalink
load_boolean rD, bool

Put `true` or `false` into a register.

# permalink
load_env rD

Put the globals table (`_ENV`, where `print`, `math`, etc. live) into a register so later instructions can look things up in it.

# permalink
move rD, rS

Copy the value in one register into another. Like `local x = y`.

# permalink

Globals & upvalues

Read and write the global environment and captured outer-scope bindings.

get_global rD, name

Read a global variable (e.g. `print`) by name into a register.

# permalink
set_global name, rS

Write a register's value to a global variable.

# permalink
get_upvalue rD, up[i]

Read an upvalue — a variable this function captured from the enclosing function — into a register.

# permalink
set_upvalue up[i], rS

Write a register's value back to a captured upvalue.

# permalink
get_open_upvalue rD, rS

Read a captured local that's still living on the parent's stack (parent hasn't returned yet).

# permalink
set_open_upvalue rD, rS

Write to a captured local that's still living on the parent's stack (parent hasn't returned yet).

# permalink

Tables

Allocate, index, field-access, and bulk-fill the universal Lua data structure.

new_table rD, array, hash

Create a fresh empty table. The compiler pre-sizes it based on how many array entries and hash keys it expects.

# permalink
get_table rD, rT, k

Read `t[k]` (any key) and put the result in a register.

# permalink
set_table rT, k, rV

Write a register's value to `t[k]` (any key).

# permalink
get_field rD, rT, name

Read `t.name` — same as `get_table` but specialised for string keys. The VM uses a faster path here.

# permalink
set_field rT, name, rV

Write `t.name` — fast path for string-keyed assignment.

# permalink
set_list rT, start, count, off

Bulk-populate the array part of a table. Used for table literals like `{1, 2, 3}` so the VM can write all entries in one instruction.

# permalink
self rD, rO, name

Set up an `obj:method(args)` call. Copies `obj` into one register and `obj.method` into the next, so the call instruction can use both.

# permalink

Arithmetic & strings

Numeric and bitwise ops, plus string concatenation and length.

add rD, rA, rB

Compute `a + b` and write the result to a register.

# permalink
subtract rD, rA, rB

Compute `a - b` and write the result to a register.

# permalink
multiply rD, rA, rB

Compute `a * b` and write the result to a register.

# permalink
divide rD, rA, rB

Float division: `a / b`. Always returns a float, even for whole numbers.

# permalink
floor_divide rD, rA, rB

Integer floor division: `a // b`. Drops the fractional part.

# permalink
modulo rD, rA, rB

Compute `a % b` (remainder after floor division).

# permalink
power rD, rA, rB

Compute `a ^ b` (exponentiation). Always returns a float.

# permalink
negate rD, rS

Compute `-x`.

# permalink
concatenate rD, rA, rB

Join two strings with `..` and write the result to a register.

# permalink
length rD, rS

Compute `#x` — string length, array length of a table, or the result of the `__len` metamethod.

# permalink
bitwise_and rD, rA, rB

Compute `a & b` (bitwise AND).

# permalink
bitwise_or rD, rA, rB

Compute `a | b` (bitwise OR).

# permalink
bitwise_xor rD, rA, rB

Compute `a ~ b` (bitwise XOR — the binary `~`).

# permalink
bitwise_not rD, rS

Compute `~x` (bitwise NOT — the unary `~`).

# permalink
shift_left rD, rA, rB

Compute `a << b` (left shift).

# permalink
shift_right rD, rA, rB

Compute `a >> b` (right shift).

# permalink

Comparison & logic

Equality, ordering, and short-circuit logical control.

equal rD, rA, rB

Compare `a == b` and write `true` or `false` to a register.

# permalink
less_than rD, rA, rB

Compare `a < b` and write the boolean result.

# permalink
less_equal rD, rA, rB

Compare `a <= b` and write the boolean result.

# permalink
not rD, rS

Compute `not x` — flip a truthy value to `false` or a falsy one to `true`.

# permalink
test rR

Branch on truthiness: if the register is truthy, execute the next continuation; otherwise skip it. Powers `if` / `elseif` / `while` conditions.

# permalink
test_true rR

Inverse of `test`: continue if truthy, skip if falsy.

# permalink
test_and rD, rS

Short-circuit AND. If the source is falsy, copy it to the destination and skip the rest of the expression; otherwise keep going.

# permalink
test_or rD, rS

Short-circuit OR. If the source is truthy, copy it to the destination and skip the rest; otherwise keep going.

# permalink

Control flow

Loops and structured exits. Most jumps live on the continuation list, not as PC offsets.

while_loop

Top of a `while` loop: test the condition, run the body, jump back.

# permalink
repeat_loop

Top of a `repeat … until` loop: run the body, test the condition, jump back.

# permalink
numeric_for rB

A `for i = start, stop, step do` loop. Steps the loop variable and continues until it passes `stop`.

# permalink
generic_for rB, vars

A `for k, v in iter do` loop. Calls the iterator function on each iteration and binds its return values.

# permalink
break

Jump out of the nearest enclosing loop. Implements Lua's `break`.

# permalink
scope registers

Open a new block scope and reserve registers for its locals. Bytecode-level mirror of a `do … end` block.

# permalink

Calls & returns

Invoke and return, including tail calls, varargs, and the method-shim for `obj:method(...)`.

call rB, argc, resc

Call a function. The function and its arguments must already be in consecutive registers. Returns are written back to those same registers.

# permalink
tail_call rB, argc

Call a function in tail position — reuses the current function's stack frame instead of growing it. Lets recursive functions run without exhausting the stack.

# permalink
return rB, count

Return zero or more values from this function. Values come from a run of consecutive registers.

# permalink
return_vararg (varargs)

Return whatever `...` arguments this function received, unchanged.

# permalink
vararg rB, count

Expand `...` into a run of consecutive registers so following instructions can use them.

# permalink

Closures

Build nested functions with captured upvalues.

closure rD, proto[i]

Build a closure from a nested function definition, capturing its upvalues from the surrounding scope. This is what makes `function() ... end` actually produce a callable value.

# permalink

Metadata

Pseudo-instructions for source tracking and debugging.

source_line line

Pseudo-instruction. Marks where in your source code the next batch of instructions came from — used for line numbers in error messages and the cross-highlight in this panel.

# permalink