ReviewOS

zig-utils/zig-js

Parser: allow new.target in class field initializer contexts

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

Parent: #496, #465. Found while qualifying #1090.

Executed on exact parent bc83af30: class Box { target = new.target; arrow = () => new.target; } is accepted by Node and evaluates to [true,true] when both reads are compared with undefined. zig-js tree and required-VM modes both return ERR UnexpectedToken.

The parser gives ordinary functions/methods and static blocks a NewTarget context, but does not introduce that context while parsing a field initializer. Field initialization is a function context; arrows inherit it. Computed field names remain in the surrounding context and must not acquire the initializer's permission.

Scope: introduce and restore the parser's existing NewTarget depth around the field initializer expression only. Pin public/private, instance/static, arrow, nested-class, and computed-name/non-leak boundaries; preserve arguments, SuperCall, await/yield, and return restrictions. Run affected class/NewTarget/arrow corpus comparisons against the saved exact-parent binary and publish scoped flips.

Definition of done:

  • Node-confirmed accepted/rejected syntax is pinned, including restoration after successful and failing initializers.
  • Tree/required-VM runtime reads return undefined and preserve initializer/lexical contexts.
  • Focused parser/engine, ReleaseSafe/TSan and exact-parent affected corpus outcomes are measured; production build passes.
  • Small conventional fix and evidence are pushed to main; #1090 remains separate.
9 days ago

Implemented in 30ce39b7, pushed to main over exact parent bc83af30.

The five-line production fix introduces the existing NewTarget syntactic context only while parsing a field initializer expression, then restores it on every exit. Arrows inherit that context; computed names retain the surrounding context. This follows ClassFieldDefinitionEvaluation. Existing arguments, SuperCall, return, and await checks remain in their original paths.

Before, the standalone public-field/arrow probe returned ERR UnexpectedToken in both tree and required-VM modes while Node produced [true,true]. The permanent runtime witness now observes undefined instance/static/private/arrow and nested-constructor field reads in tree, required-VM, and JIT-enabled configurations.

Qualification:

  • Seven accepted and eight rejected syntax fixtures are independently confirmed with Node's script parser. They pin private/static fields, lexical arrows, nested classes, computed names, and depth restoration after success and syntax failure.
  • Focused class-field parser cases and the runtime/syntax root pass in Debug, ReleaseSafe, and unsuppressed TSan. Frontend smoke: 79 cases passed. Production runner build and diff checks pass.
  • Exact parent/current reports match for 8,783 cases: class statements 4,367; class expressions 4,059; NewTarget 14; arrows 343. Both binaries have zero default-tier failures and zero tree/VM differences in all four subtrees. Flips 0 test262 cases; the standalone global-field shape was not exposed by those existing fixtures.
  • Parent/changed runner SHA-256: 97cfe1a6c07e98538ada1010093497c7525c4dba96a4d8b19b717fd3c6e68ac8 / 5e5d8abf42ec528363b8ededd51c3a45098237294b08ba03c1fd4b770d30fc0c.
  • The initial four-minute external diagnostic wrapper stopped an incomplete parent VM sweep. A longer bounded run completed the entire sweep; the incomplete phase is not counted as passing evidence.

The full combined local unit link remains blocked by #933's unchanged memory cap. Hosted integration is pending. The separately preserved native activation-read implementation and its remaining qualification continue under #1090.

Sign in to comment on this issue.