lib: implement WeakReference on top of JS WeakRef

The C++ implementation can now be done entirely in JS using WeakRef.
Re-implement it in JS instead to simplify the code.

PR-URL: https://github.com/nodejs/node/pull/49053
Reviewed-By: Anna Henningsen <anna@addaleax.net>
Reviewed-By: Yagiz Nizipli <yagiz@nizipli.com>
Reviewed-By: Rafael Gonzaga <rafael.nunu@hotmail.com>
Reviewed-By: Benjamin Gruenbaum <benjamingr@gmail.com>
This commit is contained in:
Joyee Cheung 2023-08-07 16:28:56 +02:00
parent c64c9149ad
commit 8dcce52c33
6 changed files with 39 additions and 9 deletions

View File

@ -28,7 +28,7 @@ const {
const { triggerUncaughtException } = internalBinding('errors');
const { WeakReference } = internalBinding('util');
const { WeakReference } = require('internal/util');
// Can't delete when weakref count reaches 0 as it could increment again.
// Only GC can be used as a valid time to clean up the channels map.

View File

@ -52,9 +52,8 @@ const {
const { createHook } = require('async_hooks');
const { useDomainTrampoline } = require('internal/async_hooks');
// TODO(addaleax): Use a non-internal solution for this.
const kWeak = Symbol('kWeak');
const { WeakReference } = internalBinding('util');
const { WeakReference } = require('internal/util');
// Overwrite process.domain with a getter/setter that will allow for more
// effective optimizations

View File

@ -33,6 +33,7 @@ const {
SafeMap,
SafeSet,
SafeWeakMap,
SafeWeakRef,
StringPrototypeReplace,
StringPrototypeToLowerCase,
StringPrototypeToUpperCase,
@ -797,6 +798,38 @@ function guessHandleType(fd) {
return handleTypes[type];
}
class WeakReference {
#weak = null;
#strong = null;
#refCount = 0;
constructor(object) {
this.#weak = new SafeWeakRef(object);
}
incRef() {
this.#refCount++;
if (this.#refCount === 1) {
const derefed = this.#weak.deref();
if (derefed !== undefined) {
this.#strong = derefed;
}
}
return this.#refCount;
}
decRef() {
this.#refCount--;
if (this.#refCount === 0) {
this.#strong = null;
}
return this.#refCount;
}
get() {
return this.#weak.deref();
}
}
module.exports = {
getLazy,
assertCrypto,
@ -855,4 +888,5 @@ module.exports = {
kEnumerableProperty,
setOwnProperty,
pendingDeprecate,
WeakReference,
};

View File

@ -1,7 +1,6 @@
'use strict';
const { internalBinding } = require('internal/test/binding');
const { WeakReference } = internalBinding('util');
const { WeakReference } = require('internal/util');
const {
setDeserializeMainFunction
} = require('v8').startupSnapshot

View File

@ -1,7 +1,6 @@
'use strict';
const { internalBinding } = require('internal/test/binding');
const { WeakReference } = internalBinding('util');
const { WeakReference } = require('internal/util');
const {
setDeserializeMainFunction
} = require('v8').startupSnapshot

View File

@ -2,8 +2,7 @@
'use strict';
const common = require('../common');
const assert = require('assert');
const { internalBinding } = require('internal/test/binding');
const { WeakReference } = internalBinding('util');
const { WeakReference } = require('internal/util');
let obj = { hello: 'world' };
const ref = new WeakReference(obj);