Skip to content

Commit c875109

Browse files
committed
streams: use private symbol for bitmap state
PR-URL: nodejs#49993
1 parent aadfea4 commit c875109

File tree

2 files changed

+133
-141
lines changed

2 files changed

+133
-141
lines changed

lib/internal/streams/readable.js

+23-22
Original file line numberDiff line numberDiff line change
@@ -73,6 +73,7 @@ const {
7373
const { validateObject } = require('internal/validators');
7474

7575
const kPaused = Symbol('kPaused');
76+
const kState = Symbol('kState');
7677

7778
const { StringDecoder } = require('string_decoder');
7879
const from = require('internal/streams/from');
@@ -107,10 +108,10 @@ const kDataEmitted = 1 << 18;
107108
function makeBitMapDescriptor(bit) {
108109
return {
109110
enumerable: false,
110-
get() { return (this.state & bit) !== 0; },
111+
get() { return (this[kState] & bit) !== 0; },
111112
set(value) {
112-
if (value) this.state |= bit;
113-
else this.state &= ~bit;
113+
if (value) this[kState] |= bit;
114+
else this[kState] &= ~bit;
114115
},
115116
};
116117
}
@@ -163,13 +164,13 @@ function ReadableState(options, stream, isDuplex) {
163164

164165
// Bit map field to store ReadableState more effciently with 1 bit per field
165166
// instead of a V8 slot per field.
166-
this.state = kEmitClose | kAutoDestroy | kConstructed | kSync;
167+
this[kState] = kEmitClose | kAutoDestroy | kConstructed | kSync;
167168
// Object stream flag. Used to make read(n) ignore n and to
168169
// make all the buffer merging and length checks go away.
169-
if (options && options.objectMode) this.state |= kObjectMode;
170+
if (options && options.objectMode) this[kState] |= kObjectMode;
170171

171172
if (isDuplex && options && options.readableObjectMode)
172-
this.state |= kObjectMode;
173+
this[kState] |= kObjectMode;
173174

174175
// The point at which it stops calling _read() to fill the buffer
175176
// Note: 0 is a valid value, means "don't call _read preemptively ever"
@@ -188,10 +189,10 @@ function ReadableState(options, stream, isDuplex) {
188189
this[kPaused] = null;
189190

190191
// Should close be emitted on destroy. Defaults to true.
191-
if (options && options.emitClose === false) this.state &= ~kEmitClose;
192+
if (options && options.emitClose === false) this[kState] &= ~kEmitClose;
192193

193194
// Should .destroy() be called after 'end' (and potentially 'finish').
194-
if (options && options.autoDestroy === false) this.state &= ~kAutoDestroy;
195+
if (options && options.autoDestroy === false) this[kState] &= ~kAutoDestroy;
195196

196197

197198
// Indicates whether the stream has errored. When true no further
@@ -296,7 +297,7 @@ function readableAddChunk(stream, chunk, encoding, addToFront) {
296297
const state = stream._readableState;
297298

298299
let err;
299-
if ((state.state & kObjectMode) === 0) {
300+
if ((state[kState] & kObjectMode) === 0) {
300301
if (typeof chunk === 'string') {
301302
encoding = encoding || state.defaultEncoding;
302303
if (state.encoding !== encoding) {
@@ -323,11 +324,11 @@ function readableAddChunk(stream, chunk, encoding, addToFront) {
323324
if (err) {
324325
errorOrDestroy(stream, err);
325326
} else if (chunk === null) {
326-
state.state &= ~kReading;
327+
state[kState] &= ~kReading;
327328
onEofChunk(stream, state);
328-
} else if (((state.state & kObjectMode) !== 0) || (chunk && chunk.length > 0)) {
329+
} else if (((state[kState] & kObjectMode) !== 0) || (chunk && chunk.length > 0)) {
329330
if (addToFront) {
330-
if ((state.state & kEndEmitted) !== 0)
331+
if ((state[kState] & kEndEmitted) !== 0)
331332
errorOrDestroy(stream, new ERR_STREAM_UNSHIFT_AFTER_END_EVENT());
332333
else if (state.destroyed || state.errored)
333334
return false;
@@ -338,7 +339,7 @@ function readableAddChunk(stream, chunk, encoding, addToFront) {
338339
} else if (state.destroyed || state.errored) {
339340
return false;
340341
} else {
341-
state.state &= ~kReading;
342+
state[kState] &= ~kReading;
342343
if (state.decoder && !encoding) {
343344
chunk = state.decoder.write(chunk);
344345
if (state.objectMode || chunk.length !== 0)
@@ -350,7 +351,7 @@ function readableAddChunk(stream, chunk, encoding, addToFront) {
350351
}
351352
}
352353
} else if (!addToFront) {
353-
state.state &= ~kReading;
354+
state[kState] &= ~kReading;
354355
maybeReadMore(stream, state);
355356
}
356357

@@ -366,7 +367,7 @@ function addChunk(stream, state, chunk, addToFront) {
366367
stream.listenerCount('data') > 0) {
367368
// Use the guard to avoid creating `Set()` repeatedly
368369
// when we have multiple pipes.
369-
if ((state.state & kMultiAwaitDrain) !== 0) {
370+
if ((state[kState] & kMultiAwaitDrain) !== 0) {
370371
state.awaitDrainWriters.clear();
371372
} else {
372373
state.awaitDrainWriters = null;
@@ -382,7 +383,7 @@ function addChunk(stream, state, chunk, addToFront) {
382383
else
383384
state.buffer.push(chunk);
384385

385-
if ((state.state & kNeedReadable) !== 0)
386+
if ((state[kState] & kNeedReadable) !== 0)
386387
emitReadable(stream);
387388
}
388389
maybeReadMore(stream, state);
@@ -437,7 +438,7 @@ function computeNewHighWaterMark(n) {
437438
function howMuchToRead(n, state) {
438439
if (n <= 0 || (state.length === 0 && state.ended))
439440
return 0;
440-
if ((state.state & kObjectMode) !== 0)
441+
if ((state[kState] & kObjectMode) !== 0)
441442
return 1;
442443
if (NumberIsNaN(n)) {
443444
// Only flow one buffer at a time.
@@ -468,7 +469,7 @@ Readable.prototype.read = function(n) {
468469
state.highWaterMark = computeNewHighWaterMark(n);
469470

470471
if (n !== 0)
471-
state.state &= ~kEmittedReadable;
472+
state[kState] &= ~kEmittedReadable;
472473

473474
// If we're doing read(0) to trigger a readable event, but we
474475
// already have a bunch of data in the buffer, then just trigger
@@ -519,7 +520,7 @@ Readable.prototype.read = function(n) {
519520
// 3. Actually pull the requested chunks out of the buffer and return.
520521

521522
// if we need a readable event, then we need to do some reading.
522-
let doRead = (state.state & kNeedReadable) !== 0;
523+
let doRead = (state[kState] & kNeedReadable) !== 0;
523524
debug('need readable', doRead);
524525

525526
// If we currently have less than the highWaterMark, then also read some.
@@ -537,18 +538,18 @@ Readable.prototype.read = function(n) {
537538
debug('reading, ended or constructing', doRead);
538539
} else if (doRead) {
539540
debug('do read');
540-
state.state |= kReading | kSync;
541+
state[kState] |= kReading | kSync;
541542
// If the length is currently zero, then we *need* a readable event.
542543
if (state.length === 0)
543-
state.state |= kNeedReadable;
544+
state[kState] |= kNeedReadable;
544545

545546
// Call internal read method
546547
try {
547548
this._read(state.highWaterMark);
548549
} catch (err) {
549550
errorOrDestroy(this, err);
550551
}
551-
state.state &= ~kSync;
552+
state[kState] &= ~kSync;
552553

553554
// If _read pushed data synchronously, then `reading` will be false,
554555
// and we need to re-evaluate how much data we can return to the user.

0 commit comments

Comments
 (0)