From 3868d36e313e433b9942de93eeaa392ab7b85a5c Mon Sep 17 00:00:00 2001 From: "Fabio M. Costa" Date: Sun, 6 Dec 2015 18:31:23 -0800 Subject: [PATCH] [babel-plugin-transform-es2015-parameters] more oportunities for optimisations --- .../src/rest.js | 27 ++++++++++++++----- .../actual.js | 4 +++ .../expected.js | 8 ++++++ .../actual.js | 16 ++++++++--- .../expected.js | 16 ++++++++--- 5 files changed, 57 insertions(+), 14 deletions(-) diff --git a/packages/babel-plugin-transform-es2015-parameters/src/rest.js b/packages/babel-plugin-transform-es2015-parameters/src/rest.js index 0cc5a8c83a..aa4cb119a7 100644 --- a/packages/babel-plugin-transform-es2015-parameters/src/rest.js +++ b/packages/babel-plugin-transform-es2015-parameters/src/rest.js @@ -52,19 +52,34 @@ let memberExpressionOptimisationVisitor = { if (state.noOptimise) { state.deopted = true; } else { - if (path.parentPath.isMemberExpression({ computed: true, object: node })) { - // if we know that this member expression is referencing a number then we can safely - // optimise it - let prop = path.parentPath.get("property"); + let {parentPath} = path; + + // ex: args[0] + if (parentPath.isMemberExpression({ computed: true, object: node })) { + // if we know that this member expression is referencing a number then + // we can safely optimise it + let prop = parentPath.get("property"); if (prop.isBaseType("number")) { state.candidates.push(path); return; } } + // ex: args.length + if (parentPath.isMemberExpression({ computed: false, object: node })) { + let prop = parentPath.get("property"); + if (prop.node.name === "length") { + state.candidates.push(path); + return; + } + } + + // we can only do these optimizations if the rest variable would match + // the arguments exactly // optimise single spread args in calls - if (path.parentPath.isSpreadElement() && state.offset === 0) { - let call = path.parentPath.parentPath; + // ex: fn(...args) + if (state.offset === 0 && parentPath.isSpreadElement()) { + let call = parentPath.parentPath; if (call.isCallExpression() && call.node.arguments.length === 1) { state.candidates.push(path); return; diff --git a/packages/babel-plugin-transform-es2015-parameters/test/fixtures/parameters/rest-member-expression-deoptimisation/actual.js b/packages/babel-plugin-transform-es2015-parameters/test/fixtures/parameters/rest-member-expression-deoptimisation/actual.js index 0e52926868..c65daf8da7 100644 --- a/packages/babel-plugin-transform-es2015-parameters/test/fixtures/parameters/rest-member-expression-deoptimisation/actual.js +++ b/packages/babel-plugin-transform-es2015-parameters/test/fixtures/parameters/rest-member-expression-deoptimisation/actual.js @@ -28,3 +28,7 @@ var b = function (foo, ...bar) { var join = "join"; return bar[join]; }; + +var b = function (...bar) { + return bar.len; +}; diff --git a/packages/babel-plugin-transform-es2015-parameters/test/fixtures/parameters/rest-member-expression-deoptimisation/expected.js b/packages/babel-plugin-transform-es2015-parameters/test/fixtures/parameters/rest-member-expression-deoptimisation/expected.js index 56bad87ea3..dcb833d10e 100644 --- a/packages/babel-plugin-transform-es2015-parameters/test/fixtures/parameters/rest-member-expression-deoptimisation/expected.js +++ b/packages/babel-plugin-transform-es2015-parameters/test/fixtures/parameters/rest-member-expression-deoptimisation/expected.js @@ -53,3 +53,11 @@ var b = function (foo) { return bar[join]; }; + +var b = function () { + for (var _len7 = arguments.length, bar = Array(_len7), _key7 = 0; _key7 < _len7; _key7++) { + bar[_key7] = arguments[_key7]; + } + + return bar.len; +}; diff --git a/packages/babel-plugin-transform-es2015-parameters/test/fixtures/parameters/rest-member-expression-optimisation/actual.js b/packages/babel-plugin-transform-es2015-parameters/test/fixtures/parameters/rest-member-expression-optimisation/actual.js index 8e81076ecc..238b33c18d 100644 --- a/packages/babel-plugin-transform-es2015-parameters/test/fixtures/parameters/rest-member-expression-optimisation/actual.js +++ b/packages/babel-plugin-transform-es2015-parameters/test/fixtures/parameters/rest-member-expression-optimisation/actual.js @@ -1,9 +1,17 @@ var t = function (...items) { - var x = items[0]; - var y = items[1]; + var x = items[0]; + var y = items[1]; } function t(...items) { - var x = items[0]; - var y = items[1]; + var x = items[0]; + var y = items[1]; } + +function t(...items) { + var a = []; + for (var i = 0; i < items.length; i++) { + a.push(i); + } + return a; +} \ No newline at end of file diff --git a/packages/babel-plugin-transform-es2015-parameters/test/fixtures/parameters/rest-member-expression-optimisation/expected.js b/packages/babel-plugin-transform-es2015-parameters/test/fixtures/parameters/rest-member-expression-optimisation/expected.js index 9a680b3ad4..451e173701 100644 --- a/packages/babel-plugin-transform-es2015-parameters/test/fixtures/parameters/rest-member-expression-optimisation/expected.js +++ b/packages/babel-plugin-transform-es2015-parameters/test/fixtures/parameters/rest-member-expression-optimisation/expected.js @@ -1,9 +1,17 @@ var t = function () { - var x = arguments.length <= 0 || arguments[0] === undefined ? undefined : arguments[0]; - var y = arguments.length <= 1 || arguments[1] === undefined ? undefined : arguments[1]; + var x = arguments.length <= 0 || arguments[0] === undefined ? undefined : arguments[0]; + var y = arguments.length <= 1 || arguments[1] === undefined ? undefined : arguments[1]; }; function t() { - var x = arguments.length <= 0 || arguments[0] === undefined ? undefined : arguments[0]; - var y = arguments.length <= 1 || arguments[1] === undefined ? undefined : arguments[1]; + var x = arguments.length <= 0 || arguments[0] === undefined ? undefined : arguments[0]; + var y = arguments.length <= 1 || arguments[1] === undefined ? undefined : arguments[1]; +} + +function t() { + var a = []; + for (var i = 0; i < arguments.length; i++) { + a.push(i); + } + return a; }