ReviewOS

zig-utils/zig-js

Parser: early-error scans skip expressions inside destructuring patterns

#920
Closed glennmichael123 opened this 9 days ago ·
9 days ago

Parent: #904; related #899 and #919.

The shared scanSuperAndArgs traversal skips expressions embedded in binding/assignment patterns. Destructuring declarations scan only their initializer; for-in/of scans omit the target, catch scans omit the binding, and parameter checks scan top-level defaults but not parameter patterns. Consequently await, yield, arguments, and super restrictions can be bypassed with pattern defaults or computed keys.

An 18-case differential against actual JSC and Node/V8 confirms 13 invalid programs accepted by both zig-js tree-walker and required VM. A statement preceding the invalid declaration executes, violating early-error non-execution. Two direct invalid controls reject and three valid nested-function/plain-pattern controls remain accepted.

Examples that must reject:

class C { static { if (false) { let [x = await 0] = []; } } }
class C { static { for (let [x = await 0] of []) {} } }
class C { static { try {} catch ([x = await 0]) {} } }
class C { x = () => { let {[arguments]: x} = {}; }; }
async function f([x = await 0]) {}
function* g({[yield 0]: x}) {}
class C extends Object { m() { let [x = super()] = []; } }

Root fix: traverse pattern computed keys/defaults and nested/rest patterns everywhere the owning early-error scan runs, retaining the distinct boundaries for lexical arrows and ordinary functions. Do not classify binding identifiers as IdentifierReferences. Cover declarations, assignments, loops, catches, function/method/arrow parameters, nested patterns, and valid shadowing/function boundaries. Batch the related restrictions, verify early rejection in both execution modes, and compare affected test262 subtrees before/after.

Specification: ECMA-262 function/class early errors and recursive ContainsArguments semantics: https://tc39.es/ecma262/2026/multipage/ecmascript-language-functions-and-classes.html#sec-static-semantics-containsarguments

Diagnostic wording remains a separate #904/#899 requirement; this issue tracks the missed semantic checks, not a blanket exact-message parity claim.

9 days ago

The initial pattern traversal candidate passes 72 focused units without failures or leaks, improves the original tree/VM specification differential from 5/18 to 18/18, and preserves 5,520 passes with zero failures across eleven targeted corpus comparisons. Review then reproduced nine additional bypasses through logical-assignment operands and dynamic-import specifier/options expressions; the scan omitted those expression kinds too. These paths are now covered in the extended candidate with additional invalid/valid controls. Holding the commit until that exact candidate is rebuilt and verified; the initial results are not claimed as verification of the extension.

9 days ago

Landed in https://github.com/zig-utils/zig-js/commit/41104a44ee2a7bfd7939a617bfd45fcc0a369d3f, together with the related contextual-scan fix in #921. Pattern computed keys/defaults and parameter, declaration, loop, and catch bindings now receive the owning early-error checks. Logical-assignment and dynamic-import expression paths are traversed too; static-block await iteration/disposal flags are checked without rejecting valid nested async-function/arrow controls. The combined batch fixes 25 distinct early-error cases in both tree-walker and required VM, preserving valid controls and preventing preceding effects. Final verification: 72 focused units, zero failures or leaks; 7,462 corpus passes and zero failures before/after across 16 explicitly scoped comparisons. The commit records every subtree/filter and denominator. Full unit/full test262 suites and universal diagnostic-message parity are not claimed. Parent #904 and related #899 remain open.

Sign in to comment on this issue.