-
Notifications
You must be signed in to change notification settings - Fork 903
Implement ES2021 WeakRef with ES2023 symbols-as-weakmap-keys support #2074
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
- Add NativeWeakRef class implementing ES2021 WeakRef specification - Support for unregistered symbols as weak targets (ES2023 feature) - Correctly reject registered symbols (Symbol.for()) - Use Java WeakReference for garbage collection semantics - Add comprehensive unit tests (29/29 passing, 100% success) - Register WeakRef constructor in ES6+ language mode - Add error messages for invalid WeakRef targets - Auto-generate test262.properties with proper format - Fix Object.seal test for WeakRef (seal-weakref.js now passes) - WeakRef passes 25/29 test262 tests (86.21% success rate) WeakRef allows holding weak references to objects without preventing their garbage collection, useful for caches and memory-sensitive code. Key features: - new WeakRef(target) constructor validates target can be held weakly - deref() method returns referenced object or undefined if collected - Follows ES2021 CanBeHeldWeakly abstract operation specification - Compatible with ES2023 symbols-as-weakmap-keys proposal Failing test262 tests are related to cross-realm prototype handling and NewTarget customization, which are advanced edge cases that don't affect core WeakRef functionality. Signed-off-by: Anivar A. Aravind <[email protected]>
3c96ca8 to
1e278f4
Compare
Fix code formatting issues identified by CI
gbrail
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This looks helpful and straightforward -- thanks!
Do you think that you could put a bit of detail in the comments about the four failing test cases? I feel that if we don't address them now (even if they're advanced use cases) we may never get to them, so I'd like to at least see what the possibilities are. Thanks!
|
@gbrail I've analyzed the 4 failing test cases. They all relate to how the constructor handles the newTarget parameter when called through Reflect.construct. When calling The deref test fails because it should only work on objects that actually went through WeakRef construction, not just objects that inherit from WeakRef.prototype. These are edge cases used in proxies and polyfills. The core WeakRef functionality works - it properly holds weak references that don't prevent garbage collection." │ Fixing this requires either extending LambdaConstructor to handle newTarget (which would benefit other built-ins too) or implementing WeakRef with a traditional constructor pattern. The current implementation delivers the core WeakRef functionality - weak references that don't prevent garbage collection - which is what most developers need. |
…ments This PR provides a complete implementation of ES2021 memory management features with ES2023 symbol support, consolidating both WeakRef and FinalizationRegistry. - Full ES2021 WeakRef implementation with deref() method - ES2023 symbols-as-weakmap-keys support via canBeHeldWeakly - Uses Java WeakReference for proper GC semantics - Supports unregistered symbols as weak targets - Follows Rhino patterns with realThis and instanceOfWeakRef - Complete register/unregister methods per ES2021 spec - Optional cleanupSome() method for synchronous cleanup (server-side use) - Thread-safe implementation using ConcurrentHashMap - Java WeakReference with ReferenceQueue for GC tracking - Supports symbols as unregister tokens (canBeHeldWeakly) - Proper SameValue comparison using ScriptRuntime.same() - Uses LambdaConstructor for consistency with other Rhino built-ins - Follows established Rhino patterns (realThis, instanceof fields) - Comprehensive error handling with proper error messages - Symbol.toStringTag support for both constructors - Proper validation per ECMAScript spec requirements - Comprehensive test coverage including edge cases - Internal method tests using reflection (white-box testing) - Test pass rate: 95% (80/84 tests passing) - Minor failures in edge cases that don't affect core functionality - Added cleanupSome() method addressing reviewer feedback - Enhanced symbol support for ES2023 compatibility - Better spec compliance with proper validation - Additional test coverage for internal methods - Cleaner code following Rhino conventions Closes mozilla#943 (FinalizationRegistry support) Supersedes PR mozilla#2074 (WeakRef-only implementation)
|
Closing this PR as WeakRef is now included in PR #2058 along with FinalizationRegistry. The consolidated implementation provides both ES2021 features together with ES2023 symbol support. |
This PR implements the ES2021 WeakRef constructor and prototype, allowing JavaScript code to hold weak references to objects without preventing their garbage collection. This is particularly useful for implementing caches, memoization, and other memory-sensitive patterns.
Changes
The implementation adds a new NativeWeakRef class that provides the WeakRef constructor and its deref() method. The implementation follows the ES2021 specification while also supporting unregistered symbols as weak targets, which is part of the ES2023 symbols-as-weakmap-keys specification.
Key implementation decisions:
Testing
Unit tests: All 29 unit tests pass, covering constructor validation, deref behavior, symbol handling, and error cases.
Test262: 25 out of 29 test262 tests pass (86.21% success rate). The 4 failing tests involve advanced edge cases around cross-realm prototype handling and NewTarget customization that don't affect normal usage.
Additionally, this implementation fixes an existing test262 test (Object/seal/seal-weakref.js) that was previously failing.
Technical Notes
The implementation correctly distinguishes between registered and unregistered symbols per ES2023 symbols-as-weakmap-keys specification. Registered symbols (created with Symbol.for()) cannot be held weakly as they lack unique identity, while unregistered symbols can be held weakly. This matches the behavior of WeakMap and WeakSet.
Partially addresses #943 (WeakRef portion - FinalizationRegistry still needs implementation)