Skip to main content

Opcode

Enum Opcode 

Source
#[repr(u8)]
pub enum Opcode {
Show 47 variants Const = 0, Pop = 1, Dup = 2, GetLocal = 3, SetLocal = 4, GetGlobal = 5, SetGlobal = 6, Add = 7, Sub = 8, Mul = 9, Div = 10, Mod = 11, Neg = 12, FAdd = 13, FSub = 14, FMul = 15, FDiv = 16, FNeg = 17, Eq = 18, Ne = 19, Lt = 20, Le = 21, Gt = 22, Ge = 23, FEq = 24, FNe = 25, FLt = 26, FLe = 27, FGt = 28, FGe = 29, Not = 30, Jump = 31, JumpIfFalse = 32, JumpIfTrue = 33, Call = 34, Return = 35, MakeArray = 36, MakeTuple = 37, MakeStruct = 38, MakeEnumVariant = 39, Index = 40, Field = 41, Len = 42, ToStr = 43, ConcatN = 44, MatchVariant = 45, Halt = 255,
}
Expand description

the bytecode opcode set.

one byte per opcode, dense discriminants 0..=45 for the active set plus Opcode::Halt at 0xFF as the decoder’s “unknown / end-of-stream” sentinel. derives Copy because opcodes flow through codegen and the peephole optimizer by value; one byte is cheaper to copy than to reference.

the discriminants are part of the bytecode format – changing them reshapes every compiled chunk. add new opcodes by appending discriminants above the current high-water mark; never reuse a freed discriminant.

Variants§

§

Const = 0

push the constant pool entry at index u16 onto the stack. emitted for every literal and for every constant-folded result.

§

Pop = 1

discard the value on top of the stack. emitted at statement-expression boundaries and after expressions whose result is unused.

§

Dup = 2

duplicate the value on top of the stack. used by MATCH_VARIANT chains so multiple arms can test the same scrutinee.

§

GetLocal = 3

read local slot u16 and push its value. slots are numbered 0..N per call frame; parameters occupy slots 0..argc.

§

SetLocal = 4

pop the top value and store it into local slot u16. used by let mut rebinding and by loop-variable updates.

§

GetGlobal = 5

read the global variable at index u16 and push its value. globals are keyed by name in the Program.globals table.

§

SetGlobal = 6

pop the top value and store it into the global at index u16. Qala v1 has no top-level mutable bindings, so this is reserved for forward compatibility.

§

Add = 7

pop two i64 values, push their sum. codegen emits this only when both operands are statically i64-typed; constant folding intercepts the all-literal case at codegen time.

§

Sub = 8

pop two i64 values, push their difference (lhs - rhs).

§

Mul = 9

pop two i64 values, push their product.

§

Div = 10

pop two i64 values, push their quotient (truncated toward zero).

§

Mod = 11

pop two i64 values, push their remainder (Rust’s % semantics).

§

Neg = 12

pop one i64, push its negation. emitted by the unary - operator on i64-typed expressions.

§

FAdd = 13

pop two f64 values, push their sum (IEEE 754).

§

FSub = 14

pop two f64 values, push their difference (IEEE 754).

§

FMul = 15

pop two f64 values, push their product (IEEE 754).

§

FDiv = 16

pop two f64 values, push their quotient (IEEE 754).

§

FNeg = 17

pop one f64, push its negation (sign-bit flip).

§

Eq = 18

pop two values of equal type (i64, bool, or str), push the bool result of lhs == rhs. the VM dispatches by operand type at runtime.

§

Ne = 19

pop two values of equal type, push lhs != rhs.

§

Lt = 20

pop two values of equal type, push lhs < rhs.

§

Le = 21

pop two values of equal type, push lhs <= rhs.

§

Gt = 22

pop two values of equal type, push lhs > rhs.

§

Ge = 23

pop two values of equal type, push lhs >= rhs.

§

FEq = 24

pop two f64 values, push lhs == rhs. follows IEEE 754: NaN == NaN is false.

§

FNe = 25

pop two f64 values, push lhs != rhs. follows IEEE 754: NaN != NaN is true.

§

FLt = 26

pop two f64 values, push lhs < rhs (IEEE 754).

§

FLe = 27

pop two f64 values, push lhs <= rhs (IEEE 754).

§

FGt = 28

pop two f64 values, push lhs > rhs (IEEE 754).

§

FGe = 29

pop two f64 values, push lhs >= rhs (IEEE 754).

§

Not = 30

pop one bool, push its negation. short-circuiting && / || compile to jump patterns, not dedicated opcodes; this is the only logic op.

§

Jump = 31

branch by the signed i16 offset relative to the byte AFTER the operand. negative offsets allowed for backward jumps (loops).

§

JumpIfFalse = 32

pop one bool; if false, branch by the signed i16 offset relative to the byte AFTER the operand. otherwise fall through.

§

JumpIfTrue = 33

pop one bool; if true, branch by the signed i16 offset relative to the byte AFTER the operand. otherwise fall through. emitted by the peephole rewrite NOT; JUMP_IF_FALSE -> JUMP_IF_TRUE.

§

Call = 34

call the function at Program.chunks[u16] with u8 arguments already on the stack (top is the rightmost arg). pushes the returned value (or [crate::value::Value::Void] for void-returning functions).

§

Return = 35

return from the current call frame; the value on top of the stack becomes the call’s result. void-returning functions push [crate::value::Value::Void] before this opcode.

§

MakeArray = 36

pop u16 values off the stack (top is the last element), push a heap array containing them in stack order.

§

MakeTuple = 37

pop u16 values off the stack (top is the last element), push a heap tuple containing them in stack order.

§

MakeStruct = 38

build a heap struct. the u16 operand is a struct id – an index into Program.structs, NOT a bare field count. the VM reads the field count from Program.structs[id].field_count, pops that many values off the stack (top is the last field’s value), and labels the struct with Program.structs[id].name. the field order is locked by the struct declaration; codegen emits the values in declaration order so the VM pairs them without a per-field name index.

§

MakeEnumVariant = 39

construct an enum variant value: variant id u16, then u8 payload values already on the stack (top is the rightmost payload field). the VM keeps the variant id and payload as a heap object.

§

Index = 40

pop an index (i64) then an array value, push the array’s element at that index. out-of-bounds is a runtime error.

§

Field = 41

pop a struct value, push the field at name-pool index u16. the VM resolves the name to the struct’s declared field offset.

§

Len = 42

pop an array (or string), push its length as i64.

§

ToStr = 43

pop one value, push its string form. used to materialise interpolated segments whose static type is not already str.

§

ConcatN = 44

pop u16 values off the stack (in stack order, top last), concatenate them as strings, push the result. used to materialise string interpolation.

§

MatchVariant = 45

test the value on top of the stack against variant id u16; on match, leave the destructured payload on the stack; on miss, branch by the signed i16 offset. consumes the scrutinee on match, leaves it on miss (so a chain of MATCH_VARIANT over multiple arms tests against the same scrutinee via DUP).

§

Halt = 255

sentinel discriminant 0xFF; never emitted by codegen but useful as the disassembler’s “unknown byte” marker. the VM treats it as an error.

Implementations§

Source§

impl Opcode

Source

pub fn from_u8(b: u8) -> Option<Opcode>

safe reverse lookup: the disassembler’s only entry from raw bytes back to a typed Opcode. returns None for any undefined discriminant rather than the UB that a transmute would risk. the match compiles to the same branch table a transmute-based decode would, so the safety is free.

Source

pub fn name(self) -> &'static str

the locked uppercase identifier per Opcode used by the disassembler and the playground bytecode panel. one line per variant; a missing arm fails to compile. the strings are part of the public disassembler contract.

Source

pub fn operand_bytes(self) -> u8

the number of operand bytes following this opcode in the instruction stream. used by the peephole optimizer’s instruction-step function and by crate::chunk::Chunk::disassemble to skip past operand bytes when walking the byte stream. variants reading no operand return 0; variants reading a u16 return 2; variants reading a u16 + u8 return 3; variants reading a u16 + i16 return 4. v1 has no wider operand layouts.

Trait Implementations§

Source§

impl Clone for Opcode

Source§

fn clone(&self) -> Opcode

Returns a duplicate of the value. Read more
1.0.0 (const: unstable) · Source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
Source§

impl Debug for Opcode

Source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
Source§

impl Hash for Opcode

Source§

fn hash<__H: Hasher>(&self, state: &mut __H)

Feeds this value into the given Hasher. Read more
1.3.0 · Source§

fn hash_slice<H>(data: &[Self], state: &mut H)
where H: Hasher, Self: Sized,

Feeds a slice of this type into the given Hasher. Read more
Source§

impl PartialEq for Opcode

Source§

fn eq(&self, other: &Opcode) -> bool

Tests for self and other values to be equal, and is used by ==.
1.0.0 (const: unstable) · Source§

fn ne(&self, other: &Rhs) -> bool

Tests for !=. The default implementation is almost always sufficient, and should not be overridden without very good reason.
Source§

impl Copy for Opcode

Source§

impl Eq for Opcode

Source§

impl StructuralPartialEq for Opcode

Auto Trait Implementations§

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> CloneToUninit for T
where T: Clone,

Source§

unsafe fn clone_to_uninit(&self, dest: *mut u8)

🔬This is a nightly-only experimental API. (clone_to_uninit)
Performs copy-assignment from self to dest. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T> ToOwned for T
where T: Clone,

Source§

type Owned = T

The resulting type after obtaining ownership.
Source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
Source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = Infallible

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
Source§

impl<S, T> Upcast<T> for S
where T: UpcastFrom<S> + ?Sized, S: ?Sized,

Source§

fn upcast(&self) -> &T
where Self: ErasableGeneric, T: ErasableGeneric<Repr = Self::Repr>,

Perform a zero-cost type-safe upcast to a wider ref type within the Wasm bindgen generics type system. Read more
Source§

fn upcast_into(self) -> T
where Self: Sized + ErasableGeneric, T: ErasableGeneric<Repr = Self::Repr>,

Perform a zero-cost type-safe upcast to a wider type within the Wasm bindgen generics type system. Read more