Explorar el Código

test: add per-object self-host fixpoint gate

Eric Streit hace 4 días
padre
commit
5374a11ead

+ 4 - 0
README.md

@@ -22,6 +22,9 @@ Benjamin R10 specs where they don't break classic code
 cd compiler
 ./build.sh      # M2.atg -> scanner/parser/driver -> ./M2
 ./run_tests.sh  # M2 -> gen_ssa/*.ssa -> qbe -> cc -> exit codes
+cd ..
+TMP="$PWD/.scratch/fixpoint" ./bootstrap/fixpoint.sh
+TMP="$PWD/.scratch/fixpoint-separate" ./bootstrap/fixpoint-separate.sh
 ```
 
 Pipeline per test: `./M2 tests/foo.mod` writes
@@ -40,6 +43,7 @@ usage/IO problems (no input, unopenable file) — no aborts.
   its `--separate` mode.
 - **`docs/separate-compilation.md`** — object model, stable symbols, init
   order and current limits.
+- `bootstrap/fixpoint-separate.sh` — per-object self-hosting gate.
 
 ## Quick compile
 

+ 4 - 2
TUTORIAL.md

@@ -145,6 +145,7 @@ runtime/syslib`.  Do not mix `lib/pim` and `lib/iso` in one session.
 ```sh
 cd compiler && ./run_tests.sh
 cd .. && TMP="$PWD/.scratch/fixpoint" ./bootstrap/fixpoint.sh
+TMP="$PWD/.scratch/fixpoint-separate" ./bootstrap/fixpoint-separate.sh
 tools/v3-corpus/corpus.sh
 ```
 
@@ -158,8 +159,9 @@ corpus **519/612 compile-OK, 0 crashes**.
   the shim, or the output changes, and treats a newer compiler binary as an
   ABI event.  There is no content-based ABI version marker yet.
 - Generic instance objects are not emitted separately yet.
-- Per-object self-hosting is not yet a green fixpoint gate; the one-shot
-  fixpoint remains the comparison.
+- Per-object self-hosting is a green gate via
+  `bootstrap/fixpoint-separate.sh`; compiler units use
+  `-legacyopen1d`, while user programs keep pointer views.
 
 For details, see `docs/separate-compilation.md` and
 `docs/plan-separate-compilation.md`.

+ 58 - 0
bootstrap/fixpoint-separate.sh

@@ -0,0 +1,58 @@
+#!/bin/sh
+# Per-object self-hosting gate.
+#
+# Build the V3 compiler as separate objects with the current M2, link
+# stage2, use stage2 to build the same objects/link stage3, and compare
+# every generated .ssa.  The compiler itself is built with the legacy
+# 1-D open-array ABI (the same rule as bootstrap/fixpoint.sh).
+#
+# Usage: ./bootstrap/fixpoint-separate.sh
+# Requires: compiler/M2 and tools/m2make/b_v3/M2make.
+set -eu
+ROOT="$(cd "$(dirname "$0")/.." && pwd)"
+M2="${M2:-$ROOT/compiler/M2}"
+M2MAKE="${M2MAKE:-$ROOT/tools/m2make/b_v3/M2make}"
+SHIM="$ROOT/runtime/syslib/shim.c"
+SRC="$ROOT/compiler/src/M2.mod"
+TMP="${TMP:-$ROOT/.scratch/fixpoint-separate}"
+FLAGS="-legacyopen1d"
+INCS="-I $ROOT/runtime/syslib -I $ROOT/compiler/src -I $ROOT/lib/common"
+
+[ -x "$M2" ] || { echo "missing $M2 (run compiler/build.sh)"; exit 1; }
+[ -x "$M2MAKE" ] || { echo "missing $M2MAKE (run tools/m2make/build_m2.sh)"; exit 1; }
+
+rm -rf "$TMP"
+mkdir -p "$TMP/s2" "$TMP/s3"
+
+build_stage() {
+  bin="$1"; out="$2"; dir="$3"
+  ( cd "$dir" && "$M2MAKE" --separate --m2flag "$FLAGS" \
+      --m2bin "$bin" --shim "$SHIM" $INCS -o "$out" "$SRC" )
+}
+
+echo "=== separate stage2 (built by $M2) ==="
+build_stage "$M2" "$TMP/s2/M2" "$TMP/s2"
+echo "=== separate stage3 (built by stage2) ==="
+build_stage "$TMP/s2/M2" "$TMP/s3/M2" "$TMP/s3"
+
+# Compare the generated per-object IR; object files and executables can
+# contain timestamps/build ids and are not the fixpoint contract.
+fail=0
+for f in "$TMP/s2/gen_ssa"/*.ssa; do
+  b=$(basename "$f")
+  if [ ! -f "$TMP/s3/gen_ssa/$b" ]; then
+    echo "MISSING stage3 object: $b"; fail=1
+  elif ! cmp -s "$f" "$TMP/s3/gen_ssa/$b"; then
+    echo "DIFF: $b"; fail=1
+  fi
+done
+for f in "$TMP/s3/gen_ssa"/*.ssa; do
+  b=$(basename "$f")
+  [ -f "$TMP/s2/gen_ssa/$b" ] || { echo "EXTRA stage3 object: $b"; fail=1; }
+done
+
+if [ "$fail" -ne 0 ]; then
+  echo "SEPARATE FIXPOINT FAILED"
+  exit 1
+fi
+echo "SEPARATE FIXPOINT OK: stage2 == stage3 ($(ls "$TMP/s2/gen_ssa"/*.ssa | wc -l) objects)"

+ 4 - 3
docs/STATUS.md

@@ -202,8 +202,8 @@ declarations still work (`t_fwdproc`, `t_fwdok`).
    per-unit objects (libraries have no `main`), with stable module/class
    symbols, `export data`, and dependency-ordered init calls.  `M2make
    --separate` builds stale objects incrementally and links them.  Core
-   shipped; generic-instance objects, content-based ABI markers and a
-   green per-object self-host fixpoint remain.  See
+   shipped; generic-instance objects and content-based ABI markers
+   remain.  Per-object self-hosting now has its own green gate.  See
    `docs/separate-compilation.md`;
    summary: `summary_session-2026-10-24-separate-compilation.md`.
 5. **Library folders** — `stdlib/` is retired; libraries live in
@@ -237,5 +237,6 @@ cd compiler
 ./build.sh          # M2.atg -> scanner/parser/driver -> ./M2
 ./run_tests.sh      # 283/283
 cd ..
-./bootstrap/fixpoint.sh   # FIXPOINT OK (byte-identical stage2/stage3)
+./bootstrap/fixpoint.sh            # one-shot fixpoint
+TMP="$PWD/.scratch/fixpoint-separate" ./bootstrap/fixpoint-separate.sh
 ```

+ 1 - 1
docs/comparison-PIM4-gm2-V3.md

@@ -124,7 +124,7 @@ change individual cells.
 | PIM coroutines (`PROCESS`, `NEWPROCESS`, `TRANSFER`, `IOTRANSFER`) | ✅ | ✅ | 🔄 `COROUTINE` type/`YIELD` (R10 phase II) | ✅ PIM-style | ✅ (`IOTRANSFER` degrades to a transfer) |
 | ISO `COROUTINES` module | ❌ | ✅ | ❌ | ❌ | ❌ (PIM interface only) |
 | Standard library | ❌ (none defined) | ✅ PIM + ISO libraries | ✅ redesigned R10 library | ✅ TopSpeed libraries (historical) | 🔄 subset in `lib/pim`, `lib/iso`, `lib/common`, `lib/gm2`: ISO/PIM I/O, strings, storage, SysClock, EXCEPTIONS; no termination/coroutine libs |
-| Self-hosting | n/a | ✅ (part of GCC) | n/a (reference compiler under development) | n/a (historical commercial compiler) | ✅ (byte-identical 3-stage fixpoint) |
+| Self-hosting | n/a | ✅ (part of GCC) | n/a (reference compiler under development) | n/a (historical commercial compiler) | ✅ one-shot byte-identical 3-stage fixpoint + per-object stage2/stage3 `.ssa` gate |
 | Backend / target | n/a | GCC (many targets) | reference compiler | x86/DOS/Windows (historical) | QBE → C (amd64 SysV today) |
 
 ## The practical differences

+ 2 - 1
docs/features.md

@@ -167,7 +167,8 @@ Legend: ✅ done · 🔄 partial · ⏸ not started / deferred.
   transitive `.def` resolution, incremental object rebuilds, module init
   functions, dependency-ordered cross-object init, stable symbols,
   exported globals; opaque completion; strict 235 signature checks
-  between a definition and its implementation.
+  between a definition and its implementation; per-object stage2/stage3
+  fixpoint gate.
 - ✅ Module `FINALLY` (program/implementation/local/class bodies), with
   its own optional `EXCEPT`; finalizers run on normal main return in
   reverse initialization order.  `RETURN` in a module body/finally

+ 4 - 4
docs/plan-separate-compilation.md

@@ -160,10 +160,10 @@ cc Prog.o Lib.o runtime/syslib/shim.o -lm -o Prog
    are rebuilt, the compiler binary is an ABI trigger, and relinking
    follows object/shim changes.  Content-based ABI markers are still
    deferred.
-6. **Self-host with separate compilation.**  IN PROGRESS: a linked
-   compiler is buildable from objects, but the separately linked stage-2
-   compiler has a signature-check regression; the one-shot fixpoint
-   remains the gate.
+6. **Self-host with separate compilation.**  DONE:
+   `bootstrap/fixpoint-separate.sh` builds stage2/stage3 as objects and
+   compares all per-object `.ssa`; the compiler uses
+   `-legacyopen1d`, user programs keep pointer views.
 
 ## 6. Tests / gates for each phase
 

+ 14 - 4
docs/separate-compilation.md

@@ -76,13 +76,23 @@ The implementation is split across:
 - **Classes** have stable vtable/method symbols for normal imported
   class use; a class that exists only in a `.def` (no implementation
   object) must still have its vtable materialised by a user object.
-- **Per-object self-hosting** builds a linked compiler from objects, but
-  is not yet a green fixpoint gate: the separately linked stage-2
-  compiler currently mis-checks some definition/implementation
-  signatures.  The one-shot fixpoint remains the gate.
+- **Per-object self-hosting is green:** `bootstrap/fixpoint-separate.sh`
+  builds the compiler as objects with stage1, links stage2, rebuilds with
+  stage2, links stage3, and compares all per-object `.ssa`.  Compiler
+  units use `-legacyopen1d`; user programs use pointer views.
 - `M2 -I` scanning is conservative: import files are read up to a 64 KiB
   buffer and interfaces are ordered by dependency.
 
+## Per-object fixpoint
+
+```sh
+TMP="$PWD/.scratch/fixpoint-separate" ./bootstrap/fixpoint-separate.sh
+# SEPARATE FIXPOINT OK: stage2 == stage3 (11 objects)
+```
+
+The script passes `--m2flag -legacyopen1d` because the compiler itself
+still uses the legacy 1-D call ABI; user programs use pointer-based views.
+
 ## Tests
 
 `compiler/run_tests.sh` has separate-mode gates:

+ 5 - 3
docs/summary_session-2026-10-24-separate-compilation.md

@@ -73,9 +73,11 @@ Manual M2make cross-object class check: `CLib.def/.mod` + `CProg.mod`
   reports `up to date`.
 - Added `SepResProg` (`M2 -c -I`), M2make separate up-to-date,
   single-object recompile and `.def`-change rebuild tests.
-- A per-object compiler build links and runs, but the separately linked
-  stage-2 compiler hits a signature-check regression on SysShim; the
-  one-shot fixpoint remains the gate.
+- Per-object self-hosting is now green.  The stage-2 compiler regression
+  was caused by building compiler units without the legacy 1-D call ABI;
+  `--m2flag -legacyopen1d` plus the new `bootstrap/fixpoint-separate.sh`
+  builds stage2/stage3 as objects and compares all per-object `.ssa`
+  (11 objects).
 
 ## Commits and tags