comptime VM: Phase 3 — register_type write side + payloadless-enum fixes
The mutating compiler-API, minting types LAZILY at lowering time (single pass,
the existing runComptimeTypeFunc path — so the write side is legacy-only; the
VM isn't wired at lowering time, and the read-side readers stay dual-path):
declare_type(name) -> Type forward nominal handle (≈ declare)
pointer_to(t) -> Type build *T references
register_type(handle, kind, members) ONE kind-branching fill (≈ unified define)
register_type branches on kind IN THE COMPILER (subsuming define's per-kind
dispatch); codes match type_kind: 1 struct, 2 actual .@"enum", 3 tagged_union,
4 tuple. Members are {name: string, ty: Type}. A non-generic `-> Type` builder is
now flagged is_comptime (decl.zig) so its dead body permits the welded calls.
Graph support: forward declare_type handles + pointer_to express a mutually-
recursive A<->B graph (*A, *B, B-by-value) before bodies are filled. register_type
is idempotent — re-filling a nominal slot (a minting module reached via two import
edges) re-mints identically rather than erroring (nominalIdent reads identity from
any nominal kind).
Fixes (issue 0142):
- A fully payloadless comptime-minted enum was minted as an all-void tagged_union,
whose IR size disagrees with its LLVM size -> verifySizes panic. Now mints a real
.@"enum" (register_type kind 2 AND the metatype defineEnum).
- Bare `EnumType.variant` qualified construction of a payloadless variant wasn't
supported (failed for hand-written enums too — the type name lowered to a Type
value). Added in lowerFieldAccess via isPayloadlessVariant; payload-carrying
variants keep their call form.
Examples: 0631 (graph + actual enum + reflection), 0632 (make_enum all-void),
0633/0634/0635 (namespaced / bare / multi-edge import of a minted type), 0187
(qualified variant construction). Unit tests added.
Parity 697/697 (gate OFF and -Dcomptime-flat).
This commit is contained in:
@@ -302,18 +302,36 @@ host through it:
|
||||
- **READ side now complete:** `find_type` + `type_kind` + `type_field_count` +
|
||||
`type_field_name` + `type_field_type` + `type_nominal_name` + `type_field_value` cover
|
||||
everything `reflectTypeInfo` reads.
|
||||
- **Next (P3.3) — ONE `register_type(info)` write fn (revised direction, 2026-06-18):** per
|
||||
the user, the mutating side is NOT per-kind (`register_struct`/`register_enum`/…) but a
|
||||
SINGLE function that takes a type-info value and **branches on the kind in the compiler**,
|
||||
minting the right `TypeInfo`. This subsumes `define`'s `defineStruct`/`defineEnum`/
|
||||
`defineTuple` dispatch into one host-side switch. Open design points to resolve when
|
||||
reached: the flat-memory shape of the `info` argument the sx side passes (a tagged
|
||||
`{ kind, payload }` over the readers' handle types), the mutable-table / host-ABI-vs-
|
||||
target-ABI boundary, and pointer-escape/lifetime (escaping field arrays copied into
|
||||
compiler-owned memory at the boundary). Re-expressing `declare`/`define`/`type_info` as sx
|
||||
(the metatype, which runs at LOWERING time) still needs the VM hardened against malformed
|
||||
lowering-time IR first — keep that on the legacy path until then (see the resume note in
|
||||
CHECKPOINT-COMPILER-API.md).
|
||||
- **(P3.3) WRITE side — `declare_type` + `pointer_to` + ONE kind-branching `register_type` (DONE).**
|
||||
The mutating side is a SINGLE `register_type(handle, kind, members)` that branches on `kind`
|
||||
IN THE COMPILER (subsuming `define`'s `defineStruct`/`defineEnum`/`defineTuple`), plus
|
||||
`declare_type(name) -> Type` (forward handle) and `pointer_to(t) -> Type` (build `*T`
|
||||
references). They take/return real `Type` values (matching meta.sx's declare/define).
|
||||
- **Timing decision (per the user):** mint LAZILY at LOWERING time (single pass, NOT a
|
||||
pre-emit phase, NOT two-pass) — the existing `runComptimeTypeFunc` path. So the write
|
||||
side is **legacy-only** (`compiler_lib` handlers); the VM isn't wired at lowering time, so
|
||||
no VM mirror is needed (the read-side readers stay dual-path for emit-time reflection). A
|
||||
non-generic `-> Type` builder is now flagged `is_comptime` (`decl.zig`) so its dead body
|
||||
permits the welded calls (the comptime-only gate).
|
||||
- **Graph support:** forward `declare_type` handles + `pointer_to` express a
|
||||
mutually-recursive A↔B graph (`*A`, `*B`, B-by-value) before bodies are filled.
|
||||
`register_type` is **idempotent** — re-filling a nominal slot (same module reached via two
|
||||
import edges) re-mints identically instead of erroring (`nominalIdent` reads identity from
|
||||
any nominal kind). `kind` codes match `type_kind`: 1 struct · 2 enum (actual `.@"enum"`) ·
|
||||
3 tagged_union · 4 tuple.
|
||||
- **Two bugs fixed en route** (issue 0142): (a) a fully payloadless comptime-minted enum
|
||||
was minted as an all-void `tagged_union` → `verifySizes` panic; now mints a real
|
||||
`.@"enum"` (both `register_type` kind 2 AND the metatype `defineEnum`). (b) bare
|
||||
`EnumType.variant` qualified construction of a payloadless variant wasn't supported (failed
|
||||
for hand-written enums too) — added in `lowerFieldAccess` (`isPayloadlessVariant`).
|
||||
- Examples: `0631` (graph + actual-enum + reflection), `0632` (make_enum all-void),
|
||||
`0633`/`0634`/`0635` (namespaced / bare / multi-edge import of a minted type), `0187`
|
||||
(qualified variant construction). Parity 697/697 (gate ON and OFF); unit tests added.
|
||||
- **Next (P3.4):** re-express `declare`/`define`/`type_info` as sx over the read+write
|
||||
compiler-API and DELETE the bespoke interp arms — needs the VM hardened against malformed
|
||||
lowering-time IR first (the metatype runs at lowering time), so either harden + wire the VM
|
||||
there, or migrate the metatype onto the legacy compiler-API calls first. Decide when reached.
|
||||
Phase 2 (bytecode) is the orthogonal speed work.
|
||||
|
||||
### Phase 3 — Compiler-API on flat memory (resume the stream — no weld)
|
||||
With native-byte comptime values, re-home the compiler-API:
|
||||
|
||||
Reference in New Issue
Block a user