ReviewOS

zig-utils/zig-js

Parser: arrow bodies inherit enclosing labels and [Yield], and skip strict parameter checks

#945
Closed glennmichael123 opened this 10 days ago ·
10 days ago

Found in the post-#933 survey. Every row below was executed, with node v24.4.1 as the oracle, against a Debug build of main (f2bafeb). Parse-only probes are wrapped in function __never(){ … }.

parseArrowBody gives an arrow a fresh return/loop/switch context but, unlike parseFnBody, keeps the enclosing labels and the enclosing [Yield], and it never applies the strict-mode parameter rules that the body's own "use strict" imposes retroactively.

familyprogramnodezig-js
labelsvar n = 0; l: for (var i = 0; i < 3; i++) { [1].forEach(() => { n++; if (i === 1) break l; }); }SyntaxErrorruns; the break is ignored (n=3 i=3)
l: { (() => { break l; })(); } and l: { async () => { break l; } }SyntaxErroraccepted
outer: for (;;) { [1].forEach(() => { outer: for (;;) break outer; }); break; } (relabel inside the callback)validUnexpectedToken
[Yield]function* g(){ () => { yield 1; }; }SyntaxErroraccepted
function* g(){ () => { var yield; }; }, () => { yield.x; }, () => { yield = 1; }validUnexpectedToken
globalThis["yield"] = 7; function* g(){ var f = () => { return yield; }; return f(); } g().next().value7SyntaxError at runtime ("yield is only supported in VM-compiled generator bodies")
strict params(eval) => { "use strict" }, eval => { "use strict" }, async (eval) => { "use strict" }SyntaxErroraccepted
(arguments) => { "use strict" }, (yield) => { "use strict" }, (interface) => { "use strict" }, (let) => { "use strict" }, static => { "use strict" }SyntaxErroraccepted

In total, 36 of the survey's arrow probes differ from node today. JavaScriptCore (home-tool) agrees with node on each one it can run.

Fix: save, reset and restore the three label lists and in_generator around both arrow body forms (the parameters keep the enclosing [?Yield], and a YieldExpression in them stays an error), and run validateStrictParams when the block body has its own "use strict".

Done: each probe matches node. Pinned as focused frontend cases. Debug before/after --diag over the arrow-function, generator, labelled-statement and class subtrees shows 0 failures on both sides.

10 days ago

Taking this: the fix is written and its before/after gate (probe corpus, Debug test262 diff, focused suites) is running. It lands together with #944/#945/#946 as separate commits.

10 days ago

Implemented and pushed to main in 9e4ae588.

All 17 direct probes now match Node: arrows cannot target enclosing labels, inner relabeling is accepted, arrow bodies use [~Yield] while their parameters retain the enclosing grammar parameter, the runtime yield identifier lookup returns 7, and every listed strict-parameter form is rejected. The focused frontend gate covers 20 acceptance/rejection and restoration cases.

Exact-parent Debug test262 comparison stayed at 0 fail before and after across 9,409 cases: arrow functions (343), async arrows (60), generator expressions (290), generator declarations (266), labeled statements (24), class expressions (4,059), and class declarations (4,367). Parser module tests pass 226/226.

The shared label-boundary repair also closes #950. ReleaseFast allocations are unchanged; instructions changed by +0.3% on the 1,024 nested-function row and +2.6% on the deliberately 1,024-deep arrow row.

Sign in to comment on this issue.