Skip to content

fix(runtime): complete computed property name reflection - #8646

Closed
proggeramlug wants to merge 1 commit into
PerryTS:mainfrom
proggeramlug:fix/5894-computed-property-names
Closed

fix(runtime): complete computed property name reflection#8646
proggeramlug wants to merge 1 commit into
PerryTS:mainfrom
proggeramlug:fix/5894-computed-property-names

Conversation

@proggeramlug

@proggeramlug proggeramlug commented Aug 23, 2026

Copy link
Copy Markdown
Contributor

Summary

  • complete the language/computed-property-names Test262 subcluster
  • preserve NaN and ±Infinity as ordinary computed property keys
  • expose computed symbol methods through Object.getOwnPropertySymbols on materialized class prototypes
  • let a computed ["constructor"] method replace the implicit prototype back-pointer
  • add an end-to-end Node/Perry parity regression covering all three seams

Refs #5894

Validation

  • scripts/test262_subset.py --root vendor/test262 --dir language/computed-property-names --jobs 8 --sample-cap 1000 — 48/48 pass, up from 45/48
  • PERRY_SKIP_BUILD=1 ./run_parity_tests.sh --filter test_issue_5894_computed_property_names — 1/1 pass
  • cargo test -p perry-runtime --lib — 2641 passed, 0 failed, 4 ignored
  • cargo fmt --all -- --check
  • bash scripts/check_file_size.sh

Summary by CodeRabbit

  • Bug Fixes

    • Computed class methods named constructor are now correctly installed and can override the default constructor property.
    • Class prototype symbols are now consistently included in symbol property enumeration without duplicates.
    • Properties defined with computed keys such as Infinity, -Infinity, and NaN can now be accessed correctly.
  • Tests

    • Added coverage for computed class methods, symbol ordering, property descriptors, invocation, and numeric computed property keys.

@coderabbitai

coderabbitai Bot commented Aug 23, 2026

Copy link
Copy Markdown

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: 1188684d-4427-4077-88a0-efdfccf6218e

📥 Commits

Reviewing files that changed from the base of the PR and between 7855182 and 29949ba.

📒 Files selected for processing (1)
  • crates/perry-runtime/src/object/class_registry/state.rs

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


📝 Walkthrough

Walkthrough

Computed class methods now install on existing prototypes, including constructor-named methods. Class symbol enumeration includes declared symbols without duplicates. Dynamic access resolves NaN and infinite computed property keys as ordinary property names. Regression coverage validates these behaviors.

Changes

Computed Property Resolution

Layer / File(s) Summary
Class method installation
crates/perry-runtime/src/object/class_registry/state.rs, crates/perry-runtime/src/object/class_registry/parent_static.rs
Constructor-named methods remain in the class vtable. Computed methods are installed on existing class declaration prototypes with writable, non-enumerable, configurable attributes.
Class symbol enumeration
crates/perry-runtime/src/symbol/iterator.rs, test-files/test_issue_5894_computed_property_names.ts
Class prototype symbol enumeration includes declared symbols and removes duplicate stored entries. Tests verify symbol visibility, descriptors, calls, and ordering.
Non-finite numeric property access
crates/perry-runtime/src/value/dyn_index.rs, test-files/test_issue_5894_computed_property_names.ts
NaN, Infinity, and -Infinity indices use ordinary property-key resolution. Tests cover finite numbers, signed zero, infinities, and NaN.

Estimated code review effort: 3 (Moderate) | ~20 minutes

Merge Risk: ⚪ Minimal · up to 29949

The PR completes computed property name support and adds parity coverage; no actionable merge-blocking risk remains beyond normal checks and review.

Suggested reviewers: thehypnoo

🚥 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 3 functions across 1 files. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
Title check ✅ Passed The title clearly identifies the main runtime fix for computed property name reflection.
Description check ✅ Passed The description explains the changes, references issue #5894, and lists concrete validation results, but omits several template headings and checklist items.
✨ Finishing Touches 💡 1
🛠️ Fix failing CI checks 💡
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests

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
proggeramlug force-pushed the fix/5894-computed-property-names branch from 7855182 to 29949ba Compare August 23, 2026 11:02
@proggeramlug

Copy link
Copy Markdown
Contributor Author

CI follow-up after the amended head (29949babc):

  • The branch-specific raw_handle_debt finding from the first run is fixed; the final lint log has no raw-handle violation.
  • Passing on the final head: cargo-test, e2e-scoped, warnings, gap-suite (5), plan, the GC self-test, and CodeRabbit review (no actionable comments).
  • The remaining API-doc, addr-class, gap-suite, and GC-stress failures are reproduced by the completed current-main sweep at base SHA f96a9d9e0. The PR uses six gap shards while main used three, but the final failing case lists map to the same base regressions.
  • The TLS self-check is likewise inherited (crates/perry-runtime/src/node_submodules/test_runner.rs, untouched here).
  • test_gap_eval_as_value had one extra intermittent crash in shard 3; an isolated rerun on this exact head passed 1/1 with Node parity.
  • The changelog lint remains intentionally unsatisfied because test262 language misc tail — 409 (self-contained worklist) #5894 explicitly requires a code-only PR with no CHANGELOG; the suggested skip-changelog label is not defined in the repository.

Ticket validation remains green: language/computed-property-names 48/48 (up from 45/48), the focused parity regression 1/1, and runtime unit tests 2,641 passed / 0 failed / 4 ignored.

proggeramlug added a commit that referenced this pull request Aug 23, 2026
* perf(codegen): materialize large constant array literals from a static descriptor + one bulk call (#8583 follow-up)

A minified bundle data table is a giant nested constant array literal. The
default lowering builds it procedurally — one `js_array_from_values` per
sub-array plus the inline element stores — so the Claude Code bundle's `__33499`
(a constant numeric array-of-arrays) lowered to 11,104 allocations and a 245k-
instruction body that made `rewrite-statepoints-for-gc` fan out.

This adds a codegen path that recognizes a LARGE, fully-constant array literal
(number/int/bool/null/undefined, recursively nested arrays) and instead:

  * serializes the constant tree into a compact tagged blob emitted as module-
    private rodata, and
  * emits ONE call to a new runtime helper `js_value_from_const_descriptor`
    that materializes the whole nested structure in a single pass.

The runtime builds a FRESH, mutable array each call (JS array literals are
mutable, so the descriptor is a template, never a shared constant), under
`GcSuppressScope` so the partially-built parents held across nested child
allocations cannot be collected or moved — the same discipline `js_json_parse`
and the lazy-array materializer use. All-number rows keep the raw-f64 layout;
any pointer element downgrades the row via `store_array_slot`.

Gated on a 256-node minimum, so small literals keep the fast inline bump-alloc
path (no regression). `PERRY_CONST_ARRAY_DESCRIPTOR=0` reverts to the procedural
path (A/B bisection + escape hatch).

On a 3,000-row nested-array synthetic: the 3,000+ `js_array_from_values` calls
collapse to one `js_value_from_const_descriptor` + a rodata blob; the compile
drops from not-finishing-in-2min to 1.46s; output is byte-identical to the
procedural build across the moving-GC matrix, with mutation-after-materialize
and bool/null rows verified.

Claude-Session: https://claude.ai/code/session_01TwxRkALrR9HKSF1zKLSTAF

* docs(changelog): fragment for #8647

Claude-Session: https://claude.ai/code/session_01TwxRkALrR9HKSF1zKLSTAF

* fix(runtime): complete computed property name reflection

* perf(codegen): restrict the const-array descriptor to NESTED literals

A flat constant scalar array (e.g. `[0; 2050]`) is already a single
`js_array_alloc_literal` + inline stores — not the per-subarray fan-out the
descriptor targets — and its inline path carries the precise per-slot write
barriers a later push/store depends on (large_object_barriers). Gate the
descriptor path on the literal containing at least one nested array element, so
only genuine nested data tables (the __33499 shape) take it; flat arrays keep
their existing path. Verified: the nested 3,000-row synthetic still collapses to
one js_value_from_const_descriptor call, and large_object_barriers passes.

Claude-Session: https://claude.ai/code/session_01TwxRkALrR9HKSF1zKLSTAF

* fix(runtime): keep old array growth targets out of nursery

* docs(changelog): note array growth generation fix

* fix(codegen): guard block-creating lowerings against diverged (terminated) blocks (#8583)

When a sub-expression provably diverges — a throwing operand (e.g. a captured
TDZ access or const-reassignment) emits `js_throw_error_with_code` + `unreachable`
— the current block is terminated. `LlBlock` silently drops any instruction
emitted after a terminator (block.rs), so the setup instructions for the
surrounding operation are discarded; but block-creating lowerings still emit
fresh blocks that reference those dropped `%rN` registers, which the dialect
builder rejects with "register %rN used but never defined" (dialect/mod.rs). The
whole surrounding operation is unreachable on that path, so the fix is to emit
nothing once the block is terminated.

Two sites hit this in the Claude Code 2.1.112 bundle (both dead code after a
proven-throwing operand): `lower_index_set_fast` (`a[i] = v`, closure
`__44845`) and `emit_persistent_shadow_root_barrier` (a pointer root store,
closure `__44449`). Each now returns early when `ctx.block().is_terminated()`.

Also adds a `PERRY_DIALECT_DUMP=<dir>` diagnostic: on a dialect construction
failure, `render_units_from_frozen` names the offending function and writes its
full IR (typed insts rendered via `render_into`) — the failing unit never parses,
so the normal `PERRY_SAVE_LL` post-parse dump cannot capture it. This is how the
two sites above were located.

Validated end-to-end: with these guards, the cli.js bundle codegens ALL 84
units with zero "used but never defined" errors (it previously failed at unit
25); the remaining blocker to a final binary is unrelated (host disk).

Claude-Session: https://claude.ai/code/session_01TwxRkALrR9HKSF1zKLSTAF

* docs(changelog): fragment for #8652

Claude-Session: https://claude.ai/code/session_01TwxRkALrR9HKSF1zKLSTAF

* fix: complete test262 built-ins misc tail semantics

* chore: fmt the stack and add the two missing changelog fragments

#8646 and #8650 landed without a changelog.d fragment; #8650 also lowers the
raw-handle ratchet 925 -> 923, which is recorded in its fragment.

---------

Co-authored-by: Ralph Küpper <ralph@skelpo.com>
@proggeramlug

Copy link
Copy Markdown
Contributor Author

Landed on main in 06e1ab3 via #8657, batched with the other four ready PRs. Validation notes there: all nine ratchets, cargo check --workspace --all-targets clean, codegen 1189/0, runtime 2641/0. I added the changelog fragment this PR was missing.

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.

1 participant