Skip to content

Answer Error.prototype for Object.getPrototypeOf of an Error - #2058

Merged
ctate merged 3 commits into
mainfrom
fix/error-proto
Oct 24, 2026
Merged

ctate merged 3 commits into
mainfrom
fix/error-proto

Conversation

@cramforce

@cramforce cramforce commented Oct 24, 2026 •

Copy link
Copy Markdown
Contributor

Natively, Object.getPrototypeOf(new Error()) answered Object.prototype or a fresh holder object instead of Error.prototype. The view of an error built as an Error, while its prototype is still the one the view starts with, now answers Error.prototype. Other error kinds keep their current behavior, because their prototypes are not modeled.

The change is runtime-only, in scr_dyn_get_prototype (scr_json.c).

Evidence: corpus 8115-error-prototype-identity.js, with its order baseline and CI cost recorded. It fails on main and matches Node in the plain and sanitized lanes.

Zero-cost gate against main, full sets (bench, self and the TypeScript corpus): bench and self are identical. 56 corpus programs that reach scr_dyn_get_prototype change in their release executable only, from +0 to +8.5 KB (median +288 B). IR and LLVM are identical everywhere. Details are in the verification comment.

🤖 Generated with Claude Code

@vercel

vercel Bot commented Oct 24, 2026 •

Copy link
Copy Markdown
Contributor

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated
scriptc Ready Ready Preview, v0 Oct 24, 2026 4:32am UTC

An Error's view had no prototype or a holder of its default name and
message, so Object.getPrototypeOf(new Error()) was Object.prototype or a
fresh object. A view of an error built as an Error, whose prototype is
still the one its view starts with, now answers Error.prototype.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@cramforce

Copy link
Copy Markdown
Contributor Author

Verification for 1b5c905 (rebased onto origin/main 4206155).

Differential. Corpus 8115-error-prototype-identity.js fails on main and matches Node in both lanes, through differential.test.ts and llvm-differential.test.ts (release and dev), plain and sanitized.

Zero-cost gate against main 4206155, full sets: bench, self and the TypeScript corpus.

  • bench + self: PASS, 38 of 38 identical. Bench geomean +0.28% [95% CI -0.39%, +1.12%] and self -0.21%, both within tolerance.
  • TypeScript corpus: 2902 identical and 56 differing out of 2958. Every difference is in the release executable only. IR and LLVM are identical everywhere, and the only changed function is scr_dyn_get_prototype. The 56 programs are the ones that reach it: prototype reflection (Object.getPrototypeOf, util.inherits) or instanceof on dynamic values. Growth runs from +0 to +8,472 B, with a median of +288 B. The largest is 5186-util-inherits.ts at +1.54%.

No typed benchmark changes. The gate's FAIL verdict on the corpus set comes from those 56 programs alone: the gate ran without --allow.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@cramforce
cramforce marked this pull request as ready for review October 24, 2026 02:57
Comment thread packages/runtime/src/scr_json.c
Object.getPrototypeOf of an Error answers Error.prototype when the error's view was built from its fields and its prototype is still the object the view was built with. After Object.setPrototypeOf(error, {}), it answers the object that was set.
@ctate
ctate merged commit de5557c into main Oct 24, 2026
66 checks passed
@ctate
ctate deleted the fix/error-proto branch October 24, 2026 05:04

This branch was successfully deployed

1 active deployment
Preview — cdef5577 Deployed Oct 24, 2026 by vercel[bot]
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants