From 505d412d508fa2d95d03175e73e9dc92e50785e0 Mon Sep 17 00:00:00 2001 From: Ruben Bridgewater Date: Tue, 13 Feb 2018 00:56:35 +0100 Subject: [PATCH] lib: switch to Number.isNaN MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Number.isNaN is now as fast as `val !== val`. Switch to the more readable version. Also switch all `isNaN` to `Number.isNaN`. PR-URL: https://github.com/nodejs/node/pull/18744 Reviewed-By: Weijia Wang Reviewed-By: Michaƫl Zasso Reviewed-By: Colin Ihrig Reviewed-By: James M Snell Reviewed-By: Yuta Hiroto Reviewed-By: Luigi Pinca --- .eslintrc.yaml | 1 + lib/_stream_readable.js | 2 +- lib/buffer.js | 20 ++++++++++---------- lib/events.js | 6 ++---- lib/internal/crypto/random.js | 4 ++-- lib/internal/repl.js | 2 +- lib/net.js | 2 +- lib/readline.js | 2 +- lib/repl.js | 2 +- lib/zlib.js | 14 +++++++------- 10 files changed, 27 insertions(+), 28 deletions(-) diff --git a/.eslintrc.yaml b/.eslintrc.yaml index 377f615e8a1d20..a46caecf085bb8 100644 --- a/.eslintrc.yaml +++ b/.eslintrc.yaml @@ -74,6 +74,7 @@ rules: message: __defineSetter__ is deprecated. no-return-await: error no-self-assign: error + no-self-compare: error no-throw-literal: error no-unused-labels: error no-useless-call: error diff --git a/lib/_stream_readable.js b/lib/_stream_readable.js index 9678d77f6c6434..5cdc0864a0e1eb 100644 --- a/lib/_stream_readable.js +++ b/lib/_stream_readable.js @@ -341,7 +341,7 @@ function howMuchToRead(n, state) { return 0; if (state.objectMode) return 1; - if (n !== n) { + if (Number.isNaN(n)) { // Only flow one buffer at a time if (state.flowing && state.length) return state.buffer.head.data.length; diff --git a/lib/buffer.js b/lib/buffer.js index 01e605f50a8376..f43f67bb9404c5 100644 --- a/lib/buffer.js +++ b/lib/buffer.js @@ -363,8 +363,7 @@ function fromArrayBuffer(obj, byteOffset, length) { byteOffset = 0; } else { byteOffset = +byteOffset; - // check for NaN - if (byteOffset !== byteOffset) + if (Number.isNaN(byteOffset)) byteOffset = 0; } @@ -376,7 +375,7 @@ function fromArrayBuffer(obj, byteOffset, length) { if (length === undefined) { length = maxLength; } else { - // convert length to non-negative integer + // Convert length to non-negative integer. length = +length; if (length > 0) { if (length > maxLength) @@ -760,8 +759,7 @@ function bidirectionalIndexOf(buffer, val, byteOffset, encoding, dir) { // Coerce to Number. Values like null and [] become 0. byteOffset = +byteOffset; // If the offset is undefined, "foo", {}, coerces to NaN, search whole buffer. - // `x !== x`-style conditionals are a faster form of `isNaN(x)` - if (byteOffset !== byteOffset) { + if (Number.isNaN(byteOffset)) { byteOffset = dir ? 0 : buffer.length; } dir = !!dir; // Cast to bool. @@ -996,15 +994,17 @@ function adjustOffset(offset, length) { // Use Math.trunc() to convert offset to an integer value that can be larger // than an Int32. Hence, don't use offset | 0 or similar techniques. offset = Math.trunc(offset); - // `x !== x`-style conditionals are a faster form of `isNaN(x)` - if (offset === 0 || offset !== offset) { + if (offset === 0) { return 0; - } else if (offset < 0) { + } + if (offset < 0) { offset += length; return offset > 0 ? offset : 0; - } else { - return offset < length ? offset : length; } + if (offset < length) { + return offset; + } + return Number.isNaN(offset) ? 0 : length; } diff --git a/lib/events.js b/lib/events.js index 9ad5ec376ff8c8..aec30e7239d13d 100644 --- a/lib/events.js +++ b/lib/events.js @@ -52,9 +52,7 @@ Object.defineProperty(EventEmitter, 'defaultMaxListeners', { return defaultMaxListeners; }, set: function(arg) { - // check whether the input is a positive number (whose value is zero or - // greater and not a NaN). - if (typeof arg !== 'number' || arg < 0 || arg !== arg) { + if (typeof arg !== 'number' || arg < 0 || Number.isNaN(arg)) { const errors = lazyErrors(); throw new errors.RangeError('ERR_OUT_OF_RANGE', 'defaultMaxListeners', @@ -79,7 +77,7 @@ EventEmitter.init = function() { // Obviously not all Emitters should be limited to 10. This function allows // that to be increased. Set to zero for unlimited. EventEmitter.prototype.setMaxListeners = function setMaxListeners(n) { - if (typeof n !== 'number' || n < 0 || isNaN(n)) { + if (typeof n !== 'number' || n < 0 || Number.isNaN(n)) { const errors = lazyErrors(); throw new errors.RangeError('ERR_OUT_OF_RANGE', 'n', 'a non-negative number', n); diff --git a/lib/internal/crypto/random.js b/lib/internal/crypto/random.js index 52afbd8af3f034..9ffaa4de76f652 100644 --- a/lib/internal/crypto/random.js +++ b/lib/internal/crypto/random.js @@ -11,7 +11,7 @@ const { kMaxLength } = require('buffer'); const kMaxUint32 = Math.pow(2, 32) - 1; function assertOffset(offset, length) { - if (typeof offset !== 'number' || offset !== offset) { + if (typeof offset !== 'number' || Number.isNaN(offset)) { throw new errors.TypeError('ERR_INVALID_ARG_TYPE', 'offset', 'number'); } @@ -25,7 +25,7 @@ function assertOffset(offset, length) { } function assertSize(size, offset = 0, length = Infinity) { - if (typeof size !== 'number' || size !== size) { + if (typeof size !== 'number' || Number.isNaN(size)) { throw new errors.TypeError('ERR_INVALID_ARG_TYPE', 'size', 'number'); } diff --git a/lib/internal/repl.js b/lib/internal/repl.js index adbb80b0af7e60..4c4e3c8cb4e275 100644 --- a/lib/internal/repl.js +++ b/lib/internal/repl.js @@ -51,7 +51,7 @@ function createRepl(env, opts, cb) { } const historySize = Number(env.NODE_REPL_HISTORY_SIZE); - if (!isNaN(historySize) && historySize > 0) { + if (!Number.isNaN(historySize) && historySize > 0) { opts.historySize = historySize; } else { // XXX(chrisdickinson): set here to avoid affecting existing applications diff --git a/lib/net.js b/lib/net.js index 1bc28e856df5bd..41ddda767d832a 100644 --- a/lib/net.js +++ b/lib/net.js @@ -1304,7 +1304,7 @@ function createServerHandle(address, port, addressType, fd) { handle = new Pipe(PipeConstants.SERVER); if (process.platform === 'win32') { var instances = parseInt(process.env.NODE_PENDING_PIPE_INSTANCES); - if (!isNaN(instances)) { + if (!Number.isNaN(instances)) { handle.setPendingInstances(instances); } } diff --git a/lib/readline.js b/lib/readline.js index 5f28f4c43f17d5..15933e69302d84 100644 --- a/lib/readline.js +++ b/lib/readline.js @@ -103,7 +103,7 @@ function Interface(input, output, completer, terminal) { } if (typeof historySize !== 'number' || - isNaN(historySize) || + Number.isNaN(historySize) || historySize < 0) { throw new errors.RangeError( 'ERR_INVALID_OPT_VALUE', diff --git a/lib/repl.js b/lib/repl.js index 84682b1b63e6cc..bd41ecdccf6972 100644 --- a/lib/repl.js +++ b/lib/repl.js @@ -575,7 +575,7 @@ function REPLServer(prompt, // display next prompt and return. if (trimmedCmd) { if (trimmedCmd.charAt(0) === '.' && trimmedCmd.charAt(1) !== '.' && - isNaN(parseFloat(trimmedCmd))) { + Number.isNaN(parseFloat(trimmedCmd))) { const matches = trimmedCmd.match(/^\.([^\s]+)\s*(.*)$/); const keyword = matches && matches[1]; const rest = matches && matches[2]; diff --git a/lib/zlib.js b/lib/zlib.js index 6262ddb6bc6522..aff72a868612e5 100644 --- a/lib/zlib.js +++ b/lib/zlib.js @@ -177,7 +177,7 @@ function Zlib(opts, mode) { if (opts) { chunkSize = opts.chunkSize; - if (chunkSize !== undefined && chunkSize === chunkSize) { + if (chunkSize !== undefined && !Number.isNaN(chunkSize)) { if (chunkSize < Z_MIN_CHUNK || !Number.isFinite(chunkSize)) throw new errors.RangeError('ERR_INVALID_OPT_VALUE', 'chunkSize', @@ -187,7 +187,7 @@ function Zlib(opts, mode) { } flush = opts.flush; - if (flush !== undefined && flush === flush) { + if (flush !== undefined && !Number.isNaN(flush)) { if (flush < Z_NO_FLUSH || flush > Z_BLOCK || !Number.isFinite(flush)) throw new errors.RangeError('ERR_INVALID_OPT_VALUE', 'flush', flush); } else { @@ -195,7 +195,7 @@ function Zlib(opts, mode) { } finishFlush = opts.finishFlush; - if (finishFlush !== undefined && finishFlush === finishFlush) { + if (finishFlush !== undefined && !Number.isNaN(finishFlush)) { if (finishFlush < Z_NO_FLUSH || finishFlush > Z_BLOCK || !Number.isFinite(finishFlush)) { throw new errors.RangeError('ERR_INVALID_OPT_VALUE', @@ -207,7 +207,7 @@ function Zlib(opts, mode) { } windowBits = opts.windowBits; - if (windowBits !== undefined && windowBits === windowBits) { + if (windowBits !== undefined && !Number.isNaN(windowBits)) { if (windowBits < Z_MIN_WINDOWBITS || windowBits > Z_MAX_WINDOWBITS || !Number.isFinite(windowBits)) { throw new errors.RangeError('ERR_INVALID_OPT_VALUE', @@ -219,7 +219,7 @@ function Zlib(opts, mode) { } level = opts.level; - if (level !== undefined && level === level) { + if (level !== undefined && !Number.isNaN(level)) { if (level < Z_MIN_LEVEL || level > Z_MAX_LEVEL || !Number.isFinite(level)) { throw new errors.RangeError('ERR_INVALID_OPT_VALUE', @@ -230,7 +230,7 @@ function Zlib(opts, mode) { } memLevel = opts.memLevel; - if (memLevel !== undefined && memLevel === memLevel) { + if (memLevel !== undefined && !Number.isNaN(memLevel)) { if (memLevel < Z_MIN_MEMLEVEL || memLevel > Z_MAX_MEMLEVEL || !Number.isFinite(memLevel)) { throw new errors.RangeError('ERR_INVALID_OPT_VALUE', @@ -241,7 +241,7 @@ function Zlib(opts, mode) { } strategy = opts.strategy; - if (strategy !== undefined && strategy === strategy) { + if (strategy !== undefined && !Number.isNaN(strategy)) { if (strategy < Z_DEFAULT_STRATEGY || strategy > Z_FIXED || !Number.isFinite(strategy)) { throw new errors.TypeError('ERR_INVALID_OPT_VALUE',