Skip to content

fix(class): delete prototype method removes its keys_array field (#5441)#5443

Merged
proggeramlug merged 1 commit into
mainfrom
worktree-fix-5441-class-descriptor
Jun 19, 2026
Merged

fix(class): delete prototype method removes its keys_array field (#5441)#5443
proggeramlug merged 1 commit into
mainfrom
worktree-fix-5441-class-descriptor

Conversation

@proggeramlug

@proggeramlug proggeramlug commented Jun 19, 2026

Copy link
Copy Markdown
Contributor

Summary

Fixes #5441 — the ~760 generated language/{statements,expressions}/class test262 cases that regressed to Uncaught exception: m descriptor should be configurable (language parity 94.5% → 89.3%).

Root cause

The regression came from #5395. That PR made delete C.prototype.<member> on a class-declaration prototype mark the vtable key deleted and early-return, so hasOwnProperty / getOwnPropertyDescriptor would agree the member is gone.

That is correct for instance accessors (get x()) — they live only in the class vtable, with no keys_array entry to remove (the cases #5395 actually tested).

Instance methods are different: install_class_decl_prototype_method_fields plants each method as a real keys_array data field on the prototype object (writable:true, enumerable:false, configurable:true). For a method the early return marked the vtable key deleted but left the real field in place, so hasOwnProperty kept finding it via own_key_present. test262's verifyProperty configurable probe (delete obj[name] then assert the key absent) therefore failed with m descriptor should be configurable.

This is why isolated getOwnPropertyDescriptor looked fine but the full verifyProperty path (used by the flags: [generated] class tests) failed.

Fix

Drop the early return 1 so the class-prototype delete falls through to the existing keys_array scan:

  • accessors → scan is a vacuous success (no entry), key stays marked deleted — unchanged behavior;
  • methods → scan removes the real field, and the key is still marked deleted — now invisible to both reflective paths.

One-file change in crates/perry-runtime/src/object/delete_rest.rs.

Validation (test262 radar, node v26)

dir parity descriptor should be configurable failures
language/statements/class 94.0% 0
language/expressions/class 95.6% 0
  • The specific generated repro (new-no-sc-line-method-rs-privatename-identifier-alt.js, which also checks writable:true) now passes.
  • Accessor definition/{getters,setters}-prop-desc tests (fix(class): super-in-static resolution + accessor .name reflection (#5345) #5395's targets) still pass — no regression.
  • cargo test -p perry-runtime: 1063 passed; the 2 failures are pre-existing/environmental (the known stream test-isolation flake and a cwd-dependent URL test that trips inside a worktree path), not related to this change.

Class-tail tracker: #5345.

🤖 Generated with Claude Code

Summary by CodeRabbit

  • Bug Fixes
    • Fixed incomplete property deletion behavior where certain class methods and accessors were not being fully removed from objects, improving consistency in deletion operations.

PR #5395 (#5395) made `delete C.prototype.<member>` on a class-declaration
prototype mark the vtable key deleted and early-return, so hasOwnProperty /
getOwnPropertyDescriptor would agree the member is gone. That is correct for
instance ACCESSORS (`get x()`), which live only in the class vtable — there is
no keys_array entry to remove.

Instance METHODS are different: `install_class_decl_prototype_method_fields`
plants each method as a REAL keys_array data field on the prototype object
(writable:true, enumerable:false, configurable:true). For a method the early
return marked the vtable key deleted but left the real field in place, so
hasOwnProperty kept finding it via `own_key_present`. test262's
`verifyProperty` configurable probe (`delete obj[name]` then assert the key
absent) therefore failed with "m descriptor should be configurable" — ~760
generated language/{statements,expressions}/class tests, which dropped language
parity 94.5% → 89.3%.

Fix: drop the early return so the class-prototype delete falls through to the
keys_array scan. For accessors the scan is a vacuous success (no entry); for
methods it removes the real field. The vtable key is still marked deleted, so
both member kinds become invisible to the reflective paths.

Validation (test262 radar, node v26):
- language/statements/class: parity 94.0%, 0 "descriptor should be configurable"
- language/expressions/class: parity 95.6%, 0 "descriptor should be configurable"
- accessor prop-desc tests (#5395's targets) still pass; no regressions.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@coderabbitai

coderabbitai Bot commented Jun 19, 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: 0325224f-a749-421a-944a-6773cf9acdd3

📥 Commits

Reviewing files that changed from the base of the PR and between ffb7ca9 and a8b3b4e.

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

📝 Walkthrough

Walkthrough

In js_object_delete_field, the class-declaration prototype branch previously returned early after marking a vtable member key as deleted. The early return is removed so the function falls through to the keys-array scan, ensuring instance method entries backed by keys_array are also removed.

Changes

Class Prototype Field Deletion Fix

Layer / File(s) Summary
Remove early return in class vtable member deletion
crates/perry-runtime/src/object/delete_rest.rs
For non-constructor class accessor and method members, class_mark_key_deleted is called as before, but the early success return is removed so the function continues to the keys_array scan and removes the backing entry for instance methods. Accessor-only members continue to rely solely on the deleted-key mark.

Estimated code review effort

🎯 2 (Simple) | ⏱️ ~8 minutes

Possibly related PRs

  • PerryTS/perry#5395: Directly related — this PR modifies the same js_object_delete_field class-declaration prototype branch in delete_rest.rs; the regression introduced there (early return preventing keys_array cleanup) is what this PR fixes.

Poem

🐇 A return too soon, the keys stayed in place,
The descriptor cried: "I'm not configurable, no grace!"
But now I fall through, past vtable and mark,
The keys-array swept clean, no method left dark.
~760 tests cheer from dawn until dusk — ✨

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly summarizes the main change: fixing a class method deletion issue where prototype methods weren't being properly removed from the keys_array.
Description check ✅ Passed The description thoroughly explains the regression, root cause, fix, and validation results, covering all key aspects of the change with concrete test262 metrics.
Linked Issues check ✅ Passed The PR fully addresses the linked issue #5441 by restoring correct class method property descriptors and eliminating the 752 'descriptor should be configurable' failures.
Out of Scope Changes check ✅ Passed All changes are scoped to fixing the class method deletion issue; no out-of-scope modifications are present beyond the single-file fix to delete_rest.rs.
Docstring Coverage ✅ Passed Docstring coverage is 100.00% which is sufficient. The required threshold is 80.00%.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch worktree-fix-5441-class-descriptor

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

@proggeramlug proggeramlug merged commit c0184d0 into main Jun 19, 2026
15 checks passed
@proggeramlug proggeramlug deleted the worktree-fix-5441-class-descriptor branch June 19, 2026 08:22
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.

REGRESSION: ~760 class test262 tests broke — 'm descriptor should be configurable'

1 participant