comptime VM: Phase 3 — type_kind + type_field_value readers (read side complete)

The last two read-only readers the metatype's type_info(T) needs, each backed by
a TypeTable query both the legacy handler and the VM call (no drift):

  type_kind(t: TypeId) -> i64            (kindCode; stable discriminant, total — never bails)
  type_field_value(t: TypeId, idx) -> i64 (memberValue; enum explicit value or ordinal)

kindCode codes (compiler-owned, stable): 0 other / 1 struct / 2 enum /
3 tagged_union / 4 tuple / 5 union / 6 array / 7 vector / 8 error_set.

With these, the READ side is complete: find_type + type_kind + type_field_count +
type_field_{name,type} + type_nominal_name + type_field_value cover everything
reflectTypeInfo reads — a comptime sx fn can fully reflect a struct/enum/tuple
into data with no #builtin.

Example 0630 reflects Color / WindowFlags(flags) / Point. VM unit test added.

Revised forward direction: the write side will be ONE register_type(info) fn that
branches on the kind in the compiler (subsuming define's per-kind dispatch), not a
per-kind register_struct.

Parity 691/691 (gate OFF and -Dcomptime-flat).
This commit is contained in:
agra
2026-06-18 09:47:23 +03:00
parent d23e208430
commit 27bc301651
10 changed files with 252 additions and 29 deletions

View File

@@ -289,11 +289,29 @@ host through it:
exist in `core.sx`). Example `0629` reflects `Pair { lo: Point; hi: Point }` — reads each
field name and the nominal name of a field's type, all folded at `#run`, all VM-HANDLED
natively. Parity **690/690** (gate ON and OFF); VM unit test added.
- **Next (P3.3):** `register_struct` (the first MUTATING fn — mints a `TypeId`; resolve the
mutable-table / host-ABI-vs-target-ABI boundary deliberately, per the open questions),
plus any remaining read-only readers needed to re-express the metatype (kind query,
`field_value_int` for enums). Re-expressing `declare`/`define`/`type_info` as sx (the
metatype, which runs at LOWERING time) still needs the VM hardened against malformed
- **(P3.2b) Kind + enum-value readers — `type_kind` + `type_field_value` (DONE).** The last
two read-only readers the metatype's `type_info(T)` needs, completing the READ side: a
comptime sx fn can now fully reflect a struct/enum/tagged-union/tuple into data with no
`#builtin`. `type_kind(t: TypeId) -> i64` (`TypeTable.kindCode` — a stable, compiler-owned
discriminant: 0 other · 1 struct · 2 enum · 3 tagged_union · 4 tuple · 5 union · 6 array ·
7 vector · 8 error_set; TOTAL — never bails, an unnamed/non-aggregate type reads `other`)
and `type_field_value(t: TypeId, idx: i64) -> i64` (`TypeTable.memberValue` — an enum
variant's explicit value or ordinal; mirrors the `field_value_int` builtin; loud-bail for
a non-enum / out-of-range idx). Example `0630` reflects `Color`/`WindowFlags`(flags)/`Point`.
Parity **691/691** (gate ON and OFF); VM unit test added.
- **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).