pub enum Op {
Show 65 variants
PushConst(u32),
Pop,
Dup,
LoadLocal(u16),
StoreLocal(u16),
MakeRecord {
shape_idx: u32,
field_count: u16,
},
MakeTuple(u16),
MakeList(u32),
MakeVariant {
name_idx: u32,
arity: u16,
},
GetField(u32),
GetElem(u16),
TestVariant(u32),
GetVariant(u32),
GetVariantArg(u16),
GetListLen,
GetListElem(u32),
ListAppend,
GetListElemDyn,
Jump(i32),
JumpIf(i32),
JumpIfNot(i32),
Call {
fn_id: u32,
arity: u16,
node_id_idx: u32,
},
TailCall {
fn_id: u32,
arity: u16,
node_id_idx: u32,
},
MakeClosure {
fn_id: u32,
capture_count: u16,
},
CallClosure {
arity: u16,
node_id_idx: u32,
},
SortByKey {
node_id_idx: u32,
},
ParallelMap {
node_id_idx: u32,
},
EffectCall {
kind_idx: u32,
op_idx: u32,
arity: u16,
node_id_idx: u32,
},
Return,
Panic(u32),
IntAdd,
IntSub,
IntMul,
IntDiv,
IntMod,
IntNeg,
IntEq,
IntLt,
IntLe,
FloatAdd,
FloatSub,
FloatMul,
FloatDiv,
FloatNeg,
FloatEq,
FloatLt,
FloatLe,
NumAdd,
NumSub,
NumMul,
NumDiv,
NumMod,
NumNeg,
NumEq,
NumLt,
NumLe,
BoolAnd,
BoolOr,
BoolNot,
StrConcat,
StrLen,
StrEq,
BytesLen,
BytesEq,
LoadLocalAddIntConst {
local_idx: u16,
imm_const_idx: u32,
},
}Variants§
PushConst(u32)
Pop
Dup
LoadLocal(u16)
StoreLocal(u16)
MakeRecord
Builds a record by interning its field-name shape in
Program.record_shapes (#461). shape_idx indexes that
side-table; field_count is shape.len() cached inline so the
stack-effect verifier can compute its delta without needing a
Program reference. The VM pops field_count values off the
stack and pairs them with Program.record_shapes[shape_idx].
Externalizing the field-name vec is what lets Op be Copy,
which is the precondition for direct-threaded dispatch
(code[pc] becomes a register-sized read instead of an
every-step Vec clone).
MakeTuple(u16)
MakeList(u32)
MakeVariant
GetField(u32)
GetElem(u16)
TestVariant(u32)
GetVariant(u32)
GetVariantArg(u16)
GetListLen
GetListElem(u32)
ListAppend
Pop [list, value]; push list with value appended.
GetListElemDyn
Pop list; push it indexed by the integer on top. Stack: [list, idx] → [list[idx]]. (Like GetListElem(u32) but the index is dynamic.)
Jump(i32)
JumpIf(i32)
JumpIfNot(i32)
Call
TailCall
MakeClosure
Build a Value::Closure: pop capture_count values (in order) and
pair them with fn_id.
CallClosure
Call a closure: pop arity args + 1 closure (top of stack), invoke.
SortByKey
Stable sort-by-key (#338). Stack: [xs, f] (xs underneath).
Pops the key-fn f and the list xs, applies f to each
element to derive a sortable key, returns the list reordered
so keys ascend. Keys must be one of Int / Float / Str;
other key types pair-wise compare as equal (preserving
insertion order). node_id_idx is the originating NodeId.
ParallelMap
Parallel map (#305 slice 1). Stack: [xs, f] (xs underneath).
Pops the closure f and the list xs, applies f to each
element in parallel via OS threads, pushes the result list
in input order. node_id_idx is the originating NodeId for
trace keying. The pool size is capped by
LEX_PAR_MAX_CONCURRENCY (default = available CPU cores).
Slice 1 limitation: closures invoking effects fail at
runtime with VmError::Effect. The per-thread effect handler
split is queued as slice 2.
EffectCall
EFFECT_CALL <effect_kind_const_idx> <op_name_const_idx> <arity>.
Pops arity args, dispatches to a host effect handler, pushes result.
node_id_idx points to a Const::NodeId for trace keying.
Return
Panic(u32)
IntAdd
IntSub
IntMul
IntDiv
IntMod
IntNeg
IntEq
IntLt
IntLe
FloatAdd
FloatSub
FloatMul
FloatDiv
FloatNeg
FloatEq
FloatLt
FloatLe
NumAdd
NumSub
NumMul
NumDiv
NumMod
NumNeg
NumEq
NumLt
NumLe
BoolAnd
BoolOr
BoolNot
StrConcat
StrLen
StrEq
BytesLen
BytesEq
LoadLocalAddIntConst
Fused LoadLocal(local_idx) + PushConst(imm_const_idx) + IntAdd. imm_const_idx must point to a Const::Int. The
dispatch arm reads the local, adds the constant, pushes the
result, and advances pc by 3 (past this op and the two
inert PushConst + IntAdd slots that follow). For
body_hash stability (#222) the canonical encoding decomposes
this op back to a standalone LoadLocal(local_idx) at hash
time; the unchanged PushConst / IntAdd at the next two
slots hash normally, so the total bytes match pre-fusion.