ReviewOS

zig-utils/zig-js

Error: retain realm intrinsic prototypes independently of public bindings

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

Parent #465; related #821 and #822.

Reproduced on pushed 4f7718d before the current candidates: a class call can create its TypeError using a shadowing lexical TypeError binding or a replaced global TypeError constructor. Checking Object.getPrototypeOf(error) against the original realm TypeError.prototype fails in both witnesses. The older instanceof error-name fallback concealed this defect; the prototype-identity check does not.

makeErrorWithProto currently resolves named constructors through self.env.get(name), which is an ordinary mutable binding lookup rather than the realm intrinsic. Other intrinsic prototype helpers also require an audit for the same distinction. Engine-generated errors must use the current or explicitly selected callee realm intrinsic, without invoking user getters or depending on public global replacement.

Acceptance: retain and trace realm-owned intrinsic identities using the existing environment/GC ownership facilities; handle lexical shadowing, replacement/deletion, cross-realm errors and moving GC. Preserve explicit prototype overrides and normal user construction/Reflect.construct semantics. New shared state must follow existing initialization/publication and no-GIL synchronization rules. Do not restore a name-based instanceof heuristic or use mutable public bindings as an intrinsic cache. Unknown engine error names need an explicit Error prototype/name policy, not unprototyped objects silently recognized by tags.

This is a separately reproduced existing error-construction defect, not a passing result or completed implementation.

9 days ago

Implementation in progress: private root-Environment-owned Error intrinsic identities, traced/relocated through the existing GC visitor and protected by Environment publication/locking. Constructor ordinary calls now use the active constructor as newTarget and enter its realm; temporary roots cover message, cause and iterator callbacks. Fifteen semantic witnesses pass the Node 24.18.0 reference. Debug builds with 2164 linked tests; GC relocation inventory passes (9 kinds, 27 surfaces, 21 tags). Runtime candidate validation waits for the preceding immutable full suite; no pass or completion claim yet. Unknown engine names receive Error.prototype plus their non-enumerable diagnostic name. Non-Error intrinsic lookup, including AggregateError errors-array realm selection, remains an explicitly separate audit boundary.

9 days ago

The retained-foreign-realm candidate passes 9/9 Debug and 9/9 unsuppressed ReleaseSafe+TSan; the broader realm filter passes 50/50 (overlapping the nine new tests), with no failures/leaks/races. Corpus remains 302/302 Error/instanceof and 7155/7160 positive class pairs, no measured regressions; default classes 8426/8426. The pre-landing extension audit is now validating optional ConcurrentAccessError registration and explicit WebAssembly error prototypes, with 2167 linked tests. Separately reproduced baseline defects are tracked in #824 (Array identity/active AggregateError realm) and #825 (BigInt primitive prototype rejection), not claimed fixed by this change.

9 days ago

Pre-landing gate update: the extensions candidate scores 9/10 in Debug and unsuppressed ReleaseSafe+TSan. The optional ConcurrentAccessError ownership witness fails; all other new Error/GC/explicit-Wasm tests pass, with no leaks/race reports. The untouched VM own-slot/array fast paths can bypass checkRestricted, tracked as #826. Keeping the failing test and holding this change uncommitted until the access paths are diagnosed and fixed; not weakening the test or claiming integration passed. Source hashes, binaries and failure logs are retained.

9 days ago

The #826 candidate removes the failing VM access-control bypass without changing or weakening the #823 witness. All ten Error-intrinsic tests now pass: Debug 10/10 (95.653s), unsuppressed ReleaseSafe+TSan 10/10 (4.543s), no failures/leaks/sanitizer reports. Node passes all sixteen local reference cases. The restriction matrix and direct native-artifact tests also pass in both builds. Final checkpoint-boundary coverage and full integration are still pending; no commit or closure claimed.

9 days ago

Landed on main: fix(errors): retain realm-owned intrinsic identities (#823). The realm table retains constructors/prototypes independently of public bindings, and its 22 slots plus retained foreign constructor realms are traced and relocated. Error calls use the active constructor realm and preserve message/cause/iteration ordering; callback arguments and allocated results remain rooted.

Local witnesses improve 9/16 to 16/16 in automatic and forced paired execution (Node 16/16). The 302-case Error/instanceof census remains 302/302, descriptors 362/362, and default class scopes 8426/8426. Combined Debug: 2169 passed, one platform skip, zero failures/leaks. Unsuppressed ReleaseSafe+TSan: 10/10 intrinsic tests and 51/51 broader realm tests (including those ten). Moving-GC and exhaustive allocation-failure checks pass. Threadfuzz seed 1: default 400/400, verify 300/300. Waiting for pushed-revision CI before closure. Separate Array-realm and BigInt-prototype defects remain #824 and #825.

9 days ago

The later #826 fix is now pushed on top as 8d68a20. Its combined full Debug run passed 2171 tests with one platform skip and zero failures/leaks; the unsuppressed TSan realm filter passed 51/51. CI 33217684445 is the current combined-main run. The earlier 2ebcdc1 run was superseded/cancelled by the push, not treated as a terminal pass. #823 remains open pending current CI completion; uncommitted #824 work is excluded.

9 days ago

The retained Error identities and their updated shared realm container also pass the subsequent #824 combined-main validation: full Debug 2182 passed/1 platform skip/0 failed or leaked, and the unsuppressed TSan realm filter 62/62.

Latest combined-main commit is 8e1e441d; current CI is pending. The preceding run reached 49 successes, 1 skip and 4 pending checks before this push, so it is not terminal-green evidence. #823 remains open pending the current gates.

9 days ago

Terminal verification for the current push is blocked by the concrete Linux JSON stringify peak-memory assertion tracked in #828. Local Error-intrinsic tests remain passing, but this issue stays open until the required CI result is resolved.

9 days ago

Terminal descendant-main verification is now complete: CI run 33312141595 on f4f00803 completed successfully with all 56 jobs terminal and no failed/cancelled jobs. This run contains the landed #823 implementation and the subsequent integration history. Closing the issue as completed; any newly reproduced defect should retain its own exact witness rather than reopening this verified scope.

Sign in to comment on this issue.