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 Copy for Opcode

Source§

impl Debug for Opcode

Source§

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

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

impl Eq for Opcode

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

Equality operator ==. Read more
1.0.0 (const: unstable) · Source§

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

Inequality operator !=. Read more
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: Sized + 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: Sized + ErasableGeneric<Repr = Self::Repr>,

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