Skip to content

feat(builtins): support Symbol unregister tokens in FinalizationRegistry#5259

Closed
tkshsbcue wants to merge 1 commit intoboa-dev:mainfrom
tkshsbcue:fix/finalization-registry-symbol-support
Closed

feat(builtins): support Symbol unregister tokens in FinalizationRegistry#5259
tkshsbcue wants to merge 1 commit intoboa-dev:mainfrom
tkshsbcue:fix/finalization-registry-symbol-support

Conversation

@tkshsbcue
Copy link
Contributor

Summary

Implement CanBeHeldWeakly checks per ECMAScript spec for FinalizationRegistry.prototype.register and .unregister methods.

Non-registered symbols (created via Symbol()) are now accepted as unregister tokens, while registered symbols (Symbol.for()) correctly throw TypeError.

Changes

  • Add UnregisterToken enum to hold either Object or Symbol tokens
  • Add is_registered_symbol() helper in symbol module
  • Update register() to accept symbol unregister tokens
  • Update unregister() to match against symbol tokens
  • Add tests for symbol token usage and registered symbol rejection

How it works

The CanBeHeldWeakly abstract operation returns true when:

  1. The value is an Object, OR
  2. The value is a Symbol and KeyForSymbol(v) is undefined (i.e., not created via Symbol.for())

Previously, only objects were accepted as unregister tokens. Now symbols work too:

const registry = new FinalizationRegistry(() => {});
const sym = Symbol("token");

registry.register({}, undefined, sym);  // works now
registry.unregister(sym);               // works now

registry.register({}, undefined, Symbol.for("x"));  // throws TypeError (registered symbol)
registry.unregister(Symbol.for("x"));                // throws TypeError (registered symbol)

Limitations

Symbol targets (first argument to register()) are not yet supported as they require Ephemeron support for non-GC types. This is tracked separately and can be addressed in a follow-up PR.

Test plan

  • Symbol as unregister token: register and unregister via Symbol("token") works correctly
  • Registered symbol rejection: Symbol.for("x") throws TypeError for both register and unregister
  • All 4 existing tests still pass unchanged

Closes #5253

Implement CanBeHeldWeakly checks per ECMAScript spec (sec-canbeheldweakly)
for FinalizationRegistry.prototype.register and .unregister methods.

Non-registered symbols (created via Symbol()) are now accepted as
unregister tokens, while registered symbols (Symbol.for()) correctly
throw TypeError.

Changes:
- Add UnregisterToken enum to hold either Object or Symbol tokens
- Add is_registered_symbol() helper in symbol module
- Update register() to accept symbol unregister tokens
- Update unregister() to match against symbol tokens
- Add tests for symbol token registration/unregistration and
  registered symbol rejection

Note: Symbol targets (as the first argument to register()) are not yet
supported as they require Ephemeron support for non-GC types.

Closes boa-dev#5253
@tkshsbcue tkshsbcue requested a review from a team as a code owner March 26, 2026 06:39
@github-actions github-actions bot added C-Tests Issues and PRs related to the tests. C-Builtins PRs and Issues related to builtins/intrinsics Waiting On Review Waiting on reviews from the maintainers labels Mar 26, 2026
@github-actions github-actions bot added this to the v1.0.0 milestone Mar 26, 2026
@github-actions
Copy link

Test262 conformance changes

Test result main count PR count difference
Total 52,963 52,963 0
Passed 50,732 50,732 0
Ignored 1,426 1,426 0
Failed 805 805 0
Panics 0 0 0
Conformance 95.79% 95.79% 0.00%

Tested main commit: 2437b6704c4315f6ec8f0766bf229fba23e0e61e
Tested PR commit: a89b4794569c6f5c366232c9655b602931f501a8
Compare commits: 2437b67...a89b479

@codecov
Copy link

codecov bot commented Mar 26, 2026

Codecov Report

❌ Patch coverage is 72.41379% with 8 lines in your changes missing coverage. Please review.
✅ Project coverage is 59.73%. Comparing base (6ddc2b4) to head (a89b479).
⚠️ Report is 919 commits behind head on main.

Files with missing lines Patch % Lines
...e/engine/src/builtins/finalization_registry/mod.rs 70.37% 8 Missing ⚠️
Additional details and impacted files
@@             Coverage Diff             @@
##             main    #5259       +/-   ##
===========================================
+ Coverage   47.24%   59.73%   +12.48%     
===========================================
  Files         476      589      +113     
  Lines       46892    63424    +16532     
===========================================
+ Hits        22154    37886    +15732     
- Misses      24738    25538      +800     

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

@jedel1043
Copy link
Member

This is doing things backwards. We should first add support for JsSymbol in our Gc and only then add this feature.

@jedel1043 jedel1043 closed this Mar 26, 2026
@github-actions github-actions bot removed the Waiting On Review Waiting on reviews from the maintainers label Mar 26, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

C-Builtins PRs and Issues related to builtins/intrinsics C-Tests Issues and PRs related to the tests.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Feature: Implement CanBeHeldWeakly Symbol support for FinalizationRegistry

2 participants