ReviewOS

zig-utils/zig-js

VM: instantiate environment-mode block and switch declarations exactly

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

Parent: #465 Related: #788, #771

Original verified boundary

Ordinary-function frame-mode block/CaseBlock lowering landed in 81ce8599 for #788. Program and suspendable environment-mode declaration planning is a separate unfinished path; hoisting a function through def_var does not create its distinct block lexical binding.

Both the cfef054 baseline and the #788 candidate fail these exact required-bytecode witnesses while their forced tree-walker runs pass:

  • test/annexB/language/global-code/switch-case-global-init.js: ReferenceError: f. The outer legacy binding must already exist as undefined before the switch.
  • test/annexB/language/global-code/switch-case-global-block-scoping.js: TypeError: value is not a function. Mutation of the block binding must not overwrite the outer legacy binding.

The #788 candidate deliberately leaves the existing environment-mode switch path unchanged; its ordinary-function 2 -> 159 / 159 witness gain is not evidence for these program cases.

Required implementation

  • Give programs and environment-mode function bodies an explicit declaration plan using the shared Annex B eligibility model.
  • Perform global/eval/function declaration instantiation at the actual variable record, including lexical conflicts, restricted/non-configurable global properties, deletability, and arguments/parameter exclusions.
  • Instantiate block and whole-switch lexical function bindings before statements/case tests, exactly once per entry, and perform only the eligible source-order legacy copy at declaration evaluation.
  • Preserve live closure identity, strict/sloppy distinctions, labelled and conditional declarations, repeated entries, abrupt completion, and suspend/resume across generator/async bodies.
  • Keep ordinary frame-mode O(1) slots and captured-record selection intact. No source rewriting, forced global definitions, snapshots of live bindings, or fallback disguised as required-bytecode execution.

Acceptance

  • Both named global witnesses pass required bytecode with no fallback, followed by the complete relevant global/eval Annex B sets.
  • Suspendable and program block/switch identity has exact value, side-effect, exception, and completion-order tests.
  • Moving-GC, allocation-failure, no-GIL/TSan, interruption and full integration gates cover the new environment path.
  • Land issue-linked conventional commits and record default-tier flips separately from required-bytecode admission gains.

This is compiler/declaration semantics work, not a request to change native stacks, queues/jobs, Promise/Worker lifecycle, or iterator implementations.

Landed implementation and evidence

  • a4c035b7: synchronous generator native ownership and precise saved caller roots (#791).
  • 11c00cab: canonical realm identity on owned environments (#793).
  • 8d772d15: environment-mode declaration plans, block/CaseBlock records, exact legacy copies, native patterns and loop-head lifetime.

Required-bytecode global Annex B: 65/153 -> 153/153 (+88); paired forced-tree-walker runs all pass. Required-bytecode and forced-tree-walker direct/indirect eval Annex B: 469/469 -> 469/469, unchanged. The 15 measured default-tier subtrees have byte-identical reports: 3215 passes and the same existing generator eval-var-scope-syntax-err failure; 0 default-tier flips and no measured regressions.

Final local sharded suite: 2006 pass, 1 platform skip, 0 fail/leak. Declaration checks 6/6 in Debug and ReleaseSafe+TSan; realm identity and generator root-failure checks also pass TSan. Actual moving-GC, no-GIL suspended invocation identity and allocation-failure checks pass. Seed-1 ReleaseFast fuzz: 400 default and 300 verify programs, 0 failures. Full details and per-subtree counts are in the commit descriptions.

The required pushed CI matrix has passed; see completed integration below. The async native-borrow audit remains on #791; known lifecycle gates remain on #722/#792. No queue/job/Worker/Promise implementation was changed.

Completed integration

CI run 33113309062 completed successfully on main commit 8a1398ffc04e9e30987f968693667c7271ca3ce1, a descendant containing this implementation. All 53 executed jobs succeeded (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. Together with the measured local evidence in the comments, this completes this issue's acceptance.

Environment-mode declaration implementation: 8d772d15 (#790). Its observed eval-context defects were subsequently fixed and verified in #795 and #797. The separate async native-borrow audit remains open in #791; native stack/queue/job and lifecycle work is not claimed complete.

9 days ago

Implementation is in progress against 81ce859. The saved baseline has 65 PASS / 88 FAIL across all 153 global-code required-bytecode witnesses. The first candidate reaches 137 PASS / 16 FAIL; all 16 remaining failures share uncaptured environment-mode for/for-of head leakage, now corrected in the verification build. Both originally named switch witnesses pass that first candidate.

The candidate adds immutable declaration plans, invocation-owned Annex B eligibility, exact block/CaseBlock lexical records, source-order legacy copies, complete global preflight, and global property Set/descriptor semantics. It also admits async block declarations and preserves generator suspension. Five focused groups pass, including concurrent no-GIL generator invocations and compiler allocation-failure replay. Full integration and the final corpus comparison are still pending; this is not closure evidence. Stack/queue/job, Promise/Worker lifecycle, and iterator implementations remain untouched.

9 days ago

Progress: all 153 Annex B global-code witnesses now pass both forced tree-walker and required-bytecode execution (baseline required mode: 65/153). Program and suspendable chunks own immutable declaration plans; each invocation owns eligibility state. Block/CaseBlock lexical instantiation, exact source-order legacy copies, uncaptured loop-head records, and native var-pattern References are covered. Two integration-discovered prerequisites are tracked separately: #791 active generator native ownership during moving GC, and #793 stable realm-global environment identity. Focused declaration tests pass in Debug and ReleaseSafe+TSan; actual moving-GC and root-allocation-failure witnesses pass. The final combined sharded run and expanded conformance/fuzz evidence are still pending, so this is not closure.

9 days ago

#795 landed as e0ed6eb1: exact callee parameter metadata/strictness, complete destructuring initialization context, and body-entry restoration.

The seven generator/async-generator eval-parameter cases now pass. Across 13 measured subtrees, 11,487 pass / 7 fail became 11,494 pass / 0 fail; the paired required-bytecode corpus has those same seven gains and zero new failing paths. Its 369 pre-existing failures remain explicit, so this does not close the broader VM-admission work.

Full local units (2013 pass, one platform skip), focused ReleaseSafe/TSan, and 700 seeded fuzz iterations pass. Pushed CI is queued. The audit's remaining private-name/field-initializer context defects are tracked in #797; native stack/queue/job and lifecycle mechanisms were untouched.

Sign in to comment on this issue.