# Session 2026-10-24 — separate compilation (core) V3 now builds per-unit objects. The one-shot mode remains the default for the suite/corpus. **Branch:** `master`. **Feature state:** `v3-separate-compilation`. **Gates:** suite **305/305**, fixpoint **OK (3,807,056 bytes)**, corpus **519/612 compile-OK, 0 crashes**. --- ## What shipped - **Stable symbols** - module procedure: `__` - module global: `_` - string/ctor/set pools: `_strN`, `_ctoN`, `_setN` - class vtable: `____vt`; methods include their class - nested procedures: object-local module-prefixed uid - external C procedures: C link name unchanged - **Per-unit codegen** - `M2 -c Target.mod` emits one `.ssa`; the target's own `.def` is found beside it automatically. - Library objects have **no `main`**; the program object has the only `main`. - Every object exports `_init`, including modules with no `BEGIN` body; the program calls imported inits in dependency order. - Top-level data is `export data`, so imported globals resolve. - **Driver** - `M2 -c` lowers the target `.mod` and its own `.def` (for exported data), skips imported definition units, and records imported init calls. - `M2make --separate` scans imports transitively, compiles each unit to `gen_ssa/.o`, and links all objects with `cc` + shim. - **Classes** - stable vtable/method symbols; a manual imported-class virtual call links and returns 42. Client objects do not duplicate imported vtables. ## Tests Added `SepLib`/`SepProg` and `SepEmpty`/`SepEmptyProg`: - library object contains no `main`; - program object contains `main` and links against only the library object (not its `.mod`); - exported data + library BEGIN works (`42`); - bodyless library still exports init and links (`42`). Manual M2make cross-object class check: `CLib.def/.mod` + `CProg.mod` → virtual `Area()` = 42. ## Limits - `M2 -c` requires imported interfaces on the command line; `M2 -I` import scanning is deferred. `M2make --separate` is the transitive resolver. - `--separate` rebuilds all objects (no incremental build/ABI marker). - Generics still need the generic body at the client; no separate generic-instance object emission yet. - The fixpoint gate still compares the one-shot compiler image, not a multi-object self-host. ## Follow-up — `-I` and incremental objects (2026-10-24) - `M2 -c -I dir` now recursively scans target/import source files, resolves `.def` files (including lower-case names), topologically orders them, and parses them before the target. - `M2make --separate` now passes the target through `M2 -c -I ...` instead of an ever-growing explicit interface list. - Stale-object checks use source/interface mtimes; a newer compiler binary is treated as an ABI event; shim changes relink. A second run reports `up to date`. - Added `SepResProg` (`M2 -c -I`), M2make separate up-to-date, single-object recompile and `.def`-change rebuild tests. - 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). ## Follow-up — ABI stamp and definition-only objects (2026-10-24) - `M2make --separate` now records `gen_ssa/.m2abi` containing the ABI version and `--m2flag` settings; a missing/changed stamp rebuilds all objects. - Modules with a `.def` but no `.mod` are compiled to `gen_ssa/.o`, so definition-only data and class vtables link. - Added `CDefProg` (class-only `.def` vtable) and M2make checks for the ABI stamp and definition-only object. - Suite is now 305/305. ## Generic-instance objects (2026-10-24) - M2make detects `MODULE X = G(actuals)` in `.def`/`.mod` files and records `G` as a dependency. - Abstract `GENERIC` modules are ordered but not compiled/linked. - An instance module is compiled to its own `gen_ssa/.o` with the generic template sources in the same session; the program links that object. - Type, value, procedure and generic-class generics work through separate objects. Imported instance implementations are parsed for method information but not lowered into the client object. - Added M2make `GenProg` and coverage for qualified procedure actuals. ## Commits and tags | commit | tag | work | | --- | --- | --- | | `0adc637` | `v3-separate-compilation` | stable symbols, `-c`, library/program split, init list, M2make `--separate`, tests/docs | | `92d11d9` | `v3-separate-compilation-p1` | `M2 -I` transitive resolution, incremental M2make objects, tests/docs | | this docs commit | `v3-separate-compilation-summary` | session summary | | final docs commit | `v3-session-2026-10-24-separate-end` | session tag | No push was performed.