prometeu-runtime/docs/specs/pbs/files/PRs para Junie.md
Nilton Constantino e784dab34e
pr 43
2026-01-31 17:23:29 +00:00

7.6 KiB
Raw Blame History

PR-04 — Locals opcodes: GET_LOCAL / SET_LOCAL / INIT_LOCAL

Why: PBS let and parameters need first-class support.

Scope

  • Implement opcodes:

    • GET_LOCAL <u16 slot> pushes value slots
    • SET_LOCAL <u16 slot> pops value slots and writes
    • INIT_LOCAL <u16 slot> (optional) for explicit initialization semantics
  • Enforce bounds: local slot index must be within [0..param+local_slots)

  • Enforce slot width: if types are multi-slot, compiler emits multiple GET/SET or uses *_N variants.

Deliverables

  • LocalAddressing utilities

  • Deterministic trap codes:

    • TRAP_INVALID_LOCAL
    • TRAP_LOCAL_WIDTH_MISMATCH (if enforced)

Tests

  • let x: int = 1; return x; works
  • invalid local index traps

Acceptance

  • let works reliably; no stack side effects beyond specified pops/pushes.

PR-05 — Core arithmetic + comparisons in VM (int/bounded/bool)

Why: The minimal executable PBS needs arithmetic that doesnt corrupt stack.

Scope

  • Implement v0 numeric opcodes (slot-safe):

    • IADD, ISUB, IMUL, IDIV, IMOD
    • ICMP_EQ, ICMP_NE, ICMP_LT, ICMP_LE, ICMP_GT, ICMP_GE
    • BADD, BSUB, ... (or unify with tagged values)
  • Define conversion opcodes if lowering expects them:

    • BOUND_TO_INT, INT_TO_BOUND_CHECKED (trap OOB)

Deliverables

  • Deterministic traps:

    • TRAP_DIV_ZERO
    • TRAP_OOB (bounded checks)

Tests

  • simple arithmetic chain
  • div by zero traps
  • bounded conversions trap on overflow

Acceptance

  • Arithmetic and comparisons are closed and verified.

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 isnt executable.

Scope

  • Introduce CALL <u16 func_id>

    • caller pushes args (slots)
    • callee frame allocates locals
  • Introduce RET

    • callee must leave exactly return_slots on operand stack at RET
    • VM pops frame and transfers return slots to caller
  • Define return mechanics for void (return_slots=0)

Deliverables

  • FunctionTable indexing and bounds checks

  • Deterministic traps:

    • TRAP_INVALID_FUNC
    • TRAP_BAD_RET_SLOTS

Tests

  • fn add(a:int,b:int):int { return a+b; }
  • multi-slot return (e.g., Pad flattened)
  • 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
  • Implement/confirm:

    • GfxClear565 (0x1010)
    • InputPadSnapshot (0x2010)
    • InputTouchSnapshot (0x2011)

Deliverables

  • A SyscallRegistry mapping id -> handler + signature

  • Deterministic traps:

    • TRAP_INVALID_SYSCALL
    • TRAP_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
  • 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 ProgramImage from N modules
    • resolves imports to exports
    • produces a single final FunctionTable and code blob

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.pbs that covers:

    • locals
    • arithmetic
    • if
    • function call
    • syscall clear
    • input snapshot
  • Add golden artifacts:

    • 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 VmRunner test 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 Slot explicit:

    • 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.

Work split (what can be parallel later)

  • VM core correctness: PR-01..PR-08 (sequential, contract-first)
  • Debug + tooling: PR-09, PR-12 (parallel after PR-03)
  • Linking/imports: PR-10 (parallel after PR-01)
  • Canonical cartridge: PR-11 (parallel after PR-05)

“Stop the line” rules

  1. If a PR introduces an opcode without stack spec + verifier integration, its rejected.
  2. If a PR changes bytecode layout without bumping version, its rejected.
  3. If a PR adds a feature before the canonical cartridge passes, its rejected.

First implementation target (tomorrow morning, start here)

Start with PR-02 (Opcode spec + verifier) even if you think you already know the bug. Once the verifier exists, the rest becomes mechanical: every failure becomes actionable.

Definition of Done (DoD) for PBS v0 “minimum executable”

A single canonical cartridge runs end-to-end:

  • let declarations (locals)
  • arithmetic (+, -, *, /, %, comparisons)
  • if/else control flow
  • when expression (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)