|
|
@@ -0,0 +1,58 @@
|
|
|
+# V3 self-hosting fixpoint reached
|
|
|
+
|
|
|
+Tag `v3-fixpoint`. Main suite 111/111.
|
|
|
+
|
|
|
+## The milestone
|
|
|
+
|
|
|
+V3, **compiled by V3 itself**, compiles the whole compiler source set to
|
|
|
+a **byte-identical** `gen_ssa/M2.ssa`:
|
|
|
+
|
|
|
+```
|
|
|
+M2 (built by gm2 -fiso) compiles SymTab QbeGen M2S M2P M2(driver)
|
|
|
+ -> gen_ssa/M2.ssa (1,991,439 bytes)
|
|
|
+M2self (built by V3 from that image) compiles the same set
|
|
|
+ -> gen_ssa/M2.ssa
|
|
|
+cmp: *** IDENTICAL (FULL FIXPOINT) ***
|
|
|
+```
|
|
|
+
|
|
|
+So Stage 2 (V3 compiling itself) reproduces Stage 1's image exactly —
|
|
|
+the self-hosting fixpoint.
|
|
|
+
|
|
|
+## The last fix
|
|
|
+
|
|
|
+`QbeGen.InitHeap`, for a nested array (`ARRAY … OF ARRAY …`) on the
|
|
|
+heap/stack, allocated each element sub-array with `NewHeap` but never
|
|
|
+**initialised its descriptor header**. A local `ARRAY [0..15] OF Name`
|
|
|
+therefore had sub-descriptors with garbage headers, and passing
|
|
|
+`names[i]` to an `ARRAY OF CHAR` formal trapped in the scanner's
|
|
|
+`GetName`. Fix: call `InitHeap(eb, elem)` on each sub-array.
|
|
|
+
|
|
|
+Repro:
|
|
|
+
|
|
|
+```modula2
|
|
|
+TYPE Name = ARRAY [0..63] OF CHAR;
|
|
|
+PROCEDURE P;
|
|
|
+ VAR names: ARRAY [0..3] OF Name; i: CARDINAL;
|
|
|
+ PROCEDURE Set (VAR s: ARRAY OF CHAR); BEGIN s[0] := 'x' END Set;
|
|
|
+BEGIN i := 0; Set(names[i]) END P;
|
|
|
+```
|
|
|
+
|
|
|
+## How we got here (this arc)
|
|
|
+
|
|
|
+From "sources compile and link" to the fixpoint, each step a real V3
|
|
|
+runtime/ABI bug with a minimal repro: nested modules; inline record
|
|
|
+array fields; the NUL-terminated string model; `p^` as a `VAR` actual;
|
|
|
+de-eagered NIL guards; off-by-one string scans; short-circuit `AND`/`OR`;
|
|
|
+and now nested-array heap initialisation.
|
|
|
+
|
|
|
+## Remaining (bootstrap polish)
|
|
|
+
|
|
|
+- `bootstrap/fixpoint.sh`: automate Stage1 gm2 → Stage2 V3 → Stage3 V3
|
|
|
+ and `cmp` the images (the manual chain above already shows Stage2 ==
|
|
|
+ Stage1). Stage-aware CR flag: `-m` for gm2, no `-m` for V3.
|
|
|
+- Cross-stage `FileIO` selection (stage 1 uses the host `FileIO`; stage 2+
|
|
|
+ the self-hosted `runtime/syslib/FileIO`).
|
|
|
+
|
|
|
+## Files
|
|
|
+
|
|
|
+`compiler/src/{QbeGen.mod,M2.lst}`.
|