ReviewOS

zig-utils/zig-js

VM: retain live frame bindings for nested suspendable closures

#794
Closed chris opened this 9 days ago ·
9 days ago

Parent: #465. Related: #771, #785, #790, #791.

Ordinary frame-mode functions reject every nested generator/async template in Compiler.compileFunction, because suspendable bodies resolve captured names through Environment Records while enclosing locals occupy frame slots.

At main 8d772d1, a paired witness with an ordinary outer(value) returning a generator and sibling setter passes forced tree-walker mode but fails required bytecode with template_plain_rejected_unsupported_lowering. This is an eligibility gap, not a default-tier semantic flip.

Implement exact, live defining-environment projections using the existing frame-backed binding views. Preserve parameter/body separation, TDZ and const semantics, mapped arguments, nested frame boundaries, with/catch/per-iteration record ordering, eval-created bindings, escaping lifetimes, GC relocation, and existing no-GIL publication/slot synchronization. No local-value copies or hidden interpreter fallback.

Acceptance:

  • Nested generator, async function, and async generator templates compile under ordinary VM functions.
  • Paired semantic witnesses cover live writes, TDZ/const, parameters, nested captures, runtime scopes, and suspension.
  • OOM and GC ownership checks cover the new creation path; focused no-GIL/TSan checks pass.
  • Exact-parent Test262 comparisons and full local units are recorded, separately from required-tier gains.
  • Pushed integration gates pass.

Scope excludes native stack/queue/job drivers and async/Worker lifecycle changes, which are being handled separately.

Completed integration

CI run 33113309062 completed successfully on main commit 8a1398ffc04e9e30987f968693667c7271ca3ce1, which contains this fix. All 53 executed jobs succeeded, including all four unit and TSan-unit shards, Linux no-GIL TSan, functional/no-GIL corpus gates, fuzz profiles, ABI, Wasm, Test262 parallel, and docs. The scheduled-only nightly job was skipped, not counted as a pass. The local evidence above plus this descendant integration run completes this issue's acceptance.

9 days ago

Landed e1afde2d — feat(vm): capture frame bindings in suspendable closures (#794), after the independent #796 GC ownership prerequisite.

Nested generators, async functions and async generators now retain immutable defining-environment plans and capture live frame-backed binding records. Ordinary templates only carry a nullable plan pointer. This preserves parameter/body separation, TDZ/const, mapped arguments, nested frames, named self bindings, with/catch/iteration records, eval-created bindings, escaping lifetimes, and existing no-GIL synchronization. The caller's runtime block/handler depth is restored exactly; there is no local-value copy or hidden fallback.

Final local evidence (Zig 0.17.0-dev.1441+d5181a9; Test262 4249661):

  • Full sharded units: 2011 pass, 1 platform skip, 0 fail/leak.
  • Twelve semantic cases pass in forced-tree-walker and required-bytecode modes. The dedicated capture witness changes required mode 0/1 -> 1/1; its tree-walker result remains passing.
  • ReleaseSafe+TSan: new capture/OOM/no-GIL checks 4/4, generator-related checks 45/45, actual moving-GC witness 1/1.
  • Six Test262 diagnostics are byte-identical to 8d772d1: generator expression/declaration passes 289/265, async-function expression/declaration 93/74, async-generator expression/declaration 621/300. Total 1642 passes plus five unchanged failures now tracked in #795; 0 default-tier flips and no measured regressions.
  • All 1388 passing positive corpus witnesses retain both execution modes; the same five pre-existing eval failures remain. This preserved corpus coverage is not claimed as a new admission gain.
  • Seed-1 ReleaseFast fuzz: 400 default + 300 verify programs, zero failures.

The first full run exposed #796 (2009 pass, 1 skip, 1 fail); that failed evidence was retained, the cause fixed with a deterministic witness, and the full suite rerun. No performance publication, corpus exclusion, or native stack/queue/job/lifecycle implementation change. Pushed integration remains pending, so this issue stays open.

Sign in to comment on this issue.