Files
cell/docs/spec/mach.md
2026-02-08 08:25:48 -06:00

4.5 KiB

title, description
title description
Register VM Register-based virtual machine (Mach)

Overview

The Mach VM is a register-based virtual machine using 32-bit instructions. It is modeled after Lua's register VM — operands are register indices rather than stack positions, reducing instruction count and improving performance.

Instruction Formats

All instructions are 32 bits wide. Four encoding formats are used:

iABC — Three-Register

[op: 8][A: 8][B: 8][C: 8]

Used for operations on three registers: R(A) = R(B) op R(C).

iABx — Register + Constant

[op: 8][A: 8][Bx: 16]

Used for loading constants: R(A) = K(Bx).

iAsBx — Register + Signed Offset

[op: 8][A: 8][sBx: 16]

Used for conditional jumps: if R(A) then jump by sBx.

isJ — Signed Jump

[op: 8][sJ: 24]

Used for unconditional jumps with a 24-bit signed offset.

Registers

Each function frame has a fixed number of register slots, determined at compile time. Registers hold:

  • R(0)this binding
  • R(1)..R(arity) — function arguments
  • R(arity+1).. — local variables and temporaries

Instruction Set

Loading

Opcode Format Description
LOADK iABx R(A) = K(Bx) — load from constant pool
LOADI iAsBx R(A) = sBx — load small integer
LOADNULL iA R(A) = null
LOADTRUE iA R(A) = true
LOADFALSE iA R(A) = false
MOVE iABC R(A) = R(B) — register copy

Arithmetic

Opcode Format Description
ADD iABC R(A) = R(B) + R(C)
SUB iABC R(A) = R(B) - R(C)
MUL iABC R(A) = R(B) * R(C)
DIV iABC R(A) = R(B) / R(C)
MOD iABC R(A) = R(B) % R(C)
POW iABC R(A) = R(B) ^ R(C)
NEG iABC R(A) = -R(B)
INC iABC R(A) = R(B) + 1
DEC iABC R(A) = R(B) - 1

Comparison

Opcode Format Description
EQ iABC R(A) = R(B) == R(C)
NEQ iABC R(A) = R(B) != R(C)
LT iABC R(A) = R(B) < R(C)
LE iABC R(A) = R(B) <= R(C)
GT iABC R(A) = R(B) > R(C)
GE iABC R(A) = R(B) >= R(C)

Property Access

Opcode Format Description
GETFIELD iABC R(A) = R(B)[K(C)] — named property
SETFIELD iABC R(A)[K(B)] = R(C) — set named property
GETINDEX iABC R(A) = R(B)[R(C)] — computed property
SETINDEX iABC R(A)[R(B)] = R(C) — set computed property

Variable Resolution

Opcode Format Description
GETNAME iABx Unresolved variable (compiler placeholder)
GETINTRINSIC iABx Global intrinsic / built-in
GETENV iABx Module environment variable
GETUP iABC R(A) = UpFrame(B).slots[C] — closure upvalue
SETUP iABC UpFrame(A).slots[B] = R(C) — set closure upvalue

Control Flow

Opcode Format Description
JMP isJ Unconditional jump
JMPTRUE iAsBx Jump if R(A) is true
JMPFALSE iAsBx Jump if R(A) is false
JMPNULL iAsBx Jump if R(A) is null

Function Calls

Opcode Format Description
CALL iABC Call R(A) with B args starting at R(A+1), C=keep result
RETURN iA Return R(A)
RETNIL Return null
CLOSURE iABx Create closure from function pool entry Bx

Object / Array

Opcode Format Description
NEWOBJECT iA R(A) = {}
NEWARRAY iABC R(A) = array(B)
PUSH iABC Push R(B) to array R(A)

JSCodeRegister

The compiled output for a function:

struct JSCodeRegister {
  uint16_t arity;           // argument count
  uint16_t nr_slots;        // total register count
  uint32_t cpool_count;     // constant pool size
  JSValue *cpool;           // constant pool
  uint32_t instr_count;     // instruction count
  MachInstr32 *instructions; // 32-bit instruction array
  uint32_t func_count;      // nested function count
  JSCodeRegister **functions; // nested function table
  JSValue name;             // function name
  uint16_t disruption_pc;   // exception handler offset
};

The constant pool holds all non-immediate values referenced by LOADK instructions: strings, large numbers, and other constants.