From ce6673a256574c11d1ca6d4bcdba1aeb32eccc4d Mon Sep 17 00:00:00 2001 From: Denis Pushkarev Date: Fri, 6 Nov 2020 03:07:31 +0700 Subject: [PATCH] forced replacement of `Array#{ reduce, reduceRight }` in Chrome 80-82, #766 https://bugs.chromium.org/p/chromium/issues/detail?id=1049982 --- CHANGELOG.md | 1 + packages/core-js-compat/src/data.js | 6 ++++-- packages/core-js/internals/engine-is-node.js | 4 ++++ packages/core-js/internals/microtask.js | 3 +-- packages/core-js/internals/task.js | 4 ++-- packages/core-js/modules/es.array.reduce-right.js | 7 ++++++- packages/core-js/modules/es.array.reduce.js | 7 ++++++- packages/core-js/modules/es.promise.js | 3 +-- packages/core-js/modules/web.queue-microtask.js | 5 ++--- 9 files changed, 27 insertions(+), 13 deletions(-) create mode 100644 packages/core-js/internals/engine-is-node.js diff --git a/CHANGELOG.md b/CHANGELOG.md index 204fdf405ad6..58748e776e3e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -10,6 +10,7 @@ - Fixed microtask implementation in engines with `MutationObserver`, but without `document`, [#865](https://github.com/zloirock/core-js/issues/865), [#866](https://github.com/zloirock/core-js/issues/866) - Fixed `core-js-builder` with an empty (after the targets engines or another filtration) modules list, [#822](https://github.com/zloirock/core-js/issues/822) - Added a workaround for 3rd party `Reflect.set` polyfill bug, [#847](https://github.com/zloirock/core-js/issues/847) +- Forced replacement of `Array#{ reduce, reduceRight }` in Chrome 80-82 because of [a bug](https://bugs.chromium.org/p/chromium/issues/detail?id=1049982), [#766](https://github.com/zloirock/core-js/issues/766) - Updated compat data: - Chrome up to 86 - FF up to 82 diff --git a/packages/core-js-compat/src/data.js b/packages/core-js-compat/src/data.js index dd81d59d93d9..0324a0388384 100644 --- a/packages/core-js-compat/src/data.js +++ b/packages/core-js-compat/src/data.js @@ -202,15 +202,17 @@ const data = { safari: '9.0', }, 'es.array.reduce': { - chrome: '48', + chrome: '83', // https://bugs.chromium.org/p/chromium/issues/detail?id=1049982 edge: '15', firefox: '50', + node: '6.0', // ^^^ safari: '9.0', }, 'es.array.reduce-right': { - chrome: '48', + chrome: '83', // https://bugs.chromium.org/p/chromium/issues/detail?id=1049982 edge: '15', firefox: '50', + node: '6.0', // ^^^ safari: '9.0', }, 'es.array.reverse': { diff --git a/packages/core-js/internals/engine-is-node.js b/packages/core-js/internals/engine-is-node.js new file mode 100644 index 000000000000..56fdc036d81a --- /dev/null +++ b/packages/core-js/internals/engine-is-node.js @@ -0,0 +1,4 @@ +var classof = require('../internals/classof-raw'); +var global = require('../internals/global'); + +module.exports = classof(global.process) == 'process'; diff --git a/packages/core-js/internals/microtask.js b/packages/core-js/internals/microtask.js index 1a80a6491aca..2da2c24a46ed 100644 --- a/packages/core-js/internals/microtask.js +++ b/packages/core-js/internals/microtask.js @@ -1,14 +1,13 @@ var global = require('../internals/global'); var getOwnPropertyDescriptor = require('../internals/object-get-own-property-descriptor').f; -var classof = require('../internals/classof-raw'); var macrotask = require('../internals/task').set; var IS_IOS = require('../internals/engine-is-ios'); +var IS_NODE = require('../internals/engine-is-node'); var MutationObserver = global.MutationObserver || global.WebKitMutationObserver; var document = global.document; var process = global.process; var Promise = global.Promise; -var IS_NODE = classof(process) == 'process'; // Node.js 11 shows ExperimentalWarning on getting `queueMicrotask` var queueMicrotaskDescriptor = getOwnPropertyDescriptor(global, 'queueMicrotask'); var queueMicrotask = queueMicrotaskDescriptor && queueMicrotaskDescriptor.value; diff --git a/packages/core-js/internals/task.js b/packages/core-js/internals/task.js index c92190fb1533..bb2c534caf20 100644 --- a/packages/core-js/internals/task.js +++ b/packages/core-js/internals/task.js @@ -1,10 +1,10 @@ var global = require('../internals/global'); var fails = require('../internals/fails'); -var classof = require('../internals/classof-raw'); var bind = require('../internals/function-bind-context'); var html = require('../internals/html'); var createElement = require('../internals/document-create-element'); var IS_IOS = require('../internals/engine-is-ios'); +var IS_NODE = require('../internals/engine-is-node'); var location = global.location; var set = global.setImmediate; @@ -58,7 +58,7 @@ if (!set || !clear) { delete queue[id]; }; // Node.js 0.8- - if (classof(process) == 'process') { + if (IS_NODE) { defer = function (id) { process.nextTick(runner(id)); }; diff --git a/packages/core-js/modules/es.array.reduce-right.js b/packages/core-js/modules/es.array.reduce-right.js index 37aeb2d315ef..f11d8d467c26 100644 --- a/packages/core-js/modules/es.array.reduce-right.js +++ b/packages/core-js/modules/es.array.reduce-right.js @@ -3,14 +3,19 @@ var $ = require('../internals/export'); var $reduceRight = require('../internals/array-reduce').right; var arrayMethodIsStrict = require('../internals/array-method-is-strict'); var arrayMethodUsesToLength = require('../internals/array-method-uses-to-length'); +var CHROME_VERSION = require('../internals/engine-v8-version'); +var IS_NODE = require('../internals/engine-is-node'); var STRICT_METHOD = arrayMethodIsStrict('reduceRight'); // For preventing possible almost infinite loop in non-standard implementations, test the forward version of the method var USES_TO_LENGTH = arrayMethodUsesToLength('reduce', { 1: 0 }); +// Chrome 80-82 has a critical bug +// https://bugs.chromium.org/p/chromium/issues/detail?id=1049982 +var CHROME_BUG = !IS_NODE && CHROME_VERSION > 79 && CHROME_VERSION < 83; // `Array.prototype.reduceRight` method // https://tc39.github.io/ecma262/#sec-array.prototype.reduceright -$({ target: 'Array', proto: true, forced: !STRICT_METHOD || !USES_TO_LENGTH }, { +$({ target: 'Array', proto: true, forced: !STRICT_METHOD || !USES_TO_LENGTH || CHROME_BUG }, { reduceRight: function reduceRight(callbackfn /* , initialValue */) { return $reduceRight(this, callbackfn, arguments.length, arguments.length > 1 ? arguments[1] : undefined); } diff --git a/packages/core-js/modules/es.array.reduce.js b/packages/core-js/modules/es.array.reduce.js index 40e0458751f9..3d66308b01f8 100644 --- a/packages/core-js/modules/es.array.reduce.js +++ b/packages/core-js/modules/es.array.reduce.js @@ -3,13 +3,18 @@ var $ = require('../internals/export'); var $reduce = require('../internals/array-reduce').left; var arrayMethodIsStrict = require('../internals/array-method-is-strict'); var arrayMethodUsesToLength = require('../internals/array-method-uses-to-length'); +var CHROME_VERSION = require('../internals/engine-v8-version'); +var IS_NODE = require('../internals/engine-is-node'); var STRICT_METHOD = arrayMethodIsStrict('reduce'); var USES_TO_LENGTH = arrayMethodUsesToLength('reduce', { 1: 0 }); +// Chrome 80-82 has a critical bug +// https://bugs.chromium.org/p/chromium/issues/detail?id=1049982 +var CHROME_BUG = !IS_NODE && CHROME_VERSION > 79 && CHROME_VERSION < 83; // `Array.prototype.reduce` method // https://tc39.github.io/ecma262/#sec-array.prototype.reduce -$({ target: 'Array', proto: true, forced: !STRICT_METHOD || !USES_TO_LENGTH }, { +$({ target: 'Array', proto: true, forced: !STRICT_METHOD || !USES_TO_LENGTH || CHROME_BUG }, { reduce: function reduce(callbackfn /* , initialValue */) { return $reduce(this, callbackfn, arguments.length, arguments.length > 1 ? arguments[1] : undefined); } diff --git a/packages/core-js/modules/es.promise.js b/packages/core-js/modules/es.promise.js index b6e0d53b16fe..42df9b3223dd 100644 --- a/packages/core-js/modules/es.promise.js +++ b/packages/core-js/modules/es.promise.js @@ -11,7 +11,6 @@ var setSpecies = require('../internals/set-species'); var isObject = require('../internals/is-object'); var aFunction = require('../internals/a-function'); var anInstance = require('../internals/an-instance'); -var classof = require('../internals/classof-raw'); var inspectSource = require('../internals/inspect-source'); var iterate = require('../internals/iterate'); var checkCorrectnessOfIteration = require('../internals/check-correctness-of-iteration'); @@ -25,6 +24,7 @@ var perform = require('../internals/perform'); var InternalStateModule = require('../internals/internal-state'); var isForced = require('../internals/is-forced'); var wellKnownSymbol = require('../internals/well-known-symbol'); +var IS_NODE = require('../internals/engine-is-node'); var V8_VERSION = require('../internals/engine-v8-version'); var SPECIES = wellKnownSymbol('species'); @@ -39,7 +39,6 @@ var process = global.process; var $fetch = getBuiltIn('fetch'); var newPromiseCapability = newPromiseCapabilityModule.f; var newGenericPromiseCapability = newPromiseCapability; -var IS_NODE = classof(process) == 'process'; var DISPATCH_EVENT = !!(document && document.createEvent && global.dispatchEvent); var UNHANDLED_REJECTION = 'unhandledrejection'; var REJECTION_HANDLED = 'rejectionhandled'; diff --git a/packages/core-js/modules/web.queue-microtask.js b/packages/core-js/modules/web.queue-microtask.js index ac5530c1b2d1..181643a1365d 100644 --- a/packages/core-js/modules/web.queue-microtask.js +++ b/packages/core-js/modules/web.queue-microtask.js @@ -1,16 +1,15 @@ var $ = require('../internals/export'); var global = require('../internals/global'); var microtask = require('../internals/microtask'); -var classof = require('../internals/classof-raw'); +var IS_NODE = require('../internals/engine-is-node'); var process = global.process; -var isNode = classof(process) == 'process'; // `queueMicrotask` method // https://html.spec.whatwg.org/multipage/timers-and-user-prompts.html#dom-queuemicrotask $({ global: true, enumerable: true, noTargetGet: true }, { queueMicrotask: function queueMicrotask(fn) { - var domain = isNode && process.domain; + var domain = IS_NODE && process.domain; microtask(domain ? domain.bind(fn) : fn); } });