ReviewOS

zig-utils/zig-js

Generator: establish callee parameter metadata for direct eval

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

Parents: #465, #790. Observed while validating #794; independent of its capture change.

Implemented by e0ed6eb1. Local verification and pushed CI are complete.

At main 8d772d1, all five pinned Test262 generator/async-generator eval-var-scope-syntax-err.js variants fail identically before and after the nested-capture change. They expect SyntaxError from parameter initialization, but receive ReferenceError:

function* f(a = eval("var a = 42")) {}
assert.throws(SyntaxError, function () { f(); });

Affected paths:

  • test/language/statements/generators/eval-var-scope-syntax-err.js
  • test/language/expressions/generators/eval-var-scope-syntax-err.js
  • test/language/statements/async-generator/eval-var-scope-syntax-err.js
  • test/language/expressions/async-generator/eval-var-scope-syntax-err.js
  • test/language/expressions/async-generator/named-eval-var-scope-syntax-err.js
  • test/language/expressions/object/method-definition/gen-meth-eval-var-scope-syntax-err.js
  • test/language/expressions/object/method-definition/async-gen-meth-eval-var-scope-syntax-err.js

The existing Interpreter.checkEvalLexicalConflicts uses cur_func_params during a parameter default to reject colliding eval var declarations. Ordinary calls install the callee's parameter metadata, but vm.makeGenerator and makeAsyncGenerator bind parameters without installing that metadata. This makes the conflict check depend on the caller's parameters and lets execution reach the parameter TDZ instead of rejecting the eval declaration.

Acceptance:

  • Install and restore exact callee parameter metadata for suspendable parameter initialization, including abrupt exits and nested calls.
  • All seven existing failures flip, with paired forced-tree-walker/required-bytecode evidence and unchanged adjacent parameter/eval cases.
  • Cover caller/callee name collisions, destructuring/defaults, and restoration after an exception.
  • Audit the other parameter-initialization context fields without changing native job/queue/lifecycle mechanisms or masking errors.
  • Focused safety and full integration checks pass.
  • Pushed CI passes before closing.

No implementation is included in the #794 capture change. The pinned corpus revision is 4249661.

The current audit also found pre-existing private-name and field-initializer context defects, tracked separately with exact before/after probes in #797. The #795 fix does not claim those behaviors are corrected.

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

The local fix now flips seven pinned Test262 cases, including the two object-method variants outside the original five-path list.

Measured against main e1afde2 on pinned corpus 4249661:

  • Eleven generator, async, ordinary-function, arrow, and object-method subtrees: 3061 pass / 7 fail → 3068 pass / 0 fail.
  • Paired forced-tree-walker/required-bytecode witnesses over 2492 eligible positive files: 2116 pass / 376 fail → 2123 pass / 369 fail. The exact diff contains those seven gains and zero new failing paths. Existing required-bytecode admission/semantic failures remain visible; this is not a claim of complete VM conformance.
  • Eighteen focused witnesses: 2 pass / 16 fail → 18 pass, covering strict/sloppy callee context, caller-name collisions, nested ordinary/generator/async body eval, destructuring/computed/rest defaults, arguments bindings, mutable parameters inside const initializers, and abrupt restoration.

The shared BindingInitialization helper now installs/restores callee formal metadata across the whole operation; all four function-aware entry points use callee strictness. Function-body entry clears inherited parameter-expression flags. No queue/job/lifecycle mechanism changed. Focused debug regressions and the allocation-failure replay pass (2/2); full integration and sanitizer verification remain pending. No commit has landed yet.

9 days ago

Landed directly on main as e0ed6eb1, authored and committed as Chris with no trailers.

Final local verification:

  • 11,487 pass / 7 fail → 11,494 pass / 0 fail across 13 measured Test262 subtrees. The added 8,426 class cases were byte-identical before/after; no regressions in the measured scope.
  • Paired required-bytecode/tree-walker corpus witnesses: 7 gains, zero new failing paths among 2492 eligible files; 369 pre-existing required-mode failures remain.
  • 18 focused paired semantic witnesses pass, including eager async rejection and context restoration.
  • Full units: 2013 pass, 1 platform skip, 0 failures/leaks, four shards, 348.9 s.
  • ReleaseSafe + TSan: 47/47 parameter and 45/45 generator checks pass (overlapping filters), including allocation-failure restoration and concurrent generator tracing.
  • Seeded threadfuzz: 400 default + 300 verify, seed 1, zero failures.
  • GC inventory remains valid: 9 cell kinds, 27 pointer surfaces, 21 boundary tags.

Audit follow-up #797 remains open for private-name/field-initializer context. No native stack, queue, job, Promise/Worker lifecycle, or Map/Set iterator mechanism was changed.

Evidence retained locally in /tmp/zig-js-795-params.qYytM4 (README maps final vs historical diagnostics). Temporary corpus files and obsolete owned binaries were cleaned up. Pushed CI is pending; leaving this issue open until that gate is verified.

9 days ago

Landed #797 in 8a1398ff — fix(eval): retain lexical private contexts across suspension (#797), directly on origin/main as Chris, without trailers.

This completes the private-name/field-initializer context follow-up discovered during #795: exact lexical capture for ordinary and suspendable functions, correct nested-class shadowing, parameter/resume context restoration, early rejection of unknown private names, and indirect-eval/dynamic-constructor isolation. Existing native stack, queue, job, and root ownership is reused unchanged; #791 remains separate.

Measured evidence: 24 paired-mode witnesses improve 5 -> 24 pass; all 18 measured Test262 diagnostic subtrees are unchanged (12,075 pass / 2 existing fail, zero flips or regressions in this scope). The 9,643 eligible positive paired corpus files retain 8,475 passes and the identical 1,168 existing required-bytecode failures. Full units: 2,017 pass, 1 skip, 0 fail/leak. ReleaseSafe + TSan passes private 4/4, parameter 47/47, generator 45/45 (overlap); 400 default + 300 verify seeded fuzz programs pass. The GC witness proves actual receiver relocation.

#797 has updated local acceptance and remains open for pending required CI. Evidence: /tmp/zig-js-797-context.2QwDxk/README.md. This does not claim the parent VM-admission goal is complete.

Sign in to comment on this issue.