Skip to content

Fix Object.prototype reads before globalThis initialization - #11000

Closed
proggeramlug wants to merge 2 commits into
PerryTS:mainfrom
proggeramlug:fix/10880-object-prototype-reads
Closed

proggeramlug wants to merge 2 commits into
PerryTS:mainfrom
proggeramlug:fix/10880-object-prototype-reads

Conversation

@proggeramlug

@proggeramlug proggeramlug commented Sep 22, 2026 •

Copy link
Copy Markdown
Contributor

Fixes #10880.

Summary

Ordinary inherited property reads and in returned a miss when this thread had not yet materialized globalThis. The Object.prototype address cache intentionally returns zero in that state for its array write fast path, but inherited lookups need to initialize the intrinsic before resolving it.

Materialize the realm global on that first inherited lookup and root the receiver and key across bootstrap, which can allocate and collect. Once the global exists, the existing cached path remains in use.

Add read-first and in-first parity fixtures covering built-in members, custom chains, null prototypes, and own-property shadowing.

Validation

  • Both new fixtures failed against the unmodified runtime and pass with this change under the default optimized parity runner.
  • Six object_prototype fixtures, test_parity_explicit_null_prototype, and test_parity_object_ctor_inherited_proto_methods pass with PERRY_NO_AUTO_OPTIMIZE=1.
  • cargo fmt --all --check, test registration, file size, and git diff --check pass.

Summary by CodeRabbit

  • Bug Fixes
    • Fixed inherited Object.prototype properties being unavailable during initial object access.
    • typeof, the in operator, and direct calls now correctly recognize inherited methods such as toString, hasOwnProperty, and valueOf, including across prototype chains.
    • Preserved expected behavior for null-prototype objects and objects that shadow inherited properties.

@coderabbitai

coderabbitai Bot commented Sep 22, 2026 •

Copy link
Copy Markdown

Review in Change Stack →

Navigate logical layers of code changes, visualize relationships, and explore their blast radius.

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Advanced

Run ID: 8a9389a6-27e1-4081-84b9-927864d926de

📥 Commits

Reviewing files that changed from the base of the PR and between c7cbc3c and a97c66f.

📒 Files selected for processing (4)
  • changelog.d/11000-lazy-object-prototype-reads.md
  • crates/perry-runtime/src/object/field_get_set/accessors.rs
  • test-files/test_issue_10880_lazy_object_prototype.ts
  • test-files/test_issue_10880_lazy_object_prototype_in_first.ts

Included review availability: Your plan provides up to 8 included reviews per hour; 0 remain after this review.


📝 Walkthrough

Walkthrough

The runtime now materializes the realm global before resolving inherited Object.prototype properties. It roots the receiver and key during this allocation. New tests cover reads, in, typeof, prototype chains, null-prototype objects, shadowing, and direct calls.

Changes

Lazy Object Prototype Resolution

Layer / File(s) Summary
Bootstrap prototype resolution
crates/perry-runtime/src/object/field_get_set/accessors.rs, changelog.d/11000-lazy-object-prototype-reads.md
The accessor roots the receiver and key, materializes the realm global, and retries the inherited prototype lookup. The changelog records the behavior change.
Inherited property regression coverage
test-files/test_issue_10880_lazy_object_prototype.ts, test-files/test_issue_10880_lazy_object_prototype_in_first.ts
Tests verify inherited Object.prototype reads and membership checks before explicit materialization across multiple object shapes and property states.

Priority: ➖ Normal

Estimated code review effort: 2 (Simple) | ~10 minutes

Change: Bug fix · Severity of issue fixed: Medium

Merge Risk: ⚪ Minimal · up to a97c6

Inherited Object.prototype members are now available from the first read or membership check without breaking prototype chains, shadowing, or null-prototype behavior.

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Docstring coverage is scoped to functions touched by this diff. Analyzed 1 functions across 3 files. (1 skipped: 1 … Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly identifies the main change: fixing Object.prototype reads before globalThis initialization.
Description check ✅ Passed The description provides a clear summary, explains the implementation, identifies issue #10880, lists the added fixtures, and documents validation results. It does not reproduce the template headings …
Linked Issues check ✅ Passed The change satisfies #10880. default_object_prototype_property_value materializes the realm global before resolving Object.prototype when needed. It roots the receiver and key across bootstrap all…
Out of Scope Changes check ✅ Passed The changes stay within #10880. The runtime change fixes lazy Object.prototype resolution. The changelog documents that fix. The test fixtures verify the required inherited-property behavior and edg…
Full details: Docstring Coverage

Explanation

Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Docstring coverage is scoped to functions touched by this diff. Analyzed 1 functions across 3 files. (1 skipped: 1 unsupported.)

  • Fix all pre-merge checks with AI
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create a new PR

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@proggeramlug

Copy link
Copy Markdown
Contributor Author

Landed on main in merge train 258 (#11078, v0.5.1641), main e27f0a068a.

Carried at head a97c66f212. CI on the train head was fully green — 22 jobs, zero failures, the first train since the public-baseline artifact was regenerated, so no known-red line to read past.

This train was bisect-verified: after an earlier 35-PR assembly hit five gap regressions, the lowering-touching PRs were split into probes, and this set (#11070) came back with all six gap shards clean while the other half reproduced all five.

Trains rebase-merge, so commits get new SHAs and GitHub cannot mark this merged. Closed as landed.

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.

Object.prototype members are invisible to property reads and in unless the program names Object.prototype ("toString" in {} is false)

1 participant