comptime VM: port the WRITE side (declare_type/pointer_to/register_type) -> first HANDLED lowering-time type-fns
declare_type / pointer_to / register_type are now serviced natively in
Vm.callCompilerFn, mirroring the legacy compiler_lib handlers (mint via
@constCast(table) — the lowering-time mint target is &module.types). register_type
reads the []Member slice from flat memory: ref_types is threaded through invoke ->
callCompilerFn so the slice element type (Member = {name: string, ty: Type}) gives
the field offsets + stride; each {name, ty} is decoded and minted with the same
kind branching + dup/payload rejections + idempotent re-fill as legacy.
Key unblock: the synthesized comptime type-fn wrapper was built with return type
.any, so regToValue bailed at the VM<->legacy boundary; changed to .type_value
(the legacy path reads via asTypeId regardless). The compiler-API write type-fns
(0631 register-graph, 0635 multi-edge import) now run HANDLED end-to-end on the VM
at lowering time — parity-correct, on the zeroed lowering-time context (fixed
member arrays, no allocation). The metatype make_enum/define examples still fall
back cleanly through call_builtin(define).
697/0 both gates + EXIT=0.
This commit is contained in:
@@ -31,11 +31,16 @@ with ONE welded mechanism. Branch: `reify` (off `master`). Update after every st
|
||||
> wired end-to-end: foundation (`6844fb9`), resolver flip + full `.any`-ref migration (`94f60c5`),
|
||||
> and the VM models `.type_value` natively (`554871b`). **697/0 BOTH gates + 494 unit tests.**
|
||||
> `first_user` is now **100** (slots 20–99 reserved builtin headroom so future builtins don't
|
||||
> renumber user TypeIds / churn snapshots). What remains is the PAYOFF, no longer gated on the WALL:
|
||||
> port the **WRITE side** (declare_type / register_type / pointer_to) into `Vm.callCompilerFn` +
|
||||
> give the lowering-time path a **REAL Context** (CAllocator thunk func-refs, not zeroed) → the
|
||||
> first **HANDLED** lowering-time type-fn end-to-end on the VM. Today those type-fns run partway on
|
||||
> the VM then bail cleanly at the `define`/`register_type` `call_builtin` → legacy mints (parity).
|
||||
> renumber user TypeIds / churn snapshots). The PAYOFF is now LANDED (`<this commit>`): the
|
||||
> **WRITE side** (declare_type / register_type / pointer_to) is VM-native in `Vm.callCompilerFn`
|
||||
> — the compiler-API type-fns (`0631`/`0635`) run **HANDLED end-to-end on the VM at LOWERING
|
||||
> time** (parity-correct), the first lowering-time comptime to do so; they run on the zeroed
|
||||
> lowering-time context (no allocation). **697/0 both gates + EXIT=0.** What's LEFT toward the
|
||||
> end-state ONE evaluator: (1) re-express the metatype `define`/`make_enum` over the compiler-API
|
||||
> + delete the bespoke interp arms (the `make_enum` examples still fall back cleanly through
|
||||
> `call_builtin(define)`); (2) a REAL lowering-time Context (CAllocator thunk func-refs) for
|
||||
> List-growing type-fns — deferred (no HANDLED type-fn allocates); (3) eventually flip the VM to
|
||||
> default + delete `interp.zig`.
|
||||
>
|
||||
> Done so far in Phase 3:
|
||||
> - **READ side (7 readers, dual-path):** `find_type`/`type_kind`/`type_field_count`/
|
||||
@@ -341,6 +346,27 @@ when reached (sentinels or accessor fns; see the design doc Risks).
|
||||
`List` growth; orthogonal, see `current/CHECKPOINT-METATYPE.md`.)
|
||||
|
||||
## Log
|
||||
- **Phase 3 P3.4 step 5 (VM plan) — WRITE side ported to the VM → FIRST HANDLED lowering-time type-fns (2026-06-18).**
|
||||
Ported `declare_type` / `pointer_to` / `register_type` into `Vm.callCompilerFn`, mirroring the
|
||||
legacy `compiler_lib` handlers (mint via `@constCast(table)` — the same mutable access the
|
||||
read-side `intern` uses; the lowering-time mint target IS `&module.types`). `register_type`
|
||||
reads the `[]Member` slice from FLAT MEMORY: threaded `ref_types` through `invoke` →
|
||||
`callCompilerFn` so the slice's element type (`Member = {name: string, ty: Type}`) gives the
|
||||
field offsets + stride; decodes each `{name, ty}` and branches on `kind` (1 struct · 2 enum ·
|
||||
3 tagged_union · 4 tuple) exactly as legacy (dup-name / payload-on-enum rejections, idempotent
|
||||
re-fill via `nominalIdentOf`). **Key unblock:** the synthesized comptime type-fn wrapper
|
||||
(`createComptimeFunction`/`…WithPrelude`) was built with return type `.any` → `regToValue`
|
||||
bailed at the VM↔legacy boundary; changed to `.type_value` (the legacy path reads via `asTypeId`
|
||||
regardless, so no legacy change). **Result: the compiler-API write type-fns now run HANDLED
|
||||
end-to-end on the VM at LOWERING time** — `0631` (register-graph: 2 HANDLED, A↔B cycle via
|
||||
forward handles + `pointer_to`) and `0635` (multi-edge import: 2 HANDLED), parity-correct. They
|
||||
run on the ZEROED lowering-time context (fixed `.[…]` member arrays, no allocation). The
|
||||
metatype `make_enum`/`define` examples (`0632`) still fall back CLEANLY through
|
||||
`call_builtin(define)` (the separate metatype path — re-expressing it onto the compiler-API is
|
||||
the other half of P3.4). **697/0 BOTH gates + EXIT=0.** On `reify`. **Next:** (optional, deferred)
|
||||
a REAL lowering-time Context (CAllocator thunk func-refs) for List-growing type-fns; and
|
||||
re-express the metatype `define`/`make_enum` over the compiler-API to delete the bespoke interp
|
||||
arms (the end-state: ONE evaluator).
|
||||
- **Phase 3 P3.4 step 4 (VM plan) — model `.type_value` natively in the comptime VM (2026-06-18).**
|
||||
The VM now HANDLES Type values instead of bailing: `kindOf(.type_value)` → `.word`; a new
|
||||
`const_type` exec arm → the word `TypeId.index()`; `regToValue` maps a `.type_value` word back
|
||||
|
||||
Reference in New Issue
Block a user