From b1a394b4b9d83a3bcbe64de27b7d5c45881e5d15 Mon Sep 17 00:00:00 2001 From: Evan Wallace Date: Thu, 11 Mar 2021 11:05:38 -0800 Subject: [PATCH] fix #951: lower object rest and spread for v8 --- CHANGELOG.md | 4 ++++ internal/compat/js_table.go | 3 --- scripts/compat-table.js | 7 +++++++ 3 files changed, 11 insertions(+), 3 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 89f37b0c2b3..7c43c012647 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -14,6 +14,10 @@ Previously conditional CSS imports such as `@import "print.css" print;` was not supported at all and was considered a syntax error. With this release, it is now supported in all cases except when bundling an internal import. Support for bundling internal CSS imports is planned but will happen in a later release. +* Always lower object spread and rest when targeting V8 ([#951](https://github.com/evanw/esbuild/issues/951)) + + This release causes object spread (e.g. `a = {...b}`) and object rest (e.g. `{...a} = b`) to always be lowered to a manual implementation instead of using native syntax when the `--target=` parameter includes a V8-based JavaScript runtime such as `chrome`, `edge`, or `node`. It turns out this feature is implemented inefficiently in V8 and copying properties over to a new object is around a 2x performance improvement. In addition, doing this manually instead of using the native implementation generates a lot less work for the garbage collector. You can see [V8 bug 11536](https://bugs.chromium.org/p/v8/issues/detail?id=11536) for details. If the V8 performance bug is eventually fixed, the translation of this syntax will be disabled again for V8-based targets containing the bug fix. + ## 0.9.0 **This release contains backwards-incompatible changes.** Since esbuild is before version 1.0.0, these changes have been released as a new minor version to reflect this (as [recommended by npm](https://docs.npmjs.com/cli/v6/using-npm/semver/)). You should either be pinning the exact version of `esbuild` in your `package.json` file or be using a version range syntax that only accepts patch upgrades such as `^0.8.0`. See the documentation about [semver](https://docs.npmjs.com/cli/v6/using-npm/semver/) for more information. diff --git a/internal/compat/js_table.go b/internal/compat/js_table.go index 40f1c1c1698..c07548f3b8a 100644 --- a/internal/compat/js_table.go +++ b/internal/compat/js_table.go @@ -313,12 +313,9 @@ var jsTable = map[JSFeature]map[Engine][]int{ Safari: {7, 1}, }, ObjectRestSpread: { - Chrome: {60}, - Edge: {79}, ES: {2018}, Firefox: {55}, IOS: {11, 3}, - Node: {8, 3}, Safari: {11, 1}, }, OptionalCatchBinding: { diff --git a/scripts/compat-table.js b/scripts/compat-table.js index 4159dd37ab8..1b9ee7fe5c1 100644 --- a/scripts/compat-table.js +++ b/scripts/compat-table.js @@ -177,6 +177,13 @@ for (const test of [...es5.tests, ...es6.tests, ...stage4.tests, ...stage1to3.te } } +// Work around V8-specific issues +for (const v8 of ['chrome', 'edge', 'node']) { + // Always lower object rest and spread for V8-based JavaScript VMs because of + // a severe performance issue: https://bugs.chromium.org/p/v8/issues/detail?id=11536 + delete versions.ObjectRestSpread[v8] +} + for (const feature in features) { if (!features[feature].found) { throw new Error(`Did not find ${feature}`)