DOCUMENTATIONVM - Opcodes and Chunk
The bytecode compiler produces a flat array of OpCode values packed into a Chunk. This document covers every opcode, the Chunk structure, MethodKind, and the loop-detection helper.
Module Layout
1src/vm/opcode/
2├── mod.rs - re-exports
3├── opcode.rs - OpCode enum, MethodKind enum, TypeTag
4├── chunk.rs - Chunk struct
5└── decode.rs - Decoder stub (currently identity; reserved for future use)
Chunk
1pub struct Chunk {
2 pub bytecode: Arc<Vec<OpCode>>,
3 pub spans: Arc<Vec<crate::error::Span>>,
4 pub is_fiber: bool,
5 pub max_locals: usize,
6 pub call_count: Arc<AtomicUsize>,
7 pub jit_ptr: Arc<AtomicPtr<c_void>>,
8 pub name: String,
9 pub arity: usize,
10 pub uses_heap: Arc<AtomicBool>,
11 pub used_locals: Arc<Vec<u8>>,
12 pub param_types: Vec<TypeTag>,
13}
Each function and the top-level program are compiled into a Chunk. Key fields:
bytecode - the instruction array. Indexed directly by instruction pointer (IP).
spans - one Span per bytecode instruction; same length as bytecode. Used for runtime error reporting.
is_fiber - true for fiber (coroutine) chunks, which have different call/return semantics.
max_locals - number of local register slots required. The executor allocates exactly this many slots per call frame.
call_count - incremented on each call. When it crosses the dynamic threshold vm.jit_threshold (default 50), the JIT compiles the chunk.
jit_ptr - atomic pointer to the JIT-compiled native function; null if not yet compiled.
used_locals - bitmask of which local slots are actually referenced, produced by jit::analysis::analyze_chunk_locals. Used by the JIT to skip zeroing unused slots.
param_types (4.4) - the declared signature type of each parameter. The JIT type inference seeds parameter registers from these declared types instead of Unknown; other registers keep flat inference.
Chunk is Clone; all fields use Arc so clones share the same underlying data.
TypeTag
Used in OpCode::Input to specify what type the runtime should parse from stdin:
1pub enum TypeTag {
2 Int, Float, String, Bool, Date, Array, BoolArray, Set, Map,
3 Table, Function, Row, Json, Fiber, Database, Unknown
4}
MethodKind
A u8-indexed enum of all built-in methods callable via MethodCall. The full list:
| Value | Name | Applies to |
|---|
| 0 | Push | Array |
| 1 | Pop | Array |
| 2 | Len | String, Array, Set, Map |
| 3 | Count | Table, Array, Set |
| 4 | Size | Array, Set, Map, Table |
| 5 | IsEmpty | Array, Set, Map, Table |
| 6 | Clear | Array, Set, Map, Table |
| 7 | Contains | Array, Set, Map |
| 8 | Get | Array, Map, Table, Store |
| 9 | Insert | Set, Map, Table, Database |
| 10 | Update | Map, Table, Database |
| 11 | Delete | Map, Set, Table, Database |
| 12 | Find | Array, Table |
| 13 | Join | Table |
| 14 | Show | Table (print formatted grid) |
| 15 | Sort | Array |
| 16 | Reverse | Array |
| 17 | Add | Set |
| 18 | Remove | Array, Set |
| 19 | Has | Set, Map, String, Array |
| 20 | Length | String |
| 21 | Upper | String |
| 22 | Lower | String |
| 23 | Trim | String |
| 24 | IndexOf | String, Array |
| 25 | LastIndexOf | String |
| 26 | Replace | String |
| 27 | Slice | String, Array |
| 28 | Split | String |
| 29 | StartsWith | String |
| 30 | EndsWith | String |
| 31 | ToInt | String, Float, Bool, Date |
| 32 | ToFloat | String, Int, Bool |
| 33 | Set | Map (upsert) |
| 34 | Keys | Map, Json |
| 35 | Values | Map, Json |
| 36 | Where | Table, Array |
| 37 | Year | Date |
| 38 | Month | Date |
| 39 | Day | Date |
| 40 | Hour | Date |
| 41 | Minute | Date |
| 42 | Second | Date |
| 43 | Format | Date, String |
| 44 | Exists | Store |
| 45 | Append | Store, String |
| 46 | Inject | Json → Table |
| 47 | ToStr | Any (calls to_string) |
| 48 | ToJson | Any (converts to JSON) |
| 49 | Next | Fiber |
| 50 | Run | Fiber |
| 51 | IsDone | Fiber |
| 52 | Close | Database, Fiber |
| 53 | Begin | Database (transaction) |
| 54 | Commit | Database |
| 55 | Rollback | Database |
| 56 | Query | Database |
| 57 | QueryRaw | Database |
| 58 | Sync | Database, Store |
| 59 | Drop | Database, Table |
| 60 | Fetch | Database |
| 61 | Save | Store |
| 62 | Truncate | Database, Table |
| 63 | Exec | Database |
| 64 | IsOpen | Database |
| 65 | First | Table, Array |
| 66 | Key | Map |
| 67 | Ready | IO (terminal ready-check) |
| 68 | Put | Store, Map |
| 69 | Stringify | Json, Any |
| 70 | Start | Fiber |
| 71 | Result | Net response |
| 72 | Table | Database (create table handle) |
| 73 | Execute | Database |
| 74 | Status | Net response |
| 75 | Ms | Date (milliseconds) |
MethodKind::from_u8 maps the u8 discriminant back to the enum. Unknown values return None.
OpCode - Full Reference
All operand registers are u8 indices into the locals array unless otherwise noted. dst is always written; src, src1, src2 are read-only.
Data Movement
| Opcode | Fields | Description |
|---|
Move | dst, src | Copy local src to dst. Handles refcounting. |
LoadConst | dst, idx: u32 | Load constant at ctx.constants[idx] into dst. |
GetVar | dst, idx: u32 | Load global variable at globals[idx] into dst. |
SetVar | idx: u32, src | Store src into globals[idx]. |
SetName | src, name_idx: u32 | Associates a debug name with a value (no runtime effect on execution). |
EnvGet | dst, src | Read the environment variable named src into dst. |
EnvArgs | dst | Load command-line arguments array into dst. |
Arithmetic
All arithmetic writes result to dst and reads operands from src1, src2. Type dispatch is performed at runtime via Value::add, .sub, etc.
| Opcode | Operation |
|---|
Add | src1 + src2 (int, float, string concat, date+int). For mixed Float/Int operands, Value::add (and .sub/.mul/.div/.rem/.pow) converts the non-float operand via .cast_float() rather than reinterpreting its raw bits as float bits - the same rule the JIT's fast-path selection follows, see compiler/jit/jit_codegen.md. |
Sub | src1 - src2 (int, float, date-int, date-date→days) |
Mul | src1 * src2 |
Div | src1 / src2 (halts on division by zero) |
Mod | src1 % src2 (halts on modulo by zero) |
Pow | src1 ^ src2 |
Neg | dst = -src |
IntConcat | src1 ++ src2 - integer concatenation (joins digits: 12 ++ 34 = 1234) |
String Append
Compiled from the self-concatenation assignment pattern x = x + expr (see compiler/compiler/compiler_stmt.md) instead of a generic Add followed by a store - this avoids allocating for both the read and the result on every iteration of a loop that accumulates a string.
| Opcode | Fields | Description |
|---|
StrAppendVar | var_idx, src | Append locals[src] to the string in global var_idx, in place if uniquely owned. |
StrAppendLocal | local_idx, src | Append locals[src] to the string in local local_idx, in place if uniquely owned. |
StrAppendMember | container, name_idx, src | Append locals[src] to the string stored at JSON field name_idx of container. |
StrAppendElement | container, index, src | Append locals[src] to the string element at index of array container. |
All four opcodes are backed by copy-on-write string concatenation logic. Ownership rules differ by site (4.4):
StrAppendVar (interpreter, get_global_raw): in-place extension only when the globals slot is the buffer's sole owner (strong_count <= 1 && weak_count == 0). A string literal loaded from the chunk's constant pool is a real second owner (LoadConst shares the pool's Arc), so the first append to a literal-initialized global re-allocates; the re-allocation path releases the construction reference after the store so the count reflects real owners. Mutating a shared buffer would corrupt the constant pool - every later load of the same literal would inherit the appended content.
StrAppendLocal (interpreter): same sole-owner rule (<= 1); locals store by transfer, so freshly built buffers are exactly singly owned.
- JIT helpers (
xcx_jit_str_append_var / _local): the var variant keeps threshold <= 2 - the second reference there is the JIT's own managed register copy, released by reload_globals right after the call. A constant-pool co-owner surfaces as count ≥ 3 and re-allocates.
StrAppendMember / StrAppendElement: in-place extension only under Arc::get_mut / strong_count == 1 respectively, otherwise clone-on-write.
Comparison
All write bool to dst. Every comparison opcode carries an int-int fast path (4.4) that compares the raw 64-bit payloads directly when both operands are TAG_INT, instead of ranking the operands first.
| Opcode | Operation |
|---|
Equal | src1 == src2 |
NotEqual | src1 != src2 |
Greater | src1 > src2 |
Less | src1 < src2 |
GreaterEqual | src1 >= src2 |
LessEqual | src1 <= src2 |
Has | src2 HAS src1 - membership test |
Logic
| Opcode | Fields | Description |
|---|
And | dst, src1, src2 | Boolean AND |
Or | dst, src1, src2 | Boolean OR |
Not | dst, src | Boolean NOT |
Control Flow
| Opcode | Fields | Description |
|---|
Jump | target: u32 | Unconditional jump to instruction index target. |
JumpIfFalse | src, target: u32 | Jump if src is falsy. |
JumpIfTrue | src, target: u32 | Jump if src is truthy. |
Halt | - | Immediately stop execution. |
Return | src | Return value in src from current function. |
ReturnVoid | - | Return with no value. |
Loop Opcodes
Specialized combined increment-and-jump instructions for loop optimization:
| Opcode | Fields | Description |
|---|
LoopNext | reg, limit_reg, target | Increment local reg, jump back to target while still in range (forward iteration). |
LoopPrev | reg, limit_reg, target | Decrement local reg, jump back to target while still in range (reverse iteration). |
IncLocal | reg | Increment local reg by 1. |
DecLocal | reg | Decrement local reg by 1. |
IncVar | idx | Increment global idx by 1. |
DecVar | idx | Decrement global idx by 1. |
IncLocalLoopNext | inc_reg, reg, limit_reg, target | Increment local inc_reg and jump if still in range. |
DecLocalLoopPrev | dec_reg, reg, limit_reg, target | Decrement local dec_reg and jump if still in range. |
IncVarLoopNext | g_idx, reg, limit_reg, target | Global variable loop increment and jump. |
DecVarLoopPrev | g_idx, reg, limit_reg, target | Global variable loop decrement and jump. |
ArrayLoopNext | idx_reg, size_reg, target | Array/set iteration loop step: advance idx_reg, jump back to target while idx_reg < size_reg. |
Set iteration is compiled through a MethodCall { kind: Values } conversion followed by the same ArrayLoopNext; there is no dedicated set-loop opcode.
Function Calls
| Opcode | Fields | Description |
|---|
Call | dst, func_idx: u32, base: u8, arg_count: u8 | Call function func_idx. Arguments are locals [base..base+arg_count]. Result stored in dst. |
MethodCall | dst, kind: MethodKind, base, arg_count | Call a built-in method on the value at locals[base]. More than 16 arguments is rejected at compile time (arg_count: u8 cannot overflow at runtime). |
MethodCallNamed | dst, kind: MethodKind, base, arg_count, names_idx: u32 | MethodCall with named arguments; names_idx indexes a constant-pool string array holding per-argument names (empty string for positional slots). |
MethodCallCustom | dst, method_name_idx: u32, base, arg_count | Method dispatch by string name from the constant pool. Used for dynamic JSON path access and row column resolution. |
I/O
| Opcode | Fields | Description |
|---|
Print | src | Print locals[src] to stdout with newline (\x1b[K\r\n on Unix). |
Input | dst, ty: TypeTag | Read from stdin, parse as ty, store in dst. |
InputKey | dst | Read a single keypress (non-blocking). |
InputKeyWait | dst | Read a single keypress (blocking). |
InputReady | dst | Check whether input is available; write bool to dst. |
Terminal Control
| Opcode | Fields | Description |
|---|
TerminalRaw | dst | Enable raw terminal mode. |
TerminalNormal | dst | Disable raw terminal mode. |
TerminalClear | dst | Clear the terminal screen. |
TerminalCursor | dst, on: bool | Show or hide the cursor. |
TerminalMove | dst, x_src, y_src | Move cursor to (x, y). |
TerminalWrite | dst, src | Write src to terminal without newline. |
TerminalRun | dst, cmd_src | Execute a shell command; result to dst. |
TerminalExit | dst | Exit the process. |
Halt
| Opcode | Fields | Description |
|---|
HaltAlert | src | Emit alert message (non-fatal; execution continues). |
HaltError | src | Print error and halt the current execution. Increments error_count. |
HaltFatal | src | Print fatal error and call process::exit(1). |
Collections - Initialization
| Opcode | Fields | Description |
|---|
ArrayInit | dst, base, count: u32 | Create an array from count values starting at locals[base]. |
BoolArrayInit | dst | Create an empty array:b (BoolArrayObj); elements are added via method calls. |
SetInit | dst, base, count: u32 | Create a set from count values. |
MapInit | dst, base, count: u32 | Create a map from alternating key/value pairs; count is the number of pairs. |
TableInit | dst, skeleton_idx, base, row_count, col_count | Initialize a table from a skeleton constant and row data in locals. |
TableBegin | dst, skeleton_idx | Begin streaming construction of a large table (>200 cells) from a skeleton constant; rows follow via TableInitRow. |
TableInitRow | tbl_dst, base, col_count | Append one row (col_count values starting at locals[base]) to a table begun with TableBegin. |
DatabaseInit | dst, engine_src, path_src, tables_base_reg, table_count | Create a DatabaseObj from engine/path registers and a contiguous span of table_count table-name registers. |
Collections - Operations
| Opcode | Fields | Description |
|---|
GetIndex | dst, container, index | dst = container[index] - works on arrays, sets (by position), maps, strings. |
SetIndex | container, index, src | container[index] = src - mutable index assignment. |
GetMember | dst, container, name_idx: u32 | Access a named member; name_idx is a constant pool index. |
SetMember | container, name_idx: u32, src | Assign to a named member. |
SetUnion | dst, src1, src2 | Mathematical set union. |
SetIntersection | dst, src1, src2 | Mathematical set intersection. |
SetDifference | dst, src1, src2 | Set difference src1 \ src2. |
SetSymDifference | dst, src1, src2 | Symmetric difference. |
SetRange | dst, start, end, step, has_step | Build a set from a numeric range. |
Array Specifics
There are no dedicated array opcodes. Element access and mutation compile to MethodCall with MethodKind::Get / Set / Update, size queries to MethodKind::Size / Len, and appends to MethodKind::Push (see the MethodKind table above). The generic GetIndex/SetIndex opcodes (under "Collections - Operations") are used only for container indexing outside the typed method paths.
Table Specifics
| Opcode | Fields | Description |
|---|
RowGet | dst, row_reg, col_idx: u16 | Read column col_idx from row row_reg. |
TableIter | tbl_reg, idx_reg, row_reg, limit_reg, target: u32 | Loop step for table iteration. Advances idx_reg, loads the row, jumps back to target. |
TablePushRow | tbl_reg, row_reg | Deep-copy row row_reg into table tbl_reg. |
TableCloneSkeleton | dst, src | Clone the schema of table src into a new empty table at dst. |
Row counts are obtained via MethodCall with MethodKind::Count / Len / Size, not a dedicated opcode.
Fiber
| Opcode | Fields | Description |
|---|
FiberCreate | dst, func_idx: u32, base, arg_count | Instantiate a fiber from function func_idx with arguments locals[base..base+arg_count]. |
Yield | src | Yield the value src from the current fiber. |
YieldWithTarget | dst, src | Yield the value src from the current fiber, storing caller's injected response in dst. |
YieldVoid | - | Bare yield; - signals the end of a fiber's current iteration. |
Fiber state queries and resumption are method calls (MethodKind::IsDone / Next / Close), not dedicated opcodes.
Set Specifics
There are no dedicated set opcodes beyond the algebraic SetUnion/SetIntersection/SetDifference/SetSymDifference/SetRange above. Cardinality compiles to MethodCall (MethodKind::Size / Len / Count); membership compiles to the Has opcode.
Random
| Opcode | Fields | Description |
|---|
RandomInt | dst, min, max, step, has_step | Generate a random integer in [min, max] with optional step. |
RandomFloat | dst, min, max, step, has_step | Same for floats. |
RandomChoice | dst, src | Pick a random element from the set src. |
JSON / Date
| Opcode | Fields | Description |
|---|
JsonParse | dst, src | Parse src as a JSON string; store JsonObj in dst. |
JsonBindLocal | dst, json_src, path_src | Extract path from JSON; store in local dst. |
JsonBind | idx: u32, json_src, path_src | Extract path from JSON; store in global idx. |
JsonInject | table_idx: u32, json_src, mapping_src | Inject JSON data into a global table using a mapping. |
JsonInjectLocal | table_reg, json_src, mapping_src | Same with a local table register. |
JsonFastGetPush | json_src, path_src, val_src | Fast JSON get and push; used in injection pipelines. |
DateNow | dst | Write current UTC timestamp (millis) as a date value into dst. |
PerfMs / PerfUs / PerfNs | dst | Write VM uptime in milliseconds / microseconds / nanoseconds to dst. |
Store (File System)
All store opcodes follow the pattern dst, base where base is the register containing the path expression.
| Opcode | Operation |
|---|
StoreWrite | Write value to file |
StoreRead | Read file contents |
StoreAppend | Append to file |
StoreExists | Check existence |
StoreDelete | Delete file or directory |
StoreList | List directory contents |
StoreIsDir | Check if path is a directory |
StoreSize | Get file size in bytes |
StoreMkdir | Create directory |
StoreGlob | Glob pattern match |
StoreZip | Create zip archive |
StoreUnzip | Extract zip archive |
Crypto
| Opcode | Fields | Description |
|---|
CryptoHash | dst, pass_src, alg_src | Hash a password using the specified algorithm. |
CryptoVerify | dst, pass_src, hash_src, alg_src | Verify password against hash. |
CryptoToken | dst, len_src | Generate a random token of specified length. |
Networking
| Opcode | Fields | Description |
|---|
HttpCall | dst, method_idx: u32, url_src, body_src | Execute an HTTP request; result JSON in dst. |
HttpServe | func_idx, port_src, host_src, workers_src, routes_src | Start HTTP server; does not return. |
HttpRespond | dst, status_src, body_src, headers_src | Send HTTP response from a route handler. |
HttpRequest | dst, arg_src | Access the current HTTP request object. |
Misc
| Opcode | Fields | Description |
|---|
Typeof | dst, src | Write the type name string of src into dst. |
Wait | src | Sleep for locals[src] milliseconds (the @wait statement and trailing @wait on method calls). |
CastInt / CastFloat / CastString / CastBool | dst, src | Type casts emitted for the i()/f()/s()/b() built-ins. |