#[repr(u8)]pub enum OpCode {
Show 57 variants
Constant = 0,
Null = 1,
True = 2,
False = 3,
Add = 10,
Sub = 11,
Mul = 12,
Div = 13,
Negate = 14,
Not = 20,
And = 21,
Or = 22,
Implication = 23,
Equal = 30,
NotEqual = 31,
Less = 32,
Greater = 33,
LessEqual = 34,
GreaterEqual = 35,
Interpolate = 40,
GetLocal = 50,
SetLocal = 51,
GetUpvalue = 52,
SetUpvalue = 53,
PushWith = 54,
PopWith = 55,
LookupWith = 56,
MakeAttrs = 60,
GetAttr = 61,
HasAttr = 62,
UpdateAttrs = 63,
SelectOrDefault = 64,
DynGetAttr = 65,
DynHasAttr = 66,
DynSelectOrDefault = 67,
MakeList = 70,
Concat = 71,
MakeClosure = 80,
Call = 81,
Return = 82,
TailCall = 83,
Jump = 90,
JumpIfFalse = 91,
JumpIfTrue = 92,
Assert = 100,
Throw = 101,
Pop = 110,
Dup = 111,
GetLocalAttr = 120,
GetLocalCall = 121,
PushBuiltins = 130,
CallBuiltin = 131,
MakeThunk = 140,
Force = 141,
PatchThunkUpvalues = 142,
MakeLazyThunk = 143,
Import = 150,
}Expand description
Bytecode instructions for the Nix VM.
Each variant occupies exactly one byte (#[repr(u8)]). Inline
operands (constant pool index, jump offset, element count) follow
the opcode in the bytecode stream as 16-bit little-endian values.
Variants§
Constant = 0
Push a constant from the constant pool. Operand: u16 constant index.
Null = 1
Push null.
True = 2
Push true.
False = 3
Push false.
Add = 10
Pop two values, push their sum (int+int, float+float, int+float).
Sub = 11
Pop two values, push their difference.
Mul = 12
Pop two values, push their product.
Div = 13
Pop two values, push their quotient. Errors on division by zero.
Negate = 14
Pop one value, push its arithmetic negation.
Not = 20
Pop one bool, push its logical negation.
And = 21
Pop two bools, push logical AND (short-circuit handled at compile time).
Or = 22
Pop two bools, push logical OR (short-circuit handled at compile time).
Implication = 23
Pop two values, push a -> b (logical implication: !a || b).
Equal = 30
Pop two values, push true if equal.
NotEqual = 31
Pop two values, push true if not equal.
Less = 32
Pop two values, push true if left < right.
Greater = 33
Pop two values, push true if left > right.
LessEqual = 34
Pop two values, push true if left <= right.
GreaterEqual = 35
Pop two values, push true if left >= right.
Interpolate = 40
Pop N string parts, concatenate into one string. Operand: u16 part count.
GetLocal = 50
Push a local variable by stack slot index. Operand: u16 slot index (relative to current frame’s stack base).
SetLocal = 51
Set a local variable by stack slot index. Operand: u16 slot index.
GetUpvalue = 52
Push an upvalue from the current closure’s upvalue array. Operand: u8 upvalue index.
SetUpvalue = 53
Set an upvalue in the current closure’s upvalue array. Operand: u8 upvalue index.
PushWith = 54
Push the TOS value onto the with-scope stack.
PopWith = 55
Pop from the with-scope stack.
LookupWith = 56
Look up a name in the with-scope stack (innermost first). Operand: u16 constant index for the variable name string.
MakeAttrs = 60
Pop N key-value pairs (key on top, value below), construct attrset. Operand: u16 pair count.
GetAttr = 61
Pop attrset and key (string constant index), push attrset.key.
Operand: u16 constant index for the key name.
HasAttr = 62
Pop attrset and key (string constant index), push bool. Operand: u16 constant index for the key name.
UpdateAttrs = 63
Pop two attrsets, push merged result (right overrides left, //).
SelectOrDefault = 64
Pop attrset, key constant, and default value, push value or default. Stack order (top to bottom): default, attrset. Operand: u16 constant index for the key name.
DynGetAttr = 65
Dynamic attribute access: pop string key, pop attrset, push attrset.key.
No inline operand — key comes from the stack at runtime.
DynHasAttr = 66
Dynamic hasattr: pop string key, pop attrset, push bool. No inline operand — key comes from the stack at runtime.
DynSelectOrDefault = 67
Dynamic select-or-default: pop default, key, attrset; push value or default. Stack order (top to bottom): default, key (string), attrset. No inline operand — key comes from the stack at runtime.
MakeList = 70
Pop N values, construct a list. Operand: u16 element count.
Concat = 71
Pop two lists, push concatenated result (++).
MakeClosure = 80
Create a closure from a sub-chunk.
Operand: u16 constant index pointing to the function’s Chunk.
Followed by u16 upvalue count, then for each upvalue:
u8 (1 = local, 0 = upvalue of enclosing), u16 index.
Call = 81
Pop function and argument, call the function.
Return = 82
Return from the current call frame.
TailCall = 83
Pop function and argument, tail-call: reuse the current frame. Semantically identical to Call but does not grow the call stack.
Jump = 90
Unconditional jump. Operand: u16 absolute target offset.
JumpIfFalse = 91
Pop condition; if false, jump to target. Operand: u16 absolute target offset.
JumpIfTrue = 92
Pop condition; if true, jump to target. Operand: u16 absolute target offset.
Assert = 100
Pop condition; if false, raise AssertionFailed.
Throw = 101
Pop a string from stack and raise Throw(msg).
Used for deferred search path errors caught by tryEval.
Pop = 110
Discard the top of the stack.
Dup = 111
Duplicate the top of the stack.
GetLocalAttr = 120
Fused GetLocal + GetAttr: push stack[base+slot].key.
Operands: u16 local slot, u16 key constant index.
GetLocalCall = 121
Fused GetLocal + Call: call stack[base+slot] with TOS as arg.
Operand: u16 local slot.
PushBuiltins = 130
Push the builtins attribute set onto the stack.
CallBuiltin = 131
Call a builtin function by index. Operand: u16 builtin index, u16 arg count.
MakeThunk = 140
Create a thunk wrapping a sub-chunk (lazy value). Operand: u16 constant index, u16 upvalue count, then for each upvalue: u8 is_local, u16 index.
Force = 141
Force the top of stack: if it is a thunk, evaluate and replace.
PatchThunkUpvalues = 142
Patch upvalues of a thunk in a local slot. Operand: u16 slot, u16 upvalue count, then for each: u8 is_local, u16 index.
MakeLazyThunk = 143
Create a lazy thunk from a source span (deferred compilation). Operand: u16 source_constant_idx, u32 offset, u32 length, u16 base_dir_constant_idx, u16 upvalue count, then for each upvalue: u8 is_local, u16 index.
Import = 150
Pop a path from the stack, import the file, push the result.
Implementations§
Source§impl OpCode
impl OpCode
Sourcepub const ALL: &'static [OpCode]
pub const ALL: &'static [OpCode]
Every opcode variant, in declaration order. Generated from the same table as the enum, so it can never omit a variant — the exhaustive roundtrip test drives off this list.
Sourcepub fn to_byte(self) -> u8
pub fn to_byte(self) -> u8
The wire byte for this opcode (inverse of Self::from_byte).
Equivalent to self as u8; provided as the named paired
inverse so the round-trip is spelled out at call sites.
Sourcepub fn disasm_operands(self) -> u8
pub fn disasm_operands(self) -> u8
Number of inline u16 operands the disassembler prints for
this opcode (0, 1, or 2). This is the arity the Chunk Debug
formatter uses to advance past inline operands; it is an
exhaustive match self, so adding an opcode without an
operand-arity column is a compile error.
Trait Implementations§
impl Copy for OpCode
impl Eq for OpCode
impl StructuralPartialEq for OpCode
Auto Trait Implementations§
impl Freeze for OpCode
impl RefUnwindSafe for OpCode
impl Send for OpCode
impl Sync for OpCode
impl Unpin for OpCode
impl UnsafeUnpin for OpCode
impl UnwindSafe for OpCode
Blanket Implementations§
Source§impl<T> ArchivePointee for T
impl<T> ArchivePointee for T
Source§type ArchivedMetadata = ()
type ArchivedMetadata = ()
Source§fn pointer_metadata(
_: &<T as ArchivePointee>::ArchivedMetadata,
) -> <T as Pointee>::Metadata
fn pointer_metadata( _: &<T as ArchivePointee>::ArchivedMetadata, ) -> <T as Pointee>::Metadata
Source§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
Source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
Source§impl<T> CloneToUninit for Twhere
T: Clone,
impl<T> CloneToUninit for Twhere
T: Clone,
Source§impl<Q, K> Equivalent<K> for Q
impl<Q, K> Equivalent<K> for Q
Source§impl<Q, K> Equivalent<K> for Q
impl<Q, K> Equivalent<K> for Q
Source§impl<T> LayoutRaw for T
impl<T> LayoutRaw for T
Source§fn layout_raw(_: <T as Pointee>::Metadata) -> Result<Layout, LayoutError>
fn layout_raw(_: <T as Pointee>::Metadata) -> Result<Layout, LayoutError>
Source§impl<T, N1, N2> Niching<NichedOption<T, N1>> for N2
impl<T, N1, N2> Niching<NichedOption<T, N1>> for N2
Source§unsafe fn is_niched(niched: *const NichedOption<T, N1>) -> bool
unsafe fn is_niched(niched: *const NichedOption<T, N1>) -> bool
Source§fn resolve_niched(out: Place<NichedOption<T, N1>>)
fn resolve_niched(out: Place<NichedOption<T, N1>>)
out indicating that a T is niched.