CHECKPOINT-COMPILER-API: refresh resume banner — Phase 3 read+write done, lowering-time VM wired; next is the dedicated Type TypeId

Records the current state (read side, write side P3.3, lowering-time hardening +
wiring + zeroed context P3.4) and pins the next focused step: a dedicated Type
builtin TypeId (8B) distinct from .any (16B box) — ~123 .any refs across ~25 files,
a cross-cutting change to run as its own session. Paused here at a clean, green
boundary (697/697 both gates) per the decision to not rush it.
This commit is contained in:
agra
2026-06-18 12:30:35 +03:00
parent 6473a4e227
commit 7d59b5eeb6

View File

@@ -26,35 +26,45 @@ with ONE welded mechanism. Branch: `reify` (off `master`). Update after every st
> breaks cross-compilation — host vs target layout — and loses the sandbox. A
> flat-memory VM keeps both while getting native bytes + speed.)
>
> **Next action (2026-06-18):** **Phase 3 is UNDER WAY — the READ side is COMPLETE.** The VM
> hosts seven read-only reflection readers, all on the same plain-`u32`-handle shape (a
> `TypeId` is a `u32`, like `StringId`), so the calls stay clean scalar host-calls — handle
> in, scalar out, no marshaling: `find_type(name) -> TypeId`, `type_kind(t) -> i64`,
> `type_field_count(t) -> i64`, `type_nominal_name(t) -> StringId`,
> `type_field_name(t, idx) -> StringId`, `type_field_type(t, idx) -> TypeId`,
> `type_field_value(t, idx) -> i64`. Each is backed by a `TypeTable` query
> (`findByName`/`kindCode`/`memberCount`/`nominalName`/`memberName`/`memberType`/`memberValue`)
> that BOTH the legacy handler and the VM call, so the two paths can't drift. Together they
> cover everything `reflectTypeInfo` reads. Examples `0628``0630`, all VM-HANDLED natively.
> Parity **691/691** (gate ON and OFF), VM unit tests added. Phase 1.final op-porting was
> already complete (the VM covers scalars/control-flow/aggregates/strings/optionals/enums,
> calls+recursion, the implicit context + full allocator protocol, globals, failables +
> return traces); both comptime call sites route through the VM with legacy fallback.
> **Forward (P3.3) — revised direction:** the WRITE side is ONE `register_type(info)` fn that
> takes a type-info value and **branches on the kind in the compiler** (subsuming
> `define`'s per-kind dispatch), NOT a per-kind `register_struct`. Open design points when
> reached: the flat-memory shape of `info`, the mutable-table / host-ABI-vs-target-ABI
> boundary, pointer-escape/lifetime. Re-expressing `declare`/`define`/`type_info` as sx (the
> metatype, which runs at LOWERING time) needs the VM hardened against malformed
> lowering-time IR first — keep it on the legacy path until then. Phase 2 (bytecode) is the
> orthogonal speed work. **Decisions recorded:** `find_type` returns a non-optional `TypeId`
> using the `unresolved` (0) sentinel, NOT `?Type`; reader names use the `type_*` family to
> avoid colliding with the std metatype builtins (`field_name`/`type_name` in core.sx); the
> write side is a single kind-branching `register_type` — see `PLAN-COMPILER-VM.md` Phase 3
> progress note.
> Build/verify: `zig build && zig build test` (691, gate OFF). Run the corpus ON the VM:
> `zig build test -Dcomptime-flat` (the build flag) OR env `SX_COMPTIME_FLAT=1`. Coverage
> trace: `SX_COMPTIME_FLAT_TRACE=1`.
> **Next action (2026-06-18) — PAUSED at a clean boundary; next step decided.** Phase 3 READ
> and WRITE sides are DONE, and the VM is now WIRED at the lowering-time comptime site
> (hardened, with legacy fallback). The first **HANDLED** lowering-time type-fn is gated on a
> **dedicated `Type` builtin TypeId** — that is the next focused effort (see "THE WALL" below).
>
> Done so far in Phase 3:
> - **READ side (7 readers, dual-path):** `find_type`/`type_kind`/`type_field_count`/
> `type_nominal_name`/`type_field_name`/`type_field_type`/`type_field_value`, each backed by a
> `TypeTable` query both the legacy handler and the VM call (no drift). Examples 06280630.
> - **WRITE side (P3.3, legacy-only at lowering time):** `declare_type` + `pointer_to` + ONE
> kind-branching `register_type` (subsumes `define`'s per-kind dispatch; codes match
> `type_kind`: 1 struct · 2 actual `.@"enum"` · 3 tagged_union · 4 tuple). Idempotent re-fill
> (two-edge import). Plus two fixes (issue 0142): all-void enum → real `.@"enum"` (was a
> verifySizes panic); bare `EnumType.variant` qualified construction. Examples 06310635, 0187.
> - **Lowering-time VM (P3.4):** hardened the VM against malformed lowering-time IR (`refTy`,
> bailing `aggType`, bounds-checked branch targets — bails, never panics); wired `tryEval`
> into `runComptimeTypeFunc` behind the flag with legacy fallback; materialized a zeroed
> lowering-time `Context` (the global isn't built yet at lowering). All measured green.
>
> **THE WALL (next step):** a `Type` *value* is an 8-byte tid, but `.any` (the boxed-any) is a
> 16-byte `{tag,value}` — and they share one TypeId (`.any`). So a `Type` in an aggregate
> (`Member.ty`/`EnumVariant.payload`) is sized 16B while the value is 8B → every lowering-time
> type-fn bails at `const_type` / the Member-array build. Can't make `kindOf(.any)` a word:
> at EMIT time `.any` really is a 16B box (variadic any, 0603), so that would silently corrupt
> it. The correct fix is a **dedicated `Type` builtin TypeId (8B), distinct from `.any`** —
> measured at **~123 `.any` references across ~25 files** (pack.zig has 30), a ~100-touch-point
> cross-cutting change → its own focused session (USER CHOSE to pause rather than rush it).
> Rejected alternatives: a scoped "lowering-mode treats `.any` as a word" flag (silent-wrong on
> a real Any box in a reflection type-fn); scalar-only Type-fns (safe but no real corpus type-fn
> is scalar-only — they all build a Member/variant aggregate).
>
> **Decisions recorded:** `find_type` returns a non-optional `TypeId` using `unresolved`(0), NOT
> `?Type`; reader names use the `type_*` family (avoid colliding with std `field_name`/`type_name`);
> the write side is a single kind-branching `register_type`; the write side stays LEGACY-only
> until the VM runs at lowering time (needs the `Type` TypeId). End-state guarantee: ONE
> evaluator — `interp.zig` deleted; dual-path + fallback are transitional (see PLAN end state).
> Build/verify: `zig build && zig build test` (**697**, gate OFF). Run the corpus ON the VM:
> `zig build test -Dcomptime-flat` OR env `SX_COMPTIME_FLAT=1`. Coverage trace:
> `SX_COMPTIME_FLAT_TRACE=1` (now also prints lowering-time `type-fn` HANDLED/fallback lines).
### (superseded) prior weld resume
Phase 1 done; Phase 2 welded structs were working via reflection + memory-order