From a26237cb8783f50417c9932a1af04611852b92db Mon Sep 17 00:00:00 2001 From: bQUARKz Date: Sat, 7 Mar 2026 13:55:41 +0000 Subject: [PATCH] delete runtime file docs --- docs/runtime/16-host-abi-and-syscalls.md | 170 --------------------- docs/runtime/ARCHITECTURE.md | 184 ----------------------- docs/runtime/ISA_CORE.md | 119 --------------- 3 files changed, 473 deletions(-) delete mode 100644 docs/runtime/16-host-abi-and-syscalls.md delete mode 100644 docs/runtime/ARCHITECTURE.md delete mode 100644 docs/runtime/ISA_CORE.md diff --git a/docs/runtime/16-host-abi-and-syscalls.md b/docs/runtime/16-host-abi-and-syscalls.md deleted file mode 100644 index b5b192b7..00000000 --- a/docs/runtime/16-host-abi-and-syscalls.md +++ /dev/null @@ -1,170 +0,0 @@ -# Host ABI and Syscalls - -Domain: host ABI structure -Function: normative - -This chapter defines the structural ABI between the PVM and the host environment. - -It focuses on: - -- syscall identity; -- load-time resolution; -- instruction-level call semantics; -- metadata shape; -- argument and return-slot contract. - -Operational policies such as capabilities, fault classes, determinism, GC interaction, budgeting, and blocking are split into a companion chapter. - -## 1 Design Principles - -The syscall ABI follows these rules: - -1. **Stack-based ABI**: arguments and return values are passed through VM slots. -2. **Canonical identity**: host services are named by stable `(module, name, version)`. -3. **Load-time resolution**: symbolic host bindings are resolved before execution. -4. **Metadata-driven execution**: arity and result shape come from syscall metadata. -5. **Not first-class**: syscalls are callable but not ordinary function values. - -## 2 Canonical Syscall Identity - -Syscalls are identified by a canonical triple: - -``` -(module, name, version) -``` - -Example: - -``` -("gfx", "present", 1) -("input", "state", 1) -("audio", "play", 2) -``` - -This identity is: - -- language-independent; -- toolchain-stable; -- used for linking and capability gating. - -## 3 Syscall Resolution - -The host maintains a registry: - -``` -(module, name, version) -> syscall_id -``` - -At load time: - -1. the cartridge declares required syscalls by canonical identity; -2. bytecode encodes host-backed call sites as `HOSTCALL `; -3. the loader validates and resolves those identities; -4. the loader rewrites `HOSTCALL ` into `SYSCALL `; -5. the executable image uses only numeric syscall ids at runtime. - -Raw `SYSCALL ` is not valid in a PBX pre-load artifact and must be rejected there. - -## 4 Syscall Instruction Semantics - -Pre-load artifact form: - -``` -HOSTCALL -``` - -Final executable form: - -``` -SYSCALL -``` - -Where: - -- `` indexes the program-declared syscall table; -- `` is the final numeric host syscall id. - -Execution steps: - -1. the VM looks up syscall metadata by ``; -2. the VM ensures the argument contract is satisfiable; -3. the syscall executes in the host environment; -4. the syscall produces exactly the declared `ret_slots`. - -## 5 Syscall Metadata Table - -Each syscall is defined by metadata. - -Conceptual structure: - -``` -SyscallMeta { - id: u32 - module: string - name: string - version: u16 - arg_slots: u8 - ret_slots: u8 - capability: CapabilityId - may_allocate: bool - cost_hint: u32 -} -``` - -Fields: - -| Field | Description | -| -------------- | ------------------------------------------------ | -| `id` | Unique numeric syscall identifier | -| `module` | Canonical module name | -| `name` | Canonical syscall name | -| `version` | ABI version of the syscall | -| `arg_slots` | Number of input stack slots | -| `ret_slots` | Number of return stack slots | -| `capability` | Required capability | -| `may_allocate` | Whether the syscall may allocate VM heap objects | -| `cost_hint` | Expected cycle cost | - -The loader uses this table to resolve identities and validate declared ABI shape. - -## 6 Arguments and Return Values - -Syscalls use the same slot-oriented argument/return philosophy as ordinary calls. - -### Argument passing - -Arguments are pushed before the syscall. - -Example: - -``` -push a -push b -SYSCALL X -``` - -### Return values - -After execution, the syscall leaves exactly `ret_slots` values on the stack. - -Composite results use multiple stack slots rather than implicit hidden structures. - -## 7 Syscalls as Callable Entities (Not First-Class) - -Syscalls behave like call sites, not like first-class guest values. - -This means: - -- syscalls can be invoked; -- syscalls cannot be stored in variables; -- syscalls cannot be passed as function values; -- syscalls cannot be returned as closures. - -Only user-defined functions and closures are first-class. - -## 8 Relationship to Other Specs - -- [`16a-syscall-policies.md`](16a-syscall-policies.md) defines operational policies layered on top of this ABI. -- [`15-asset-management.md`](15-asset-management.md) defines asset-domain semantics behind some syscall families. -- [`08-save-memory-and-memcard.md`](08-save-memory-and-memcard.md) defines persistent save-domain semantics. -- [`02a-vm-values-and-calling-convention.md`](02a-vm-values-and-calling-convention.md) defines the slot/call philosophy reused by the syscall ABI. diff --git a/docs/runtime/ARCHITECTURE.md b/docs/runtime/ARCHITECTURE.md deleted file mode 100644 index 4f03840b..00000000 --- a/docs/runtime/ARCHITECTURE.md +++ /dev/null @@ -1,184 +0,0 @@ -Prometeu VM Runtime — Canonical Architecture - -Status: canonical - -This document is the authoritative architectural reference for the Prometeu VM runtime. It reflects the implementation as it exists today and defines the invariants that govern architectural changes in the VM layer. - -Scope boundary: - -- PROMETEU itself is a fantasy handheld / fantasy console with a broader machine model, firmware model, cartridge model, and virtual hardware surface. -- This document does not define the whole PROMETEU machine. -- This document defines the VM/runtime subsystem that executes bytecode inside that machine. -- For broader machine-level framing, see [`../specs/README.md`](../specs/README.md). - -Document roles: - -- This file is normative for VM/runtime architecture. -- Detailed domain specifications may live under `docs/runtime/specs/`, but they must not contradict this document where VM/runtime invariants are concerned. -- Roadmaps, agendas, and PR proposals may discuss future changes, but they are not authoritative until this document is updated. -- The machine-wide fantasy console framing lives in the runtime specs manual and related domain specs; those documents are complementary, not competing VM architecture sources. - -Maintenance rule: - -- Any PR that changes VM/runtime architectural invariants must update this document in the same change. - - -1. Overview ------------ - -- Stack‑based virtual machine - - Operand stack + call frames; bytecode is fetched from a ROM/program image with a separate constant pool. -- GC‑managed heap - - Non‑compacting mark–sweep collector; stable object handles (`HeapRef`) while live. Sweep invalidates unreachable handles; objects are never moved. -- Closures (Model B) - - First‑class closures with a heap‑allocated environment. The closure object is passed to the callee as a hidden `arg0` when invoking a closure. -- Cooperative coroutines - - Deterministic, cooperative scheduling. Switching and GC occur only at explicit safepoints (`FRAME_SYNC`). -- Unified syscall ABI - - PBX pre-load artifacts declare canonical host bindings in `SYSC` and encode call sites as `HOSTCALL `. The loader resolves and patches them to numeric `SYSCALL ` before verification/execution. Capability gating is enforced at load and checked again defensively at runtime. Syscalls are not first‑class values. - - -2. Memory Model ----------------- - -2.1 Stack vs Heap - -- Stack - - Each running context has an operand stack plus call frames (locals, return bookkeeping). Primitive values (integers, floats, booleans) reside on the stack. Heap objects are referenced by opaque `HeapRef` values on the stack. - - The VM’s current operand stack and frames are GC roots. - -- Heap - - The heap stores runtime objects that require identity and reachability tracking. Handles are `HeapRef` indices into an internal object store. - - The collector is mark–sweep, non‑moving: it marks from roots, then reclaims unreachable objects without relocating survivors. Indices for live objects remain stable across collections. - -2.2 Heap Object Kinds (as used today) - -- Arrays of `Value` - - Variable‑length arrays whose elements may contain further `HeapRef`s. -- Closures - - Carry a function identifier and a captured environment (a slice/vector of `Value`s stored with the closure). Captured `HeapRef`s are traversed by the GC. -- Coroutines - - Heap‑resident coroutine records (state + wake time + suspended operand stack and call frames). These act as GC roots when suspended. - -Notes: -- Literals like strings and numbers are sourced from the constant pool in the program image; heap allocation is only used for runtime objects (closures, arrays, coroutine records, and any future heap kinds). The constant pool never embeds raw `HeapRef`s. - -2.3 GC Roots - -- VM roots - - Current operand stack and call frames of the running coroutine (or main context). -- Suspended coroutines - - All heap‑resident, suspended coroutine objects are treated as roots. Their saved stacks/frames are scanned during marking. -- Root traversal - - The VM exposes a root‑visitor that walks the operand stack, frames, and coroutine records to feed the collector. The collector then follows children from each object kind (e.g., array elements, closure environments, coroutine stacks). - - -3. Execution Model -------------------- - -3.1 Interpreter Loop - -- The VM runs a classic fetch–decode–execute loop over the ROM’s bytecode. The current program counter (PC), operand stack, and call frames define execution state. -- Function calls establish new frames; returns restore the caller’s frame and adjust the operand stack to the callee’s declared return slot count (the verifier enforces this shape statically). -- Errors - - Traps (well‑defined fault conditions) surface as trap reasons; panics indicate internal consistency failures. The VM can report logical frame endings such as `FrameSync`, `BudgetExhausted`, `Halted`, end‑of‑ROM, `Breakpoint`, `Trap(code, …)`, and `Panic(msg)`. - -3.2 Safepoints - -- `FRAME_SYNC` is the only safepoint. - - At `FRAME_SYNC`, the VM performs two actions in a well‑defined order: - 1) Garbage‑collection opportunity: root enumeration + mark–sweep. - 2) Scheduler handoff: the currently running coroutine may yield/sleep, and a next ready coroutine is selected deterministically. -- No other opcode constitutes a GC or scheduling safepoint. Syscalls do not implicitly trigger GC or rescheduling. - -3.3 Scheduler Behavior (Cooperative Coroutines) - -- Coroutines are cooperative and scheduled deterministically (FIFO among ready coroutines). -- `YIELD` and `SLEEP` take effect at `FRAME_SYNC`: - - `YIELD` places the current coroutine at the end of the ready queue. - - `SLEEP` parks the current coroutine until its exact `wake_tick`, after which it re‑enters the ready queue at the correct point. -- `SPAWN` creates a new coroutine with its own stack/frames recorded in the heap and enqueues it deterministically. -- No preemption: the VM never interrupts a coroutine between safepoints. - - -4. Verification Model ----------------------- - -4.1 Verifier Responsibilities - -The verifier statically checks bytecode for structural safety and stack‑shape correctness. Representative checks include: - -- Instruction well‑formedness - - Unknown opcode, truncated immediates/opcodes, malformed function boundaries, trailing bytes. -- Control‑flow integrity - - Jump targets within bounds and to instruction boundaries; functions must have proper terminators; path coverage ensures a valid exit. -- Stack discipline - - No underflow/overflow relative to declared max stack; consistent stack height at control‑flow joins; `RET` occurs at the expected height. -- Call/return shape - - Direct calls and returns must match the declared argument counts and return slot counts. Mismatches are rejected. -- Syscalls - - The verifier runs only on the patched executable image. `HOSTCALL` is invalid at verification time. Final `SYSCALL` IDs must exist per `SyscallMeta`, and arity/declared return slot counts must match metadata. -- Closures - - `CALL_CLOSURE` is only allowed on closure values; the callee function must be known; argument counts for closure calls must match. -- Coroutines - - `YIELD` context must be valid; `SPAWN` argument counts are validated. - -4.2 Runtime vs Verifier Guarantees - -- The verifier guarantees structural correctness and stack‑shape invariants. It does not perform full type checking of value contents; dynamic checks (e.g., numeric domain checks, polymorphic comparisons, concrete syscall argument validation) occur at runtime and may trap. -- Capability gating for syscalls is enforced at load from cartridge capability flags and checked again at runtime by the VM/native interface. - - -5. Closures (Model B) — Calling Convention -------------------------------------------- - -- Creation - - `MAKE_CLOSURE` captures N values from the operand stack into a heap‑allocated environment alongside a function identifier. The opcode _pushes a `HeapRef` to the new closure. -- Call - - `CALL_CLOSURE` invokes a closure. The closure object itself is supplied to the callee as a hidden `arg0`. User‑visible arguments follow the function’s declared arity. -- Access to captures - - The callee can access captured values via the closure’s environment. Captured `HeapRef`s are traced by the GC. - - -6. Unified Syscall ABI ------------------------ - -- Identification - - Host bindings are declared canonically as `(module, name, version)` in PBX `SYSC`, then executed as numeric IDs after loader patching. Syscalls are not first‑class values. -- Metadata‑driven - - `SyscallMeta` defines expected arity and return slot counts. The loader resolves `HOSTCALL` against this metadata and rejects raw `SYSCALL` in PBX pre-load artifacts; the verifier checks final IDs/arity/return‑slot counts against the same metadata. -- Arguments and returns - - Arguments are taken from the operand stack in the order defined by the ABI. Returns use multi‑slot results via a host‑side return buffer (`HostReturn`) which the VM copies back onto the stack, or zero slots for “void”. A mismatch in result counts is a fault/panic per current hardening logic. -- Capabilities - - Cartridge capability flags are applied before load-time host resolution. Missing required capability aborts load; invoking a syscall without the required capability also traps defensively at runtime. - - -7. Garbage Collection ----------------------- - -- Collector - - Non‑moving mark–sweep. -- Triggers - - GC runs only at `FRAME_SYNC` safepoints. -- Liveness - - Roots comprise: the live VM stack/frames and all suspended coroutines. The collector traverses object‑specific children (array elements, closure environments, coroutine stacks). -- Determinism - - GC opportunities and scheduling order are tied to `FRAME_SYNC`, ensuring repeatable execution traces across runs with the same inputs. - - -8. Non‑Goals -------------- - -- No RC -- No HIP -- No preemption -- No mailbox - - -9. Notes for Contributors --------------------------- - -- Keep the public surface minimal and metadata‑driven (e.g., syscalls via `SyscallMeta`). -- Do not assume implicit safepoints; schedule and GC only at `FRAME_SYNC`. -- When adding new opcodes or object kinds, extend the verifier and GC traversal accordingly (children enumeration, environment scanning, root sets). -- Update this document alongside any architectural change that affects runtime invariants. diff --git a/docs/runtime/ISA_CORE.md b/docs/runtime/ISA_CORE.md deleted file mode 100644 index cdd403d2..00000000 --- a/docs/runtime/ISA_CORE.md +++ /dev/null @@ -1,119 +0,0 @@ -### Prometeu Bytecode — Core ISA - -Status: bytecode-level normative - -This document defines the stable Core ISA surface for the Prometeu Virtual Machine at the bytecode level. It specifies instruction encoding, the stack evaluation model, and the instruction set currently available in the canonical opcode surface used by encoder, decoder, disassembler, assembler, verifier, and VM execution. - -Machine boundary: - -- PROMETEU is not "just the VM". It is the broader fantasy console/handheld machine. -- This document covers only the bytecode ISA of the VM subsystem embedded in that machine. - -Authority rule: - -- This document is normative for bytecode-level encoding and opcode surface. -- Runtime-wide invariants still live in [`../../ARCHITECTURE.md`](../../ARCHITECTURE.md). -- If a bytecode-level rule here conflicts with runtime architecture, the conflict must be resolved explicitly in both documents; neither should drift silently. - -#### Encoding Rules - -- Endianness: Little‑endian. -- Instruction layout: `[opcode: u16][immediate: spec.imm_bytes]`. -- Opcodes are defined in `prometeu_bytecode::isa::core::CoreOpCode`. -- Immediate sizes and stack effects are defined by `CoreOpCode::spec()` returning `CoreOpcodeSpec`. -- All jump immediates are absolute u32 byte offsets from the start of the current function. - -#### Stack Machine Model - -- The VM is stack‑based. Unless noted, operands are taken from the top of the operand stack and results are pushed back. -- Types at the bytecode level are represented by the `Value` enum; the VM may perform numeric promotion where appropriate (e.g., `Int32 + Float -> Float`). -- Stack underflow is a trap (TRAP_STACK_UNDERFLOW). -- Some operations may trap for other reasons (e.g., division by zero, invalid indices, type mismatches). - -#### Instruction Set (Core) - -- Execution control: - - `NOP` — no effect. - - `HALT` — terminates execution (block terminator). - - `JMP u32` — unconditional absolute jump (block terminator). - - `JMP_IF_FALSE u32` — pops `[bool]`, jumps if false. - - `JMP_IF_TRUE u32` — pops `[bool]`, jumps if true. - - `TRAP` — software trap/breakpoint (block terminator). - -- Stack manipulation: - - `PUSH_CONST u32` — load constant by index → _pushes `[value]`. - - `PUSH_I64 i64`, `PUSH_F64 f64`, `PUSH_BOOL u8`, `PUSH_I32 i32` — push literals. - - `POP` — pops 1. - - `POP_N u32` — pops N. - - `DUP` — `[x] -> [x, x]`. - - `SWAP` — `[a, b] -> [b, a]`. - -- Arithmetic: - - `ADD`, `SUB`, `MUL`, `DIV`, `MOD` — binary numeric ops. - - `NEG` — unary numeric negation. - -- Comparison and logic: - - `EQ`, `NEQ`, `LT`, `LTE`, `GT`, `GTE` — comparisons → `[bool]`. - - `AND`, `OR`, `NOT` — boolean logic. - - `BIT_AND`, `BIT_OR`, `BIT_XOR`, `SHL`, `SHR` — integer bit operations. - -- Variables: - - `GET_GLOBAL u32`, `SET_GLOBAL u32` — access global slots. - - `GET_LOCAL u32`, `SET_LOCAL u32` — access local slots (current frame). - -- Functions and scopes: - - `CALL u32` — call by function index; argument/result arity per function metadata. - - `RET` — return from current function (block terminator). - - `MAKE_CLOSURE u32,u32` — create closure from `(fn_id, capture_count)`. - - `CALL_CLOSURE u32` — invoke closure with `arg_count` user arguments. - -- Concurrency: - - `SPAWN u32,u32` — create coroutine for `(fn_id, arg_count)`. - - `YIELD` — request cooperative yield at the next safepoint. - - `SLEEP u32` — request suspension for a logical tick duration. - -- System/Timing: - - `HOSTCALL u32` — PBX pre-load host binding call by `SYSC` table index; the loader must resolve and rewrite it before verification or execution. - - `SYSCALL u32` — final numeric platform call in the executable image; raw `SYSCALL` in PBX pre-load artifacts is rejected by the loader. - - `INTRINSIC u32` — final numeric VM-owned intrinsic call. - - `FRAME_SYNC` — yield until the next frame boundary (e.g., vblank); explicit safepoint. - -For exact immediates and stack effects, see `CoreOpCode::spec()` which is the single source of truth used by the decoder, disassembler, and verifier. - -#### Canonical Decoder Contract - -- The canonical decoder is `prometeu_bytecode::decode_next(pc, bytes)`. -- It uses the Core ISA spec to determine immediate size and the canonical `next_pc`. -- Unknown or legacy opcodes must produce a deterministic `UnknownOpcode` error. - -#### Module Boundary - -- Core ISA lives under `prometeu_bytecode::isa::core` and re‑exports: - - `CoreOpCode` — the opcode enum of the core profile. - - `CoreOpcodeSpec` and `CoreOpCodeSpecExt` — spec with `imm_bytes`, stack effects, and flags. -- Consumers (encoder/decoder/disasm/verifier) should import from this module to avoid depending on internal layout. - -#### Scope Notes - -- "Core ISA" in the current repository means the canonical opcode surface implemented by the runtime today. -- It includes closures, coroutines, `HOSTCALL` patching semantics, `INTRINSIC`, and `FRAME_SYNC`. -- It does not, by itself, define higher-level runtime policy such as crash taxonomy, firmware behavior, cartridge lifecycle, or host service organization. Those belong to the canonical runtime architecture and related specs. - -#### FRAME_SYNC — Semantics and Placement (Bytecode Level) - -- Semantics: - - `FRAME_SYNC` is a zero-operand instruction and does not modify the operand stack. - - It marks a VM safepoint for GC and the cooperative scheduler. In `CoreOpcodeSpec` this is exposed as `spec.is_safepoint == true`. - - On execution, the VM may suspend the current coroutine until the next frame boundary and/or perform GC. After resuming, execution continues at the next instruction. - -- Placement rules (representable and checkable): - - `FRAME_SYNC` may appear anywhere inside a function body where normal instructions can appear. It is NOT a block terminator (`spec.is_terminator == false`). - - Instruction boundaries are canonical: encoders/emitters must only place `FRAME_SYNC` at valid instruction PCs. The verifier already enforces “jump-to-boundary” and end-exclusive `[start, end)` function ranges using the canonical layout routine. - - Entrypoints that represent a render/update loop SHOULD ensure at least one reachable `FRAME_SYNC` along every long-running path to provide deterministic safepoints for GC/scheduling. This policy is semantic and may be enforced by higher-level tooling; at the bytecode level it is representable via `spec.is_safepoint` and can be counted by static analyzers. - -- Disassembly: - - Disassemblers must print the mnemonic `FRAME_SYNC` verbatim for this opcode. - - Tools MAY optionally annotate it as a safepoint in comments, e.g., `FRAME_SYNC ; safepoint`. - -- Verification notes: - - The bytecode verifier treats `FRAME_SYNC` as a normal instruction with no stack effect and no control-flow targets. It is permitted before `RET`, between basic blocks, and as the last instruction of a function. Jumps targeting the function end (`pc == end`) remain valid under the end-exclusive rule.