1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57
/// This enum represents a single opcode.
/// Under the hood, it's just a byte.
/// This allows non opcode bytes to be inserted in bytecode streams.
#[repr(u8)]
#[derive(Debug, PartialEq, Eq)]
pub enum Opcode {
/// Load a constant.
Con = 0,
/// Load uninitialized Data.
NotInit,
/// Delete a value off the stack.
Del,
/// Calls out to a Rust function via FFI
FFICall,
/// Copies topmost value on the stack.
Copy,
/// Moves a variable onto the heap.
Capture,
/// Save a constant into a variable.
Save,
/// Save a value to a captured variable.
SaveCap,
/// Push a copy of a variable onto the stack.
Load,
/// Load a copy of a captured variable.
LoadCap,
/// Call a function.
Call,
/// Return from a function.
Return,
/// Creates a closure over the current local environment.
Closure,
/// Prints a value.
Print,
/// Constructs a label.
Label,
// Constructs a tuple.
Tuple,
/// Destructures atomic data by asserting it matches exactly.
UnData,
/// Destructures a label.
UnLabel,
/// Sestructures a tuple.
UnTuple,
}
impl Opcode {
/// Convert a raw byte to an opcode.
/// Note that non-opcode bytes should never be interpreted as an opcode.
/// Under the hood, this is just a transmute, so the regular cautions apply.
/// This *should* never cause a crash
/// and if it does, the vm's designed to crash hard
/// so it'll be pretty obvious.
pub fn from_byte(byte: u8) -> Opcode {
unsafe { std::mem::transmute(byte) }
}
}