|
|
@@ -31,28 +31,43 @@ flip once the inline emit is removed.
|
|
|
Still scaffolding (inline emit untouched); suite **200/200**, FIXPOINT OK
|
|
|
(3,401,129 bytes).
|
|
|
|
|
|
-## Gaps found (all fixable, all required for the flip)
|
|
|
-
|
|
|
-1. **`DefUnit` builds no AST.** Its `ConstBlock/TypeBlock/VarBlock/
|
|
|
- ProcHeading` loop never `AstAppend`s, so a definition module's AST has
|
|
|
- no decls; its proc *headings* (which consume backend temps) cannot be
|
|
|
- replayed. Fix: append to `astDecl` in `DefUnit`.
|
|
|
-2. **Owned-table size.** `MaxProc=64` / `MaxSym=512` are sized for one
|
|
|
- unit; a full-session re-emit needs every module's procs/vars. Growing
|
|
|
- them grows the compiler image (watch the 4 MiB `sessBuf`).
|
|
|
-3. **Nested-module globals.** `QualNode(outer, name)` does not see a
|
|
|
- nested scope's non-exported globals; `ReenterGlobals` re-enters them
|
|
|
- but with `curMod = -1` (empty `mod`), so `GlobalRef` falls back to
|
|
|
- `$name` instead of `$<outer>_<name>`.
|
|
|
-4. **Definition-module proc replay** must emit only the heading
|
|
|
- (`BeginFunc`/`FuncParam`/`AbortFunc`), like `LowerMethodHeadings`.
|
|
|
-5. Possibly more, revealed once a full session is compared.
|
|
|
-
|
|
|
-## Plan
|
|
|
-
|
|
|
-1. Fix (1) and (4); grow tables (2) within the image budget.
|
|
|
-2. Compare `Lower.LowerSession`'s image against the legacy session image
|
|
|
- for the compiler's own sources (the real test).
|
|
|
-3. Fix the remaining gaps until the session image byte-matches.
|
|
|
-4. Flip: remove the inline emit; keep `Lower` per unit; the fixpoint
|
|
|
- becomes the gate.
|
|
|
+## Progress (`ce2fc67`, tag `v3-lower7-session`)
|
|
|
+
|
|
|
+- **`DefUnit` now builds an AST** (proc headings recorded as
|
|
|
+ `NkProcDecl`); `LowerDecls` replays a bodyless proc as a heading.
|
|
|
+- **Session re-emit works** for small sessions: `lower_ok_files` added,
|
|
|
+ and `DBasicProg`, `DQualProg`, `TQual` (def-CONST), `TQualP`
|
|
|
+ (def-PROC) byte-match. Fixes: image named after the program module;
|
|
|
+ `MaterializeGlobals` also materializes TYPE/CLASS names;
|
|
|
+ `SymTab.ReenterModGlobal` keeps nested-module globals'
|
|
|
+ `"<outer>_<name>"` symbols; `AST.Init` once per session under `-lower`.
|
|
|
+
|
|
|
+Suite **204/204**; FIXPOINT OK (3,405,813 bytes).
|
|
|
+
|
|
|
+## Remaining gaps
|
|
|
+
|
|
|
+1. **AST-arena size (fundamental).** `LowerSession` needs every unit's
|
|
|
+ AST alive at once, but `AST.MaxNodes = 65536` is sized for one unit;
|
|
|
+ the compiler's session overflows it (`MakeNode` → `NoNode`, later
|
|
|
+ units dump `(nil)`). Growing the arena past the 4 MiB `sessBuf` is
|
|
|
+ not viable. So the session re-emit **cannot** handle the compiler —
|
|
|
+ the flip must instead emit **per unit** at each unit's END (AST valid,
|
|
|
+ scope open), which is the two-state / inline-emit-removal problem.
|
|
|
+2. **External procs.** `storage_prog` differs: Lower emits
|
|
|
+ `$malloc_6(l link, ...)` where the legacy emits `$malloc(...)` — the
|
|
|
+ `ext` flag in `Lower.NoteProc` is hardcoded `FALSE` and `Mangled`'s
|
|
|
+ `ProcLink` fails after scopes close.
|
|
|
+3. Definition-module proc replay (done), nested globals (done).
|
|
|
+
|
|
|
+## Plan (revised)
|
|
|
+
|
|
|
+The session re-emit is a useful *verification* tool for small sessions,
|
|
|
+but the flip needs per-unit emission. Concretely:
|
|
|
+
|
|
|
+1. Fix the external-proc flag (`NoteProc` should record `IsExternal` at
|
|
|
+ the EXTERNAL arm, not at the heading).
|
|
|
+2. Decide the flip mechanism: **two `QbeGen` states**, or remove the
|
|
|
+ grammar's inline `QbeGen` calls. Either is a big, non-incremental
|
|
|
+ change; the fixpoint is the gate.
|
|
|
+3. Then `Lower` runs per unit (AST valid, scope open), which also makes
|
|
|
+ the external-proc and module-level resolution work naturally.
|