Skip to content

Commit b1c3909

Browse files
committed
lib: initialize instance members in class constructors
Since V8 snapshot does not currently support instance member initialization, initialize them in ordianry class constructors for now so that these classes can be included in the snapshot. This may be reverted once https://bugs.chromium.org/p/v8/issues/detail?id=10704 is fixed and backported. PR-URL: #32984 Reviewed-By: Anna Henningsen <anna@addaleax.net> Reviewed-By: Daniel Bevenius <daniel.bevenius@gmail.com>
1 parent f8bde7c commit b1c3909

File tree

2 files changed

+56
-53
lines changed

2 files changed

+56
-53
lines changed

lib/internal/abort_controller.js

+7-4
Original file line numberDiff line numberDiff line change
@@ -55,15 +55,18 @@ function abortSignal(signal) {
5555
signal.dispatchEvent(event);
5656
}
5757

58+
// TODO(joyeecheung): V8 snapshot does not support instance member
59+
// initializers for now:
60+
// https://bugs.chromium.org/p/v8/issues/detail?id=10704
61+
const kSignal = Symbol('signal');
5862
class AbortController {
59-
#signal = new AbortSignal();
60-
6163
constructor() {
64+
this[kSignal] = new AbortSignal();
6265
emitExperimentalWarning('AbortController');
6366
}
6467

65-
get signal() { return this.#signal; }
66-
abort() { abortSignal(this.#signal); }
68+
get signal() { return this[kSignal]; }
69+
abort() { abortSignal(this[kSignal]); }
6770

6871
[customInspectSymbol](depth, options) {
6972
return customInspect(this, {

lib/internal/event_target.js

+49-49
Original file line numberDiff line numberDiff line change
@@ -42,32 +42,30 @@ function lazyNow() {
4242
return perf_hooks.performance.now();
4343
}
4444

45+
// TODO(joyeecheung): V8 snapshot does not support instance member
46+
// initializers for now:
47+
// https://bugs.chromium.org/p/v8/issues/detail?id=10704
48+
const kType = Symbol('type');
49+
const kDefaultPrevented = Symbol('defaultPrevented');
50+
const kCancelable = Symbol('cancelable');
51+
const kTimestamp = Symbol('timestamp');
52+
const kBubbles = Symbol('bubbles');
53+
const kComposed = Symbol('composed');
54+
const kPropagationStopped = Symbol('propagationStopped');
4555
class Event {
46-
#type = undefined;
47-
#defaultPrevented = false;
48-
#cancelable = false;
49-
#timestamp = lazyNow();
50-
51-
// None of these are currently used in the Node.js implementation
52-
// of EventTarget because there is no concept of bubbling or
53-
// composition. We preserve their values in Event but they are
54-
// non-ops and do not carry any semantics in Node.js
55-
#bubbles = false;
56-
#composed = false;
57-
#propagationStopped = false;
58-
59-
6056
constructor(type, options) {
6157
if (arguments.length === 0)
6258
throw new ERR_MISSING_ARGS('type');
6359
if (options != null)
6460
validateObject(options, 'options');
6561
const { cancelable, bubbles, composed } = { ...options };
66-
this.#cancelable = !!cancelable;
67-
this.#bubbles = !!bubbles;
68-
this.#composed = !!composed;
69-
this.#type = `${type}`;
70-
this.#propagationStopped = false;
62+
this[kCancelable] = !!cancelable;
63+
this[kBubbles] = !!bubbles;
64+
this[kComposed] = !!composed;
65+
this[kType] = `${type}`;
66+
this[kDefaultPrevented] = false;
67+
this[kTimestamp] = lazyNow();
68+
this[kPropagationStopped] = false;
7169
// isTrusted is special (LegacyUnforgeable)
7270
Object.defineProperty(this, 'isTrusted', {
7371
get() { return false; },
@@ -87,10 +85,10 @@ class Event {
8785
});
8886

8987
return `${name} ${inspect({
90-
type: this.#type,
91-
defaultPrevented: this.#defaultPrevented,
92-
cancelable: this.#cancelable,
93-
timeStamp: this.#timestamp,
88+
type: this[kType],
89+
defaultPrevented: this[kDefaultPrevented],
90+
cancelable: this[kCancelable],
91+
timeStamp: this[kTimestamp],
9492
}, opts)}`;
9593
}
9694

@@ -99,20 +97,22 @@ class Event {
9997
}
10098

10199
preventDefault() {
102-
this.#defaultPrevented = true;
100+
this[kDefaultPrevented] = true;
103101
}
104102

105103
get target() { return this[kTarget]; }
106104
get currentTarget() { return this[kTarget]; }
107105
get srcElement() { return this[kTarget]; }
108106

109-
get type() { return this.#type; }
107+
get type() { return this[kType]; }
110108

111-
get cancelable() { return this.#cancelable; }
109+
get cancelable() { return this[kCancelable]; }
112110

113-
get defaultPrevented() { return this.#cancelable && this.#defaultPrevented; }
111+
get defaultPrevented() {
112+
return this[kCancelable] && this[kDefaultPrevented];
113+
}
114114

115-
get timeStamp() { return this.#timestamp; }
115+
get timeStamp() { return this[kTimestamp]; }
116116

117117

118118
// The following are non-op and unused properties/methods from Web API Event.
@@ -121,19 +121,19 @@ class Event {
121121

122122
composedPath() { return this[kTarget] ? [this[kTarget]] : []; }
123123
get returnValue() { return !this.defaultPrevented; }
124-
get bubbles() { return this.#bubbles; }
125-
get composed() { return this.#composed; }
124+
get bubbles() { return this[kBubbles]; }
125+
get composed() { return this[kComposed]; }
126126
get eventPhase() {
127127
return this[kTarget] ? Event.AT_TARGET : Event.NONE;
128128
}
129-
get cancelBubble() { return this.#propagationStopped; }
129+
get cancelBubble() { return this[kPropagationStopped]; }
130130
set cancelBubble(value) {
131131
if (value) {
132132
this.stopPropagation();
133133
}
134134
}
135135
stopPropagation() {
136-
this.#propagationStopped = true;
136+
this[kPropagationStopped] = true;
137137
}
138138

139139
static NONE = 0;
@@ -157,15 +157,8 @@ Object.defineProperty(Event.prototype, SymbolToStringTag, {
157157
// the linked list makes dispatching faster, even if adding/removing is
158158
// slower.
159159
class Listener {
160-
next;
161-
previous;
162-
listener;
163-
callback;
164-
once;
165-
capture;
166-
passive;
167-
168160
constructor(previous, listener, once, capture, passive) {
161+
this.next = undefined;
169162
if (previous !== undefined)
170163
previous.next = this;
171164
this.previous = previous;
@@ -197,7 +190,9 @@ class EventTarget {
197190
// symbol as EventTarget may be used cross-realm. See discussion in #33661.
198191
static [kIsEventTarget] = true;
199192

200-
[kEvents] = new Map();
193+
constructor() {
194+
this[kEvents] = new Map();
195+
}
201196

202197
[kNewListener](size, type, listener, once, capture, passive) {}
203198
[kRemoveListener](size, type, listener, capture) {}
@@ -355,17 +350,22 @@ Object.defineProperty(EventTarget.prototype, SymbolToStringTag, {
355350
value: 'EventTarget',
356351
});
357352

353+
const kMaxListeners = Symbol('maxListeners');
354+
const kMaxListenersWarned = Symbol('maxListenersWarned');
358355
class NodeEventTarget extends EventTarget {
359356
static defaultMaxListeners = 10;
360357

361-
#maxListeners = NodeEventTarget.defaultMaxListeners;
362-
#maxListenersWarned = false;
358+
constructor() {
359+
super();
360+
this[kMaxListeners] = NodeEventTarget.defaultMaxListeners;
361+
this[kMaxListenersWarned] = false;
362+
}
363363

364364
[kNewListener](size, type, listener, once, capture, passive) {
365-
if (this.#maxListeners > 0 &&
366-
size > this.#maxListeners &&
367-
!this.#maxListenersWarned) {
368-
this.#maxListenersWarned = true;
365+
if (this[kMaxListeners] > 0 &&
366+
size > this[kMaxListeners] &&
367+
!this[kMaxListenersWarned]) {
368+
this[kMaxListenersWarned] = true;
369369
// No error code for this since it is a Warning
370370
// eslint-disable-next-line no-restricted-syntax
371371
const w = new Error('Possible EventTarget memory leak detected. ' +
@@ -382,12 +382,12 @@ class NodeEventTarget extends EventTarget {
382382

383383
setMaxListeners(n) {
384384
validateInteger(n, 'n', 0);
385-
this.#maxListeners = n;
385+
this[kMaxListeners] = n;
386386
return this;
387387
}
388388

389389
getMaxListeners() {
390-
return this.#maxListeners;
390+
return this[kMaxListeners];
391391
}
392392

393393
eventNames() {

0 commit comments

Comments
 (0)