5.3 KiB
PR-06 — Control flow opcodes: jumps, conditional branches, structured “if”
Why: if must be predictable and verifier-safe.
Scope
-
Implement opcodes:
JMP <i32 rel>JMP_IF_TRUE <i32 rel>JMP_IF_FALSE <i32 rel>
-
Verifier rules:
- targets must be valid instruction boundaries
- stack height at join points must match
Tests
- nested if
- if with empty branches
- branch join mismatch rejected
Acceptance
- Control flow is safe; no implicit stack juggling.
PR-07 — Calling convention v0: CALL / RET / multi-slot returns
Why: Without a correct call model, PBS isn’t executable.
Scope
-
Introduce
CALL <u16 func_id>- caller pushes args (slots)
- callee frame allocates locals
-
Introduce
RET- callee must leave exactly
return_slotson operand stack atRET - VM pops frame and transfers return slots to caller
- callee must leave exactly
-
Define return mechanics for
void(return_slots=0)
Deliverables
-
FunctionTableindexing and bounds checks -
Deterministic traps:
TRAP_INVALID_FUNCTRAP_BAD_RET_SLOTS
Tests
fn add(a:int,b:int):int { return a+b; }- multi-slot return (e.g.,
Padflattened) - void call
Acceptance
- Calls are stable and stack-clean.
PR-08 — Host syscalls v0: stable ABI, multi-slot args/returns
Why: PBS relies on deterministic syscalls; ABI must be frozen and enforced.
Scope
-
Unify syscall invocation opcode:
SYSCALL <u16 id> <u8 arg_slots> <u8 ret_slots>
-
Runtime validates:
- pops
arg_slots - pushes
ret_slots
- pops
-
Implement/confirm:
GfxClear565 (0x1010)InputPadSnapshot (0x2010)InputTouchSnapshot (0x2011)
Deliverables
-
A
SyscallRegistrymapping id -> handler + signature -
Deterministic traps:
TRAP_INVALID_SYSCALLTRAP_SYSCALL_SIG_MISMATCH
Tests
- syscall isolated tests
- wrong signature traps
Acceptance
- Syscalls are “industrial”: typed by signature, deterministic, no host surprises.
PR-09 — Debug info v0: spans, symbols, and traceable traps
Why: Industrial debugging requires actionable failures.
Scope
-
Add optional debug section:
- per-instruction span table (
pc -> (file_id, start, end)) - function names
- per-instruction span table (
-
Enhance trap payload with debug span (if present)
Tests
- trap includes span when debug present
- trap still works without debug
Acceptance
- You can pinpoint “where” a trap happened reliably.
PR-10 — Program image + linker: imports/exports resolved before VM run
Why: Imports are compile-time, but we need an industrial linking model for multi-module PBS.
Scope
-
Define in bytecode:
exports: symbol -> func_id/service entry (as needed)imports: symbol refs -> relocation slots
-
Implement a linker that:
- builds a
ProgramImagefrom N modules - resolves imports to exports
- produces a single final
FunctionTableand code blob
- builds a
Notes
- VM does not do name lookup at runtime.
- Linking errors are deterministic:
LINK_UNRESOLVED_SYMBOL,LINK_DUP_EXPORT, etc.
Tests
- two-module link success
- unresolved import fails
- duplicate export fails
Acceptance
- Multi-module PBS works; “import” is operationalized correctly.
PR-11 — Canonical integration cartridge + golden bytecode snapshots
Why: One cartridge must be the unbreakable reference.
Scope
-
Create
CartridgeCanonical.pbsthat covers:- locals
- arithmetic
- if
- function call
- syscall clear
- input snapshot
-
Add
goldenartifacts:- canonical AST JSON (frontend)
- IR Core (optional)
- IR VM / bytecode dump
- expected VM trace (optional)
Tests
-
CI runs cartridge and checks:
- no traps
- deterministic output state
Acceptance
- This cartridge is the “VM heartbeat test”.
PR-12 — VM test harness: stepper, trace, and property tests
Why: Industrial quality means test tooling, not just “it runs”.
Scope
-
Add
VmRunnertest harness:- step limit
- deterministic trace of stack deltas
- snapshot of locals
-
Add property tests (lightweight):
- stack never underflows in verified programs
- verified programs never jump out of bounds
Acceptance
- Debugging is fast, and regressions are caught.
PR-13 — Optional: Refactor Value representation (tagged slots) for clarity
Why: If current Value representation is the source of complexity/bugs, refactor now.
Scope (only if needed)
-
Make
Slotexplicit:Slot::I32,Slot::I64,Slot::U32,Slot::Bool,Slot::ConstId,Slot::GateId,Slot::Unit
-
Multi-slot types become sequences of slots.
Acceptance
- Simpler, more verifiable runtime.
Definition of Done (DoD) for PBS v0 “minimum executable”
A single canonical cartridge runs end-to-end:
letdeclarations (locals)- arithmetic (+, -, *, /, %, comparisons)
if/elsecontrol flowwhenexpression (if present in lowering)- function calls with params + returns (including
void) - multiple return slots (flattened structs / hardware value types)
- host syscalls (e.g.,
GfxClear565,InputPadSnapshot,InputTouchSnapshot) - deterministic traps (OOB bounded, invalid local, invalid call target, stack underflow)