From 8e1f134635a8a97870be74ba6b6e754fa8f82877 Mon Sep 17 00:00:00 2001 From: Sebastian McKenzie Date: Mon, 22 Jun 2015 11:54:57 +0100 Subject: [PATCH] fix rest parameter array allocation loop being incorrectly aliased - fixes #1800 --- CHANGELOG.md | 5 +++ .../transformers/es6/parameters.rest.js | 14 ++++--- .../async-function/actual.js | 7 ++++ .../async-function/expected.js | 39 +++++++++++++++++++ .../async-function/options.json | 3 ++ 5 files changed, 62 insertions(+), 6 deletions(-) create mode 100644 test/core/fixtures/transformation/es6.parameters.rest/async-function/actual.js create mode 100644 test/core/fixtures/transformation/es6.parameters.rest/async-function/expected.js create mode 100644 test/core/fixtures/transformation/es6.parameters.rest/async-function/options.json diff --git a/CHANGELOG.md b/CHANGELOG.md index 440edeed41..c9a33f3b96 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -13,6 +13,11 @@ _Note: Gaps between patch versions are faulty/broken releases._ See [CHANGELOG - 6to5](CHANGELOG-6to5.md) for the pre-4.0.0 version changelog. +## 5.6.3 + + * **Bug Fix** + * Fix rest parameter array allocation loop being incorrectly aliased. + ## 5.6.2 * **Bug Fix** diff --git a/src/babel/transformation/transformers/es6/parameters.rest.js b/src/babel/transformation/transformers/es6/parameters.rest.js index 4defa80a57..2c337f2c61 100644 --- a/src/babel/transformation/transformers/es6/parameters.rest.js +++ b/src/babel/transformation/transformers/es6/parameters.rest.js @@ -100,7 +100,6 @@ export var visitor = { } // check and optimise for extremely common cases - var state = { references: [], offset: node.params.length, @@ -135,6 +134,9 @@ export var visitor = { state.references = state.references.concat(state.candidates); } + // deopt shadowed functions as transforms like regenerator may try touch the allocation loop + state.deopted = state.deopted || !!node.shadow; + // var start = t.literal(node.params.length); @@ -173,13 +175,13 @@ export var visitor = { LEN: len }); - if (!state.deopted) { + if (state.deopted) { + loop._blockHoist = node.params.length + 1; + node.body.body.unshift(loop); + } else { // perform allocation at the lowest common denominator of all references + loop._blockHoist = 1; this.getEarliestCommonAncestorFrom(state.references).getStatementParent().insertBefore(loop); - return; } - - loop._blockHoist = node.params.length + 1; - node.body.body.unshift(loop); } }; diff --git a/test/core/fixtures/transformation/es6.parameters.rest/async-function/actual.js b/test/core/fixtures/transformation/es6.parameters.rest/async-function/actual.js new file mode 100644 index 0000000000..1bb83e3072 --- /dev/null +++ b/test/core/fixtures/transformation/es6.parameters.rest/async-function/actual.js @@ -0,0 +1,7 @@ +var fn = async (...rest) => rest; + +var fn = async (...rest) => { + if (true) { + rest; + } +}; diff --git a/test/core/fixtures/transformation/es6.parameters.rest/async-function/expected.js b/test/core/fixtures/transformation/es6.parameters.rest/async-function/expected.js new file mode 100644 index 0000000000..30a54f9006 --- /dev/null +++ b/test/core/fixtures/transformation/es6.parameters.rest/async-function/expected.js @@ -0,0 +1,39 @@ +"use strict"; + +var _this = this; + +var fn = function fn() { + for (var _len = arguments.length, rest = Array(_len), _key = 0; _key < _len; _key++) { + rest[_key] = arguments[_key]; + } + + return regeneratorRuntime.async(function fn$(context$1$0) { + while (1) switch (context$1$0.prev = context$1$0.next) { + case 0: + return context$1$0.abrupt("return", rest); + + case 1: + case "end": + return context$1$0.stop(); + } + }, null, _this); +}; + +var fn = function fn() { + for (var _len2 = arguments.length, rest = Array(_len2), _key2 = 0; _key2 < _len2; _key2++) { + rest[_key2] = arguments[_key2]; + } + + return regeneratorRuntime.async(function fn$(context$1$0) { + while (1) switch (context$1$0.prev = context$1$0.next) { + case 0: + if (true) { + rest; + } + + case 1: + case "end": + return context$1$0.stop(); + } + }, null, _this); +}; diff --git a/test/core/fixtures/transformation/es6.parameters.rest/async-function/options.json b/test/core/fixtures/transformation/es6.parameters.rest/async-function/options.json new file mode 100644 index 0000000000..b0b9a96ef0 --- /dev/null +++ b/test/core/fixtures/transformation/es6.parameters.rest/async-function/options.json @@ -0,0 +1,3 @@ +{ + "stage": 0 +}