Instruction format
Instructions are represented by theInstruction struct (src/vm/opcode.rs:122):
u32 indices instead of usize reduces instruction size from 16 to 12 bytes on 64-bit platforms, improving cache efficiency.
Core opcodes
Constants and literals
LoadConst(index)- load constant from constant poolLoadConst0,LoadConst1- load constants at indices 0 or 1 (zero-operand optimization)True,False,Void- push boolean/void literals
Local variables
Load(index)- load local variable at frame_pointer + indexLoadLocal0throughLoadLocal3- specialized loads for first 4 localsStore- push value to locals vectorStoreAt(index)- store value at specific local indexReassign(index)- update existing local variablePopLocal(count)- remove locals when scope ends
Global variables
LoadGlobal(index)- load global variableLoadGlobal0throughLoadGlobal3- specialized loads for first 4 globalsStoreGlobal(index)- store to global variableReassignGlobal(index)- update existing global
Arithmetic operations
Add,Subtract,Multiply,Divide,Modulo,Power- binary operationsNegate- unary negationAddInt,SubtractInt- specialized integer operations (no type checking)IncrementLocal(index),DecrementLocal(index)- in-place local modification
Comparison operations
Equal,NotEqual- equality testsLess,LessEqual,Greater,GreaterEqual- ordering comparisonsLessInt- specialized integer less-than (no type checking)
Logical operations
And,Or- short-circuit boolean operatorsNot- boolean negation
Control flow
Jump(target)- unconditional jump to instructionJumpIfFalse(target)- conditional jumpReturn- return from function
Collections
List(count)- create list from top N stack valuesDict(count)- create dict from top 2N stack values (key-value pairs)Range- create range from two stack valuesIndex- index into list/dict/stringStoreIndex- assign to indexed location (list[i] = x)
Loops and iteration
GetIter- convert value to iteratorIterNext(exit_ip)- get next value or jump to exitForRangeInit(local_idx)- initialize optimized range loopForRangeNext(exit_ip, local_idx)- increment and check range loop
Functions
Call(arg_count)- call function with N argumentsTailCall(arg_count)- tail-recursive call (reuses frame)CallMethod(arg_count)- call method on object
Structs
MakeStruct- create struct instance from definitionGetMethod- retrieve method from struct definition
Stack manipulation
Pop- discard top of stackPop2,Pop3- discard multiple valuesDup- duplicate top of stackSwap- swap top two values
Built-in functions
Len- get length of string/list/dictStr- convert value to stringType- get type name of valuePrint,Println- output to console
Garbage collection
Gc- manually trigger garbage collectionHeapStats- get heap statistics as dictGcConfig- configure GC thresholds
Module system
Import- load native module and return dict of functions
Specialized opcodes for performance
The compiler emits specialized opcodes to reduce instruction size and eliminate runtime checks:Zero-operand variants
Instead ofLoadConst(0) (12 bytes), emit LoadConst0 (8 bytes). Similar optimizations exist for:
LoadConst0,LoadConst1LoadLocal0,LoadLocal1,LoadLocal2,LoadLocal3LoadGlobal0,LoadGlobal1,LoadGlobal2,LoadGlobal3
Type-specialized operations
When types are known at compile time:AddIntinstead ofAdd- skips type checkingSubtractIntinstead ofSubtractLessIntinstead ofLess
Loop optimizations
Range-based for loops use optimized opcodes that avoid heap allocation:Disassembly
Use the-d flag to disassemble bytecode:
- Instruction offset
- Opcode and operands
- Comments indicating what values are loaded
Constant pool
Each instruction set has a constant pool storing:- Integer and float literals
- String constants (as heap keys)
- Compiled function objects
- Struct definitions
LoadConst(index) opcodes. The compiler deduplicates constants to reduce memory usage.
Instruction metadata
Each instruction stores aSpan for error reporting:
Compact encoding
The instruction set is designed for compactness:- Opcode enum uses
#[repr(u8)]for 1-byte discriminant - Operands are
u32instead ofusize(4 bytes vs 8 bytes on 64-bit) - Zero-operand variants for common cases
- Total instruction size: 12 bytes (down from 24 bytes in naive implementation)
Source references
- Opcode enum:
src/vm/opcode.rs:6 - Instruction struct:
src/vm/opcode.rs:122 - Disassembler:
src/vm/instruction_set.rs - Opcode handlers:
src/vm/handlers/