// FUSEVM — BYTECODE VM

fusevm v0.9.4 · Fused superinstructions · Extension dispatch · Cranelift JIT

GitHub Issues
// Color scheme

>_FUSEVM REFERENCE

Language-agnostic bytecode VM with fused superinstructions and Cranelift JIT. The shared execution engine behind strykelang, zshrs, and awkrs.

ONE VM TO RUN THEM ALL.

FUSED SUPERINSTRUCTIONS. EXTENSION DISPATCH. CRANELIFT JIT.

129
opcodes
10
op categories
8
fused superinstructions
24
shell ops
4,258
lines of Rust
0
unsafe blocks
3
language frontends
≤24B
op size (cache-friendly)

fusevm is the shared execution engine behind strykelang, zshrs, and awkrs. Any language frontend compiles to the same Op enum and gets fused hot-loop dispatch, extension opcode tables, stack-based execution with slot-indexed fast paths, and JIT eligibility analysis — for free. The VM doesn’t care which language produced the bytecodes.

stryke registers ~450 extended ops. zshrs registers ~20. awkrs registers ~95. They don’t conflict — each frontend owns its own ID space via Extended(u16, u8). Process control ops (pipes, redirects, globs, file tests) are first-class because multiple frontends need them.

[0x00] ARCHITECTURE

┌─────────────────────────────────────────────────────────────────┐ │ LANGUAGE FRONTENDS │ │ │ │ ┌───────────────┐ ┌───────────────┐ ┌───────────────┐ │ │ ��� strykelang │ │ zshrs │ │ awkrs │ │ │ │ Perl 5 compat │ │ shell compiler │ │ awk compiler │ │ │ │ ~450 ext ops │ │ ~20 ext ops │ │ ~95 ext ops │ │ │ └───────┬───────┘ └───────┬───────┘ └───────┬───────┘ │ │ │ compile │ │ │ │ └──────────────────┬───────────────────┘ │ │ ▼ │ │ ┌─────────────────────┐ │ │ │ ChunkBuilder │ │ │ │ .emit(Op, line) │ │ │ │ .build() → Chunk │ │ │ └─────────┬───────────┘ │ │ │ │ │ ┌─────────┴──────────────────┐ │ │ ▼ ▼ │ │ ┌─────────────────┐ ┌──────────────────────┐ │ │ │ VM::run() │ │ JitCompiler │ │ │ │ match-dispatch │ │ is_eligible(chunk) │ │ │ │ interpreter │ │ compile() → native │ │ │ │ │ │ (Cranelift codegen) │ │ │ └─────────────────┘ └──────────────────────┘ │ └─────────────────────────────────────────────────────────────────┘

The Chunk is the unit of compiled bytecodes: an op array, constant pool, name pool, line-number table, and slot count. The ChunkBuilder emits ops one at a time and resolves forward jumps on .build(). The VM executes via a match-dispatch loop over the op array. The JIT compiler analyzes chunks for eligibility and compiles hot paths to native code via Cranelift.

[0x01] QUICK START

use fusevm::{Op, ChunkBuilder, VM, VMResult, Value}; let mut b = ChunkBuilder::new(); b.emit(Op::LoadInt(40), 1); b.emit(Op::LoadInt(2), 1); b.emit(Op::Add, 1); let mut vm = VM::new(b.build()); match vm.run() { VMResult::Ok(val) => println!("result: {}", val.to_str()), // "42" VMResult::Error(e) => eprintln!("error: {}", e), VMResult::Halted => {} }
// Extension handler — register language-specific ops let mut vm = VM::new(chunk); vm.set_extension_handler(Box::new(|vm, id, arg| { match id { 0 => { /* your custom op */ } 1 => { /* another custom op */ } _ => {} } }));

[0x02] FUSED SUPERINSTRUCTIONS

The performance secret. The compiler detects hot loop patterns and emits single ops instead of multi-op sequences. Each fused op eliminates N−1 dispatch cycles, stack pushes, and branch mispredictions from the hot path.

Fused OpReplacesEffect
AccumSumLoop(sum, i, limit) GetSlot + GetSlot + Add + SetSlot + PreInc + NumLt + JumpIfFalse Entire counted sum loop in one dispatch
SlotIncLtIntJumpBack(slot, limit, target) PreIncSlot + SlotLtIntJumpIfFalse Loop backedge in one dispatch
ConcatConstLoop(const, s, i, limit) LoadConst + ConcatAppendSlot + SlotIncLtIntJumpBack String append loop in one dispatch
PushIntRangeLoop(arr, i, limit) GetSlot + PushArray + ArrayLen + Pop + SlotIncLtIntJumpBack Array push loop in one dispatch
AddAssignSlotVoid(a, b) GetSlot + GetSlot + Add + SetSlot Void-context add-assign, no stack traffic
PreIncSlotVoid(slot) GetSlot + Inc + SetSlot Void-context increment, no stack traffic
SlotLtIntJumpIfFalse(slot, int, target) GetSlot + LoadInt + NumLt + JumpIfFalse Fused compare + branch, no stack traffic
PreIncSlot(slot) GetSlot + Inc + SetSlot + GetSlot Slot pre-increment with push

[0x03] OP CATEGORIES

129 opcodes across 10 categories. Every op is ≤24 bytes for cache-friendly dispatch.

Constants & Stack

~12 ops

LoadInt LoadFloat LoadConst LoadTrue LoadFalse LoadUndef Pop Dup Dup2 Swap Rot

Variables

~8 ops — name-indexed + slot-indexed fast paths

GetVar SetVar DeclareVar GetSlot SetSlot SlotArrayGet SlotArraySet

Arrays & Hashes

~25 ops — full collection primitives

ArrayPush ArrayPop ArrayShift ArrayLen MakeArray HashGet HashSet HashDelete HashKeys HashValues MakeHash

Arithmetic

9 ops

Add Sub Mul Div Mod Pow Negate Inc Dec

String

3 ops

Concat StringRepeat StringLen

Comparison

~14 ops — numeric + string + three-way

NumEq NumLt NumGe Spaceship StrEq StrLt StrCmp

Logical & Bitwise

9 ops

LogNot LogAnd LogOr BitAnd BitOr BitXor BitNot Shl Shr

Control Flow

5 ops — including short-circuit keep variants

Jump JumpIfTrue JumpIfFalse JumpIfTrueKeep JumpIfFalseKeep

Functions & Scope

5 ops

Call Return ReturnValue PushFrame PopFrame

Higher-Order

5 ops — block-based functional primitives

MapBlock GrepBlock SortBlock SortDefault ForEachBlock

I/O

3 ops

Print PrintLn ReadLine

Collections

2 ops — range generation

Range RangeStep

[0x04] SHELL OPS

Process control is universal enough that multiple frontends need it. These are first-class ops, not extensions — any frontend that targets fusevm gets pipes, redirects, globs, process substitution, and file tests for free.

OpDescription
Exec(n)Spawn external command — pop N args, exec, push exit status
ExecBg(n)Spawn background — like Exec but don’t wait
PipelineBegin(n) / PipelineStage / PipelineEndSet up, wire, and wait for N-stage pipeline
Redirect(fd, op)Redirect fd — write, append, read, clobber, dup, both
HereDoc(idx) / HereStringHere-document from constant pool / here-string from stack
CmdSubst(idx)Command substitution — capture stdout of subprogram
SubshellBegin / SubshellEndIsolate scope for subshell execution
ProcessSubIn(idx) / ProcessSubOut(idx)Process substitution <(cmd) / >(cmd) — push FIFO path
Glob / GlobRecursiveGlob expand pattern from stack — recursive variant is parallel
TestFile(test)File test: -f -d -r -w -x -e -s -L -S -p -b -c
SetStatus / GetStatusLast exit status $?
TrapSet(idx) / TrapCheckSignal trap handler registration + periodic trap check
ExpandParam(mod)18 parameter expansion modifiers: ${:-} ${:=} ${:?} ${:+} ${#} ${/} ${^^} etc.
WordSplit / BraceExpand / TildeExpandIFS word split, brace expansion, tilde expansion

[0x05] EXTENSION MECHANISM

Language-specific opcodes use Extended(u16, u8) which dispatches through a handler table registered by the frontend. The u16 is the extension op ID (up to 65,535 ops per frontend). The u8 is an inline operand. ExtendedWide(u16, usize) carries a full usize payload for jump targets and large indices.

┌──────────────────────────────────────────────────────────────┐ │ EXTENSION DISPATCH TABLE │ │ │ │ strykelang frontend: │ │ Extended(0, _) → RegexMatch │ │ Extended(1, _) → RegexSubst │ │ Extended(2, _) → HashSlice │ │ Extended(3, _) → ArraySlice │ │ ... │ │ Extended(449, _) → PmapCollect │ │ │ │ zshrs frontend: │ │ Extended(0, _) → HistoryExpand │ │ Extended(1, _) → ZleWidget │ │ Extended(2, _) → ZstyleLookup │ │ ... │ │ Extended(19, _) → ModuleLoad │ │ │ │ awkrs frontend: │ │ Extended(0, _) → FieldGet │ │ Extended(1, _) → FieldSet │ │ Extended(2, _) → PrintColumns │ │ ... │ │ Extended(94, _) → GetlineCmd │ │ │ │ No conflicts — each frontend owns its own ID space. │ └──────────────────────────────────────────────────────────────┘

[0x06] JIT COMPILATION

The JitCompiler analyzes chunks for eligibility and compiles hot paths to native code via Cranelift. Frontends implement JitExtension to provide custom eligibility logic and extension op compilation.

use fusevm::jit::{JitCompiler, JitExtension, NativeCode}; struct MyJit; impl JitExtension for MyJit { fn is_eligible(&self, chunk: &Chunk) -> bool { // custom eligibility logic true } } let compiler = JitCompiler::new(); if compiler.is_eligible(&chunk) { let native: NativeCode = compiler.compile(&chunk); // execute native code instead of interpreter dispatch }
ComponentRole
JitCompilerEligibility analysis + Cranelift IR generation
JitExtensionFrontend-provided trait for custom eligibility + extension op compilation
NativeCodeCompiled native function pointer + metadata
is_eligible()Checks op mix, loop depth, extension usage to decide if JIT is profitable

[0x07] VALUE REPRESENTATION

Value is a tagged enum with fast-path immediates for numbers and booleans, and heap types for strings, arrays, and hashes. String coercion returns Cow<str> via as_str_cow() — borrows Str variants without allocation. Array and hash mutations operate in-place on globals, eliminating clone-modify-writeback.

VariantRepresentationNotes
UndefTag onlyPerl/shell undef / unset
Int(i64)Inline 8 bytesFast-path integer arithmetic
Float(f64)Inline 8 bytesIEEE 754 double
Bool(bool)Inline 1 byteLogical ops, conditionals
Str(Arc<String>)Heap, Arc-sharedUTF-8, Cow<str> coercion borrows without alloc
Array(Vec<Value>)Heap, in-place mutationOrdered collection, direct ref mut access
Hash(HashMap<String, Value>)Heap, in-place mutationKey-value map, direct ref mut access
Status(i32)Inline 4 bytesExit status ($?)
Ref(Box<Value>)HeapPass-by-reference, nested structures
NativeFn(u16)Inline 2 bytesBuiltin function pointer ID

[0x08] CHUNK STRUCTURE

A Chunk is the unit of compiled bytecodes. It contains everything the VM needs to execute a compilation unit — function body, script, or REPL line.

┌────────────────────────────────────────────┐ │ Chunk │ │ │ │ ops: Vec<Op> bytecodes │ │ constants: Vec<Value> constant pool │ │ names: Vec<String> variable name pool │ │ lines: Vec<u32> source line numbers │ │ sub_entries: Vec<(u16,usize)> subroutine IPs │ │ block_ranges: Vec<(usize,usize)> block spans │ │ source: String source file name │ │ │ │ Built by ChunkBuilder::emit() + build() │ │ Serializable via serde (JSON, bincode, etc.) │ └────────────────────────────────────────────┘

[0xFF] LICENSE & LINKS

MIT — Copyright © 2026 MenkeTechnologies

crates.io · docs.rs · GitHub · strykelang · zshrs · awkrs

ONE VM TO RUN THEM ALL.