ffi checkpoint: issue-0046 fixed — nested comptime calls now safe

Logs the 13efc56 lock-in + 248d6e6 fix for issue-0046.
`createComptimeFunction` now saves/restores eight pieces of
outer lowering state so the wrapper fn (which the interp
executes in isolation) does not inherit caller state that
would corrupt its body lowering.

Pack-fn face was already fixed by step 2b; this commit closes
the plain `(\$x: s32)` comptime face.

Test count: 204/204.

Outstanding items reduced to: non-literal comptime args in
mixed-mode pack-fns (degrades to `?` mangle today).
This commit is contained in:
agra
2026-05-27 16:58:14 +03:00
parent 248d6e669c
commit d91a15f6c9

View File

@@ -6,6 +6,45 @@ add a test and make it pass — that's two commits).
## Last completed step
**issue-0046 fix — save/restore outer state in createComptimeFunction**
(commit `248d6e6`, lock-in `13efc56`).
Closes the nested-comptime-call + return bug. The pack-fn face
was incidentally fixed by step 2b's mono refactor (pack-fn
calls now bypass the inline-return-slot setup that leaked into
nested comptime). The plain `($x: s32)` comptime face stayed
on the inline path until this fix.
`createComptimeFunction` wraps a comptime expression into a
fresh fn that the interp executes in isolation. The wrapper
must not inherit the enclosing call's lowering state. Pre-fix
only `func` / `current_block` / `inst_counter` / `scope` /
`current_ctx_ref` were saved. The fix adds eight more:
- `inline_return_target` — outer `lowerComptimeCall`'s
return-routing slot. Was leaking into the wrapper body and
routing the wrapper's `ret` into a different fn's basic
block; the interp executed garbage IR and tripped a null
pointer store at `storeAtRawPtr`.
- `pack_arg_nodes` / `pack_param_count` / `pack_arg_types`
active during pack-mono body lowering. Pack-fn face of 0046
was already fixed by step 2b moving pack-fn calls off the
inline path; these saves close a latent cross-contamination
if a future pack-mono body invokes the comptime interp.
- `comptime_param_nodes` — outer `lowerComptimeCall`'s
`$fmt`-style substitution map.
- `block_terminated` / `target_type` / `func_defer_base`
fn-local flags the wrapper's lowering needs fresh.
`examples/issue-0046.sx` (regression test): `helper :: ($x:
s32) -> s64 { print("inside\n"); return 42; }` called from
`main`. Pre-fix: interp panic at storeAtRawPtr. Post-fix:
prints "inside" then "n=42".
204/204 example tests + `zig build test` green.
---
**M5.A.next.2b.fu1fu4 — all four step-2b follow-ups landed**
(commits `c917f92`, `2e0b97a`, `d30d566`, `159f898` + lock-ins).
@@ -621,7 +660,7 @@ plus 2 codegen fixes surfaced along the way.**
## Current state
- 203/203 example tests pass; `zig build test` green.
- 204/204 example tests pass; `zig build test` green.
- Phase 3.0/3.1/3.2 + M1.0M1.3 + M2.1M2.3 + M3 + M4.0 + M4.A all landed.
- Pack feature step 1 done (1c.A → 1d.B; commits bb6eca6 → 08feb60).
- Pack feature step 2 done — typed `args[$i]` at literal indices
@@ -632,9 +671,8 @@ plus 2 codegen fixes surfaced along the way.**
mixed comptime+pack (159f898). Pack-fns are functionally
complete on the mono path.
- issue-0045 (comptime-fn-with-return verifier crash) fixed (9e78790).
- issue-0046 (nested-comptime-call + return) FILED, not blocking
next slices since builders run inside `#insert`, not inside
public pack-fn bodies.
- issue-0046 (nested-comptime-call + return) FIXED (248d6e6) —
`createComptimeFunction` now saves/restores outer state.
- iOS-sim chess running end-to-end (verified post-step-2b screencap).
- Chess on macOS / iOS-sim / Android all build and run.
@@ -662,7 +700,6 @@ Step 5 (generic `Into(Block)` impl) and step 6 (stdlib
gated on step 3 (and partially step 4).
Outstanding items not blocking step 3:
- issue-0046 (nested-comptime-call + return).
- Non-literal comptime args in mixed-mode pack-fns (degrades
to a `?` mangle segment today — would need comptime
evaluation for proper handling).