ReviewOS

zig-utils/zig-js

Parser: static blocks accept await iteration and asynchronous disposal

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

Parent #904; related #920 and #899.

Class static-block validation checks AwaitExpression nodes but misses await terminals represented by AST flags: for_in.is_await, var_decl.dispose == 2, and for_in.dispose == 2. As a result, invalid static blocks containing for-await-of, await using, or for (await using ... of ...) are accepted by both tree-walker and required VM, and preceding statements execute.

class C { static { if (false) { for await (const x of []) {} } } }
class C { static { if (false) { await using x = null; } } }
class C { static { if (false) { for (await using x of []) {} } } }

A seven-case differential against Node/V8 confirms all three are early SyntaxErrors with no preceding effects in the reference, but accepted with preceding effects in both zig-js modes. Four valid controls agree: nested ordinary async functions containing iteration or disposal, an async arrow containing iteration, and a public property named await. A separate actual-JSC comparison also rejects the for-await-of case.

ECMA-262 15.7.1 rejects a ClassStaticBlockStatementList that Contains the await terminal, not merely an AwaitExpression: https://tc39.es/ecma262/2026/multipage/ecmascript-language-functions-and-classes.html#sec-class-definitions-static-semantics-early-errors

Honor the existing contextual scan flag at these statement nodes without crossing async-function/arrow boundaries or rejecting a property whose name is await. Batch verification with the related traversal repair in #920, retain early-error non-execution tests in both execution modes, and check relevant static-block, for-await, and disposal corpus cases.

9 days ago

Landed in https://github.com/zig-utils/zig-js/commit/41104a44ee2a7bfd7939a617bfd45fcc0a369d3f, together with the related contextual-scan fix in #920. 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.