VM Opcode Set
Stack-based VM. Each opcode is 1 byte. Operands follow the opcode.
Stack
| Opcode |
Hex |
Operand |
Description |
| NOP |
0x00 |
- |
No operation |
| HALT |
0x01 |
- |
Stop the VM |
| POP |
0x02 |
- |
Pop 1 element from stack |
| DUP |
0x03 |
- |
Duplicate stack top |
Constants (Push)
| Opcode |
Hex |
Operand |
Description |
| PUSH_NIL |
0x10 |
- |
Push nil |
| PUSH_TRUE |
0x11 |
- |
Push true |
| PUSH_FALSE |
0x12 |
- |
Push false |
| PUSH_NUM |
0x13 |
f64 (8 bytes) |
Push number |
| PUSH_CONST |
0x14 |
u16 (index) |
Push from constant pool |
| PUSH_FN |
0x15 |
u32 (addr) |
Push function reference |
Variables
| Opcode |
Hex |
Operand |
Description |
| LOAD_LOCAL |
0x20 |
u8 (slot) |
Push local variable |
| STORE_LOCAL |
0x21 |
u8 (slot) |
Store to local variable |
| LOAD_GLOBAL |
0x22 |
u16 (index) |
Push global variable |
| STORE_GLOBAL |
0x23 |
u16 (index) |
Store to global variable |
Arithmetic
| Opcode |
Hex |
Operand |
Description |
| ADD |
0x30 |
- |
a + b |
| SUB |
0x31 |
- |
a - b |
| MUL |
0x32 |
- |
a * b |
| DIV |
0x33 |
- |
a / b |
| MOD |
0x34 |
- |
a % b |
| NEG |
0x35 |
- |
-a |
Comparison
| Opcode |
Hex |
Operand |
Description |
| EQ |
0x40 |
- |
a == b |
| NEQ |
0x41 |
- |
a != b |
| LT |
0x42 |
- |
a < b |
| GT |
0x43 |
- |
a > b |
| LTE |
0x44 |
- |
a <= b |
| GTE |
0x45 |
- |
a >= b |
Logic
| Opcode |
Hex |
Operand |
Description |
| NOT |
0x50 |
- |
!a |
| AND |
0x51 |
- |
a && b |
| OR |
0x52 |
- |
a || b |
Control Flow
| Opcode |
Hex |
Operand |
Description |
| JMP |
0x60 |
i16 (offset) |
Unconditional jump |
| JMP_IF |
0x61 |
i16 (offset) |
Jump if true |
| JMP_NOT |
0x62 |
i16 (offset) |
Jump if false |
| CALL |
0x63 |
u8 (arg count) |
Call function |
| RET |
0x64 |
- |
Return from function |
| TRY_CALL |
0x65 |
u8 (arg count) |
Call function with error catching, returns result<T> |
Collections
| Opcode |
Hex |
Operand |
Description |
| ARR_NEW |
0x70 |
u16 (element count) |
Create new array |
| ARR_GET |
0x71 |
- |
array[index] |
| ARR_SET |
0x72 |
- |
array[index] = value |
| DICT_NEW |
0x73 |
u16 (pair count) |
Create new dict |
| DICT_GET |
0x74 |
- |
dict[key] |
| DICT_SET |
0x75 |
- |
dict[key] = value |
Timers / Event Loop
| Opcode |
Hex |
Operand |
Description |
| EVERY |
0x80 |
u32 (callback addr) |
Register repeating timer, pushes timer ID |
| TIMER |
0x81 |
u32 (callback addr) |
Register one-shot timer, pushes timer ID |
| SCHEDULE |
0x82 |
u32 (callback addr) |
Register delayed repeating timer, pushes timer ID |
| EVENT_CHECK |
0x83 |
- |
Check timers, fire callback if ready |
| EXIT |
0x84 |
- |
Exit event loop |
| KEEP_ALIVE |
0x85 |
- |
Enter event loop mode |
| CANCEL |
0x86 |
- |
Cancel timer (pops timer ID from stack) |
Integer Arithmetic
| Opcode |
Hex |
Operand |
Description |
| PUSH_I32 |
0x90 |
i32 (4 bytes) |
Push 32-bit signed integer |
| PUSH_U8 |
0x91 |
u8 (1 byte) |
Push 8-bit unsigned integer |
| IADD |
0x92 |
- |
Integer a + b |
| ISUB |
0x93 |
- |
Integer a - b |
| IMUL |
0x94 |
- |
Integer a * b |
| IDIV |
0x95 |
- |
Integer a / b (truncates) |
| IMOD |
0x96 |
- |
Integer a % b |
| INEG |
0x97 |
- |
Integer -a |
| I32_TO_NUM |
0x98 |
- |
Convert i32 to number (double) |
| NUM_TO_I32 |
0x99 |
- |
Convert number to i32 (truncates) |
| U8_TO_I32 |
0x9A |
- |
Promote u8 to i32 |
| I32_TO_U8 |
0x9B |
- |
Truncate i32 to u8 |
Struct
| Opcode |
Hex |
Operand |
Description |
| STRUCT_NEW |
0xA0 |
u8 (field count) |
Pop N field values, create struct, push it |
| STRUCT_GET |
0xA1 |
u8 (field index) |
Pop struct, push field value |
| STRUCT_SET |
0xA2 |
u8 (field index) |
Pop value + struct, set field, push struct |
Built-in Methods
| Opcode |
Hex |
Operand |
Description |
| ARR_LEN |
0xB0 |
- |
Pop array, push length as i32 |
| ARR_PUSH |
0xB1 |
- |
Pop value + array, append value (void) |
| ARR_POP |
0xB2 |
- |
Pop array, remove last element, push element |
| STR_LEN |
0xB3 |
- |
Pop string, push byte length as i32 |
| DICT_LEN |
0xB4 |
- |
Pop dict, push pair count as i32 |
| DICT_KEYS |
0xB5 |
- |
Pop dict, push keys as typed array |
| DICT_VALUES |
0xB6 |
- |
Pop dict, push values as typed array |
| DICT_HAS |
0xB7 |
- |
Pop key + dict, push bool |
| DICT_DEL |
0xB8 |
- |
Pop key + dict, remove pair (void) |
| STR_UPPER |
0xB9 |
- |
Pop string, push uppercased copy |
| STR_LOWER |
0xBA |
- |
Pop string, push lowercased copy |
| STR_TRIM |
0xBB |
- |
Pop string, push whitespace-trimmed copy |
| STR_CONTAINS |
0xBC |
- |
Pop substring + string, push bool |
| STR_INDEXOF |
0xBD |
- |
Pop substring + string, push i32 index (-1 if not found) |
| STR_SPLIT |
0xBE |
- |
Pop separator + string, push array<string> |
| ARR_CONTAINS |
0xBF |
- |
Pop value + array, push bool |
| ARR_INDEXOF |
0xC0 |
- |
Pop value + array, push i32 index (-1 if not found) |
| ARR_SLICE |
0xC1 |
- |
Pop end + start + array, push new sub-array |
| ARR_SORT |
0xC2 |
- |
Sort array in place (number, i32, string) |
| ARR_REVERSE |
0xC3 |
- |
Reverse array in place |
| ARR_JOIN |
0xC4 |
- |
Pop separator + array, push joined string |
| STR_SUBSTR |
0xC5 |
- |
Pop end + start + string, push substring |
Conversion
| Opcode |
Hex |
Operand |
Description |
| TO_STR |
0xD0 |
- |
Pop value, push string representation |
| TO_NUM |
0xD1 |
- |
Pop value, push numeric conversion |
Native Module Call
| Opcode |
Hex |
Operand |
Description |
| NATIVE_CALL |
0xE0 |
u16 (func index) + u8 (arg count) |
Call native C function by index, push result |
The compiler resolves native function indices at compile time. Arguments are popped from the stack, passed to the C function, and the return value is pushed. No string lookup at runtime.
Task (Concurrency)
| Opcode |
Hex |
Operand |
Description |
| SPAWN |
0xE1 |
u8 (arg count) |
Pop function + args, create new task |
| YIELD |
0xE2 |
- |
Yield current task, switch to next ready task |
Channel
| Opcode |
Hex |
Operand |
Description |
| CHAN_NEW |
0xE3 |
- |
Pop capacity, create channel, push it |
| CHAN_SEND |
0xE4 |
- |
Pop value + channel, send value (may park) |
| CHAN_RECV |
0xE5 |
- |
Pop channel, receive value and push it (may park) |
| CHAN_CAN_RECV |
0xE6 |
- |
Pop channel, push bool (can recv without blocking?) |
| CHAN_CAN_SEND |
0xE7 |
- |
Pop channel, push bool (can send without blocking?) |
CHAN_CAN_RECV/CHAN_CAN_SEND are used by select to probe channel readiness without side effects.
Runtime Config
| Opcode |
Hex |
Operand |
Description |
| SET_QUANTUM |
0xE8 |
- |
Pop number, set task scheduler quantum |
Built-in
| Opcode |
Hex |
Operand |
Description |
| PRINT |
0xF0 |
u8 (arg count) |
console.log (debug mode only) |
| ASSERT |
0xF1 |
u8 (has_msg) |
Pop condition (and optional message), fail if false |
| RAISE |
0xF2 |
- |
Pop error message string, raise error (unwind to TRY_CALL or halt) |
| GC_COLLECT |
0xF3 |
- |
Trigger manual garbage collection |
| RAISE_CODE |
0xF4 |
- |
Pop error code (i32) + message (string), raise error with code |
| RESULT_FAILED |
0xF5 |
- |
Pop result, push .failed (bool) |
| RESULT_CODE |
0xF6 |
- |
Pop result, push .code (i32) |
| RESULT_ERROR |
0xF7 |
- |
Pop result, push .error (string) |
| RESULT_VALUE |
0xF8 |
- |
Pop result, push .value (T) |