.stflb bytecode by stoffel-vm-types.
Architecture Overview
The VM uses two related instruction forms:
During function registration and bytecode loading, labels are resolved, immediates are interned into a per-function constant table, and
CALL("name") becomes a numeric call-target index plus a call-target name table.
The runtime then lowers resolved instructions into packed runtime instructions for dispatch. The packed runtime opcode mapping is an internal optimization and is not the same thing as the serialized opcode values shown below.
Registers
Bytecode register operands are absolute frame indices. The default layout uses register16 as the secret-register boundary:
Important details:
r0is the return register.- The secret boundary is a layout convention, not a hard 32-register maximum.
- Each
VMFunctionhas a frame register count. Registration normalizes the count so it is large enough for parameters, the return register, and every referenced register. - The register file stores clear and secret banks separately even though bytecode operands are absolute indices.
- Moving clear values into secret registers creates or carries share values. Moving secret values back to clear registers becomes a reveal/open operation.
- Pending reveals are stored as register-slot state until the async MPC operation completes.
Frame memory
Each activation frame contains:- function name and local variable map;
- register file;
- captured upvalues;
- a volatile argument stack for
PUSHARG,LD, and calls; - a dedicated spill vector for
STS/LDS; - a compare flag;
- an instruction pointer;
- optional closure metadata.
LD reads from the current frame’s argument stack. Offset 0 resolves to the top argument; negative offsets read below the top.
STS and LDS do not use that argument stack. They access a stable per-frame spill area used by register allocation, so spilled values survive between call argument pushes without being confused with function-call arguments.
Value types
The VM value enum includes:
Object, array, and foreign values are typed handles into VM-managed stores. They are not serialized as constants in
.stflb files.
Share type metadata is shape-oriented:
- secret int: 64 bits;
- secret bool: one-bit secret int;
- fixed point: 64 total bits, 16 fractional bits.
Instruction set
Loading and movement
Arithmetic and bitwise operations
Arithmetic instructions usedest, left, right operands:
Bitwise instructions:
SHL and SHR take the shift amount from a register, not an immediate literal operand.
Comparisons and jumps
CMP left, right sets a typed compare flag:
LessEqualGreater
JMP jumps unconditionally to a label in symbolic form or instruction index in resolved form.
Calls and returns
At the end of a VM function, the runtime also treats
r0 as the return register for fallthrough-style completion.
Serialized opcode values
The opcode values used by serialized bytecode are:Bytecode format
Compiled bytecode is stored in.stflb files. The format is defined by stoffel-vm-types::compiled_binary.
Current format facts:
- magic bytes:
STFL; - format version:
9; - version 9 added
LDS/STSspill-slot instructions; - generic collection guardrail: 1,000,000 items;
- per-function instruction guardrail: 8,000,000 instructions;
- string/blob guardrail: 16 MiB.
Constants
The constant pool supports scalar constants:Unit- signed and unsigned integer values
FloatBoolString
Function records
A compiled function stores:- name;
- parameters;
- parameter types;
- return type;
- upvalues;
- optional parent function name;
- frame register count;
- labels;
- instructions.
Client and MPC manifest
The bytecode manifest carries MPC-facing metadata used by the CLI and SDK:- selected MPC backend, such as HoneyBadger or AVSS;
- selected curve/field configuration;
- client input/output schemas by client slot;
- static preprocessing demand estimate.
dynamic flag for cases where runtime demand may exceed the static estimate.