Browse Source

docs: the record-array-field/open-array codegen bug is fixed, not open

Correct a stale note: the inline-length-word / open-array codegen issue
was resolved by the hybrid QbeGen.ArrBodyItems (per-element expansion for
small record arrays) + DeclRecTemplate/InitRecArray (runtime init for
large ones).  Covered by t_arrrecfld/t_arrrecbig/t_nestarr; the two
docs/wip repros now compile and run (exit 0 / 42).  Also correct the
handoff's P4 addendum.
Eric Streit 4 days ago
parent
commit
38e0b54614
2 changed files with 28 additions and 31 deletions
  1. 5 6
      docs/gaps/README.md
  2. 23 25
      docs/summary_l3_selfhost_fix.md

+ 5 - 6
docs/gaps/README.md

@@ -171,12 +171,11 @@ The `gap13` remainder (standard builtins as identifiers) and `gap14`
 
 
 ## Not represented by a source
 ## Not represented by a source
 
 
-- **Record array field passed as an open array** — a record's inline
-  array field loses its length word when the record sits in static
-  array-of-record data, so passing the field as an `ARRAY OF …` actual
-  reads length 0 and traps.  Worked around by flattening Lower's tables;
-  the general fix and `docs/wip/nested-array-field-bug.mod` remain open
-  (see `docs/summary_l3_selfhost_fix.md`).
+- **Record array field passed as an open array** — *fixed* (hybrid
+  `QbeGen.ArrBodyItems`): small record arrays are expanded per element so
+  each inline array field's length word is in the static data; large ones
+  get a generated runtime init loop.  Covered by `t_arrrecfld`,
+  `t_arrrecbig`, `t_nestarr`; see `docs/summary_l3_selfhost_fix.md`.
 
 
 - ~~**Size-sensitive V3 miscompile**~~ — **root-caused 2026-10-19**: not
 - ~~**Size-sensitive V3 miscompile**~~ — **root-caused 2026-10-19**: not
   size-sensitive, and not a codegen bug at all.  The `ASTDUMP` debug dump
   size-sensitive, and not a codegen bug at all.  The `ASTDUMP` debug dump

+ 23 - 25
docs/summary_l3_selfhost_fix.md

@@ -47,28 +47,27 @@ so no record field is ever passed as an open array.  This matches the
 handoff's "no arrays of records in Lower" rule (which the earlier design
 handoff's "no arrays of records in Lower" rule (which the earlier design
 did not actually satisfy).
 did not actually satisfy).
 
 
-## Deferred: general codegen fix
-
-A correct general fix was implemented and validated on the repro:
-`QbeGen.ArrBodyItems` expands record/class elements per element (reusing
-a record-field walk, with `ArrData` emitting per-element nested
-sub-descriptors via a mirrored `RecStatics`).  It fixes the repro
-(rc 0) **but inflates the compiler image past `QbeGen.sessBuf`
-(4 MiB)** — `AST.arena` is `ARRAY [0..65535] OF NodeRec` and its data
-line grows from ~40 bytes to ~2 MB.  The whole image exceeds 4 MiB and is
-silently truncated (`call ` at EOF → qbe error).
-
-Options for the follow-up:
-
-1. Emit record-array elements in a **compact interleaved form**: merge
-   adjacent zero runs into `z`, emitting only `l <len>` at each array
-   field (e.g. `NodeRec` → `l 8, z 48` per element, ~590 KB total, which
-   fits).  Needs field-size arithmetic; must match `RecItems` layout.
-2. Raise `sessBuf` (band-aid; image keeps growing).
-3. Keep flattening at the source level (as Lower now does).
-
-Also documented: `docs/wip/nested-array-field-bug.mod` (nested-array
-record field) is a related, still-open case.
+## General codegen fix — landed (hybrid)
+
+The general fix (option 1 below) was landed: `QbeGen.ArrBodyItems`
+expands record/class array elements per element when the element
+(recursively) has a nested-array field, with `ArrData` emitting the
+matching per-element sub-descriptors, so every inline array field's
+length word is in the static data.
+
+To stay inside `QbeGen.sessBuf` (4 MiB), it is a **hybrid**: only
+**small** record arrays (data ≤ 131072 bytes) are expanded per element;
+**large** ones (e.g. `AST.arena`, 65536 `NodeRec`) stay a compact zero
+blob, and their elements' inline lengths are set at run time by a
+generated init loop (`QbeGen.DeclRecTemplate` + `QbeGen.InitRecArray`,
+driven from `Lower`).  Plain record arrays (no nested-array field) stay
+a compact zero blob, so `AST.arena` does not balloon.
+
+Fixed and covered by `compiler/tests/t_arrrecfld.mod` (small),
+`t_arrrecbig.mod` (large), `t_nestarr.mod` (nested) and `t_recarr.mod`
+— all run green, and `docs/wip/arrrec-field-openarray.mod` /
+`docs/wip/nested-array-field-bug.mod` now compile and exit 0 / 42.  No
+open codegen case remains here.
 
 
 ## Latent fragility — root-caused (2026-10-19)
 ## Latent fragility — root-caused (2026-10-19)
 
 
@@ -93,6 +92,5 @@ and the gate fails), and the fixpoint is byte-identical across the
 four size-changing commits of 2026-10-19.
 four size-changing commits of 2026-10-19.
 
 
 (The separate record-array-field / open-array codegen issue is described
 (The separate record-array-field / open-array codegen issue is described
-above; the deferred general `ArrBodyItems` fix and
-`docs/wip/nested-array-field-bug.mod` remain open — that is a *distinct*
-bug from the `ASTDUMP` one.)
+above and is **fixed** — that was a *distinct* bug from the `ASTDUMP`
+one, resolved by the hybrid `ArrBodyItems`/`InitRecArray` fix.)