Skip to content

Commit 896367a

Browse files
committed
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.
1 parent 096fefd commit 896367a

6 files changed

Lines changed: 38 additions & 8 deletions

File tree

lib/diagnostics_channel.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ const {
2828

2929
const { triggerUncaughtException } = internalBinding('errors');
3030

31-
const { WeakReference } = internalBinding('util');
31+
const { WeakReference } = require('internal/util');
3232

3333
// Can't delete when weakref count reaches 0 as it could increment again.
3434
// Only GC can be used as a valid time to clean up the channels map.

lib/domain.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,7 @@ const { useDomainTrampoline } = require('internal/async_hooks');
5454

5555
// TODO(addaleax): Use a non-internal solution for this.
5656
const kWeak = Symbol('kWeak');
57-
const { WeakReference } = internalBinding('util');
57+
const { WeakReference } = require('internal/util');
5858

5959
// Overwrite process.domain with a getter/setter that will allow for more
6060
// effective optimizations

lib/internal/util.js

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@ const {
3333
SafeMap,
3434
SafeSet,
3535
SafeWeakMap,
36+
SafeWeakRef,
3637
StringPrototypeReplace,
3738
StringPrototypeToLowerCase,
3839
StringPrototypeToUpperCase,
@@ -797,6 +798,37 @@ function guessHandleType(fd) {
797798
return handleTypes[type];
798799
}
799800

801+
class WeakReference {
802+
constructor(object) {
803+
this.weak = new SafeWeakRef(object);
804+
this.strong = null;
805+
this.refCount = 0;
806+
}
807+
808+
incRef() {
809+
this.refCount++;
810+
if (this.refCount === 1) {
811+
const derefed = this.weak.deref();
812+
if (derefed !== undefined) {
813+
this.strong = derefed;
814+
}
815+
}
816+
return this.refCount;
817+
}
818+
819+
decRef() {
820+
this.refCount--;
821+
if (this.refCount === 0) {
822+
this.strong = null;
823+
}
824+
return this.refCount;
825+
}
826+
827+
get() {
828+
return this.weak.deref();
829+
}
830+
}
831+
800832
module.exports = {
801833
getLazy,
802834
assertCrypto,
@@ -855,4 +887,5 @@ module.exports = {
855887
kEnumerableProperty,
856888
setOwnProperty,
857889
pendingDeprecate,
890+
WeakReference,
858891
};

test/fixtures/snapshot/weak-reference-gc.js

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
'use strict';
22

3-
const { internalBinding } = require('internal/test/binding');
4-
const { WeakReference } = internalBinding('util');
3+
const { WeakReference } = require('internal/util');
54
const {
65
setDeserializeMainFunction
76
} = require('v8').startupSnapshot

test/fixtures/snapshot/weak-reference.js

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
'use strict';
22

3-
const { internalBinding } = require('internal/test/binding');
4-
const { WeakReference } = internalBinding('util');
3+
const { WeakReference } = require('internal/util');
54
const {
65
setDeserializeMainFunction
76
} = require('v8').startupSnapshot

test/parallel/test-internal-util-weakreference.js

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,7 @@
22
'use strict';
33
const common = require('../common');
44
const assert = require('assert');
5-
const { internalBinding } = require('internal/test/binding');
6-
const { WeakReference } = internalBinding('util');
5+
const { WeakReference } = require('internal/util');
76

87
let obj = { hello: 'world' };
98
const ref = new WeakReference(obj);

0 commit comments

Comments
 (0)