Files
TerminalBasic/openspec/changes/archive/2026-09-02-phase-2-bytecode-vm/design.md
Chili Palmer a6f005d023 OpenSpec: phase-2-bytecode-vm archiviert, Delta-Specs in Hauptspecs gesynct
- Neue Hauptspecs: bytecode-kompilat, vm-ausfuehrung,
  vm-fehlerbehandlung, konsolen-basisbibliothek
- Erweitert: sprach-frontend (Typisiertes HIR als Sema-Ausgabe),
  kompat-testkorpus (Laufzeitvergleich, Phase-2-Korpusabdeckung)
- Change nach openspec/changes/archive/2026-09-02-phase-2-bytecode-vm
  verschoben; openspec validate --all: 9/9

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-09-02 11:33:51 +02:00

130 lines
6.4 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# Design — Phase 2: Bytecode und VM
## Context
Motivation siehe proposal.md („Why"). Ausgangslage: `tb-frontend` liefert
AST + Diagnosen, wirft aber alle Sema-Ergebnisse (Typen, Slots,
Konstanten) weg; `tb-vm` ist ein Stub. Rahmenbedingungen aus PLAN.md und
docs/tbvm-design.md: Instant-Compile (Single-Pass, keine
Optimierungspasses), Interpreter-Tempo in Lua-Klasse, Werte-Modell als
Tagged Enum mit `Rc` (kein GC — der Dialekt kennt keine Zyklen),
`step()`-basierte, unterbrechbare VM. Entscheidungen dieses Dokuments
wurden am 2026-09-02 in einer Explore-Session getroffen und bestätigt.
## Goals / Non-Goals
**Goals:**
- Durchgängige Pipeline Quelltext → HIR → Bytecode → Ausführung mit
byte-genauer Korpus-Ausgabe.
- Debugger-taugliche VM-Architektur, ohne dass der Debugger selbst
(Phase 5) schon gebaut wird.
- Builtin-ABI, die Phase 3 nur noch „auffüllt".
**Non-Goals:**
- Mehrmodul-Linking und `COMMON`-Verknüpfung über Moduleinheiten (die
Prozedurtabelle ist modul-qualifiziert angelegt, verknüpft wird ab
Phase 5 mit `.MAK`-Projekten).
- Datei-E/A, Ereigniszustellung (Hooks über Tick-Flag-Wort genügen),
`tbc build --exe`, Optimierungspasses jeder Art.
## Decisions
### D1 — Typisiertes HIR als Sema-Ausgabe (statt Doppel-Resolution oder Side-Tables)
Die Sema wird vom reinen Checker zum Lowering-Pass: Ausgabe ist ein
eigener HIR-Baum (Namen → Slots, Typen an jedem Ausdruck, Konstanten
gefaltet, implizite Konvertierungen als explizite Knoten). Verworfen:
(a) Codegen resolved selbst nochmal — dupliziert die Typisierungslogik,
Divergenz-Bugs; (b) Side-Tables am AST — der AST hat keine Node-IDs,
Pointer-Keys sind fragil. Das HIR hält das Single-Pass-Budget ein (alle
Pässe linear, keine globale Analyse) und macht den Codegen zum dummen
Tree-Walk.
### D2 — Monomorpher Opcode-Satz, Konvertierungen als eigene Opcodes
Da das HIR jede Konvertierung materialisiert, sind alle Arithmetik-,
Vergleichs- und Konvertierungs-Opcodes typrein (`ADD_I16`, `ADD_F64`,
`CONV_I16_F64`, `STR_EQ` …). Kein Tag-Dispatch in heißen Pfaden; die
Konvertierungsmatrix lebt an genau einer Stelle (HIR-Erzeugung), der
Interpreter bleibt eine enge `match`-Schleife. Preis: breiter
Opcode-Satz (~150200) — Fleiß, keine Komplexität. Encoding: Opcode
1 Byte; Slots u16; Konstantenpool-Index u16 (Wide-Variante bei Bedarf);
Sprünge u32-absolut innerhalb der Prozedur (fixup-freundlich).
### D3 — Host-Trait mit blockierenden Aufrufen (statt Yield-Modell)
Alle Konsolenwirkungen laufen über ein `Host`-Trait (Ausgabe, Zeile
lesen, Abbruchprüfung). Host-Calls dürfen blockieren und sind aus
VM-Sicht atomar; Ticks (Breakpoints, Einzelschritt, Abbruch) greifen an
Anweisungsgrenzen. Verworfen: VM „yieldet" bei E/A und der Einbetter
erfüllt Requests — debuggerfreundlicher, aber deutlich komplexer; für
den IDE-Debugger reicht die Anweisungsgranularität. Implementierungen:
Konsolen-Host (`tbc run`), Capture-Host (Test-Harness), später
Zellenpuffer-Host (Phase 3/5).
### D4 — Fehlerbehandlung: Handler-Zustand modul-global + pro Frame
`ON ERROR GOTO` setzt den modulweiten Handler, `ON LOCAL ERROR` einen
Frame-lokalen, der ihn verdeckt. Beim Fehler: aktiven Handler suchen
(erst Frame-Kette nach LOCAL-Handlern, sonst Modul-Handler), Stack bis
zum Handler-Frame abwickeln, gemerkten Anweisungs-Offset + Frame für
`RESUME` sichern, `ERR`/`ERL` setzen. Fehler bei aktiver Behandlung →
sofortiger Abbruch (keine Kaskade). Grundlage ist die Original-Hilfe
(Topics `ON ERROR`, `RESUME`); ein Emulator-Spike ist nur nötig, falls
die Doku Lücken lässt.
### D5 — GOSUB-Stack pro Frame
`GOSUB` legt die Rücksprungadresse auf einen separaten Stack im
aktuellen Frame (kein Call-Frame); `RETURN` bedient zuerst diesen
Stack. Prozedurende mit nicht-leerem GOSUB-Stack verwirft ihn (wie beim
Vorbild beim Verlassen der Prozedur).
### D6 — Runner-Verhalten `STOP`/`CONT`
`STOP` außerhalb der IDE terminiert mit Meldung + Exit-Code ≠ 0; `END`/
Programmende → Exit-Code 0. `CONT` ist Direktmodus-Konzept der IDE
(Phase 5) — die `step()`-Architektur liefert Suspend/Resume dort gratis.
### D7 — `.tbc` mit eigenem Writer/Reader (kein serde)
Format bleibt stabil, dokumentiert und unabhängig von Crate-Versionen;
Abschnittstabelle erlaubt spätere Abschnitte (FORMS ab Phase 4) ohne
Versionsbruch. Prozedurtabelle trägt von Beginn an die Modulkennung.
### D8 — Benchmarks als früher Bestandteil, nicht als Abschluss
Das Compile-Budget-Harness (generiertes ~50k-Zeilen-Projekt) entsteht
früh in der Phase, damit Architekturfehler (z. B. quadratische
Fixup-Listen) sofort auffallen. Criterion-Benches für VM-Durchsatz
(Schleifen/Strings); Ergebnisse werden in docs/tbvm-design.md
festgehalten. Ein Dispatch-Mikrobenchmark vorab wurde verworfen
(vorzeitige Optimierung — gemessen wird am echten Interpreter).
## Risks / Trade-offs
- [Sema-Umbau destabilisiert Phase-1-Ergebnis] → Diagnostik-Verhalten
ist durch die 33 Frontend-Tests + Korpus fixiert; Umbau gilt erst als
fertig, wenn alle Bestandstests grün sind.
- [Opcode-Breite macht Interpreter-Match unübersichtlich] → Opcodes
systematisch gruppieren (Makro/Tabelle generiert Emit + Dispatch
konsistent); Dokumentationspflicht in tbvm-design.md.
- [Konvertierungsmatrix enthält falsch rekonstruierte Zellen] →
jede Zelle mit Fundstelle in der Original-Hilfe belegen; unklare
Zellen als `TODO verify` im Korpus markieren (Konvention besteht).
- [PRINT-Zahlformatierung (SINGLE/DOUBLE-Stellen) weicht ab] →
byte-genaue Korpustests decken Randfälle ab; Formatierungsregeln aus
der Original-Hilfe ableiten, Abweichungen dokumentieren.
- [Blockierende Host-Calls verhindern Abbruch während INPUT] →
akzeptiert für Phase 2 (Abbruchprüfung obliegt dem Host); die
Ereignisschleifen-Architektur (Phase 4) kann den Host asynchroner
gestalten, ohne die VM zu ändern.
## Migration Plan
Rein additiv (neue Crate-Inhalte, neue Sema-Ausgabe neben bestehender
Diagnostik). Kein Rollback-Plan nötig; PLAN.md-Haken und
docs/tbvm-design.md-Fortschreibung erfolgen beim Abschluss der Phase.
## Open Questions
- Exakte Ergebnistyp-Regel für `^` sowie Stellenzahl der
SINGLE/DOUBLE-Textdarstellung: wird beim Ausformulieren der Matrix
aus der Original-Hilfe übernommen; ändert weder Ansatz noch
Task-Zuschnitt.
- Ob `ERL` beim Vorbild auch Zeilennummern aus `GOSUB`-Zielen o. ä.
Sonderfällen meldet: bei Doku-Lücke entscheidet ein kurzer
Emulator-Check; betrifft nur eine Matrix-/Handlerzelle.