P5.2 metadata queries: c_object_paths / link_libraries on the VM

Two abi(.compiler) build-pipeline primitives the sx driver will pass to link:
- c_object_paths() -> List(string)  (#import c companion objects)
- link_libraries() -> List(string)  (#library names)

They live in a new stdlib home library/modules/std/build.sx and are serviced
by comptime_vm.callCompilerFn reading two new BuildConfig fields that main.zig
forwards before the post-link callback. New reusable VM helper makeStringList
builds a List(string) in flat memory from the call's result type offsets
(target-aware); invoke/callCompilerFn now thread ins.ty for that. Legacy
handlers bail loudly (VM-only by nature — post-link; List(string) isn't
faithfully buildable in the legacy Value model, 0141).

Smoke test examples/1662-platform-build-pipeline-queries (AOT + a 1-line C
#source → one object): a post-link callback verifies the VM-built list is
well-formed; build exit 0 only if so (negative-probe confirmed a real guard).

emit_object + link (the actions) deferred to P5.2b — they replace the Zig
driver's auto-emit/auto-link and need a host-installed callback vtable.

703/0 both gates.
This commit is contained in:
agra
2026-06-19 07:42:27 +03:00
parent 7cba33ea6d
commit 44dfdcddf9
13 changed files with 191 additions and 11 deletions

View File

@@ -86,10 +86,20 @@ with ONE welded mechanism. Branch: `reify` (off `master`). Update after every st
> in; VM bail → hard build error (`comptime_vm.last_bail_reason` surfaced by `main.printInterpBailDiag`). Smoke
> test `1661-platform-post-link-vm-list` (AOT) — a post-link callback that GROWS a `List` (0141: works on VM,
> bails on legacy with `struct_get`); build succeeds (exit 0) only via the VM. `flushInterpOutput` deleted (VM
> writes `out` direct via host-FFI). **702/0 both gates.** **NEXT — P5.2:** expose `emit_object` + `link`
> (reuse `target.zig`) + metadata queries (`c_object_paths`/`link_libraries`/host-triple) as `abi(.compiler)`
> primitives taking EXPLICIT args. Then P5.3 (`on_build` slot — invoke WITH the `BuildConfig` arg; needs a VM
> entry that marshals args, the gap `invokeByFuncId` rejects today) · P5.4 (sx `default_build` + delete
> writes `out` direct via host-FFI). **702/0 both gates.** **P5.2 metadata queries DONE (2026-06-19, newest Log
> entry):** `c_object_paths() -> List(string)` + `link_libraries() -> List(string)` are `abi(.compiler)` primitives
> (new stdlib home `library/modules/std/build.sx`), serviced by `comptime_vm.callCompilerFn` reading `BuildConfig`
> fields `main.zig` forwards (`c_object_paths`/`link_libraries`). New reusable VM helper `makeStringList` builds a
> `List(string)` in flat memory (target-aware via the result type's offsets); `invoke`/`callCompilerFn` now thread
> the call's result type (`ins.ty`). Legacy handlers bail loudly (VM-only by nature — post-link). Smoke test
> `1662-platform-build-pipeline-queries` (AOT, C companion → 1 object): a post-link callback checks the VM-built
> list is well-formed; build exit 0 ONLY if so (negative-probe verified: wrong count → "post-link callback
> returned false", exit 1). **703/0 both gates.** **NEXT — P5.2b: `emit_object` + `link` (the ACTIONS).** These
> are NOT data reads — in the end state the Zig driver stops auto-emitting/auto-linking and the sx driver calls
> them, so they need the driver-restructuring (a callback vtable the host installs into the VM, since
> `comptime_vm.zig` can't depend on `core`/`main`/`target`). `link` is fallible (`-> !`) — its failable return
> shape is the new VM piece. Then P5.3 (`on_build` slot — invoke WITH the `BuildConfig` arg; needs a VM entry
> that marshals args, the gap `invokeByFuncId` rejects today) · P5.4 (sx `default_build` + delete
> `#compiler`/`compiler_call`/`compiler_hooks` + the S5a `build_options`/`set_post_link_callback`) — P5.4 kills
> the 4 strict `compiler_call` bails (1609/1614/1615/1616).
> **FINAL atomic step (4F):** (`out` already done — VM-native via libc `write`) handle `interp_print_frames` +
@@ -403,6 +413,28 @@ when reached (sentinels or accessor fns; see the design doc Risks).
`List` growth; orthogonal, see `current/CHECKPOINT-METATYPE.md`.)
## Log
- **P5.2 (metadata queries) — `c_object_paths` / `link_libraries` compiler primitives + the VM `List(string)` builder (2026-06-19).**
Phase 5 step 2 (the read-only slice): two `abi(.compiler)` primitives that the sx build driver will pass to
`link` — `c_object_paths() -> List(string)` (the `#import c` companion `.o`s) and `link_libraries() -> List(string)`
(the `#library` names). They live in a NEW stdlib file `library/modules/std/build.sx` (the Phase 5 home the sx
`default_build` grows into) and are serviced by `comptime_vm.callCompilerFn` reading two new `BuildConfig`
fields (`c_object_paths`/`link_libraries`) that `main.zig` forwards before the post-link callback (alongside
`binary_path`/`target_triple`/…). **Reusable new piece:** `Vm.makeStringList(table, list_ty, items)` builds a
`List(string)` in flat memory — backing array of `string` fat pointers + the `{items,len,cap}` struct, all laid
out from the RESULT type's field offsets/types (target-aware, no hardcoded layout). To get the result type,
`invoke`/`callCompilerFn` now thread the call instruction's `ins.ty` (the only call-result-type need so far).
Legacy (`compiler_lib`) handlers for these bail loudly (`handleBuildPipelineQuery`) — they're VM-only by nature
(the post-link callback always runs on the VM since P5.1), and a `List(string)` isn't faithfully buildable in
the legacy `Value` model (0141). Registered on `bound_fns` so `weldedCompilerFn` recognizes them. **Smoke test**
`examples/1662-platform-build-pipeline-queries` (AOT + a 1-line C `#source` → exactly one C object): a post-link
callback asserts `c_object_paths().len == 1`, `items[0].len > 0`, and iterates `link_libraries()` (liveness
touch) — build exit 0 only if the VM-built list is well-formed. **Negative-probe verified** a real guard (forcing
`len != 2` → "post-link callback returned false", build exit 1). **No unit test for `makeStringList`** —
constructing a `List(string)` `TypeId` in the test harness needs generic instantiation; the corpus test
exercises the real stdlib type end-to-end with a non-empty list + a negative guard instead. **`emit_object` +
`link` (the ACTIONS) deferred to P5.2b** — they must replace the Zig driver's auto-emit/auto-link (not duplicate
it), so they need the driver-restructuring + a host-installed callback vtable (the VM can't depend on
`core`/`main`/`target`). **703/0 both gates** + strict JIT run clean (no `compiler_call` bail).
- **P5.1 (= 4E) — the post-link build driver runs on the VM (NO fallback); smoke test 1661 (2026-06-19).**
Phase 5 step 1: `core.invokeByFuncId` — the post-codegen / post-link callback invocation `main.zig` fires after
`target.link` — now routes the callback through the **comptime VM** (`comptime_vm.tryEval`) instead of the