diff --git a/src/babel/transformation/transformers/es6/tail-call.js b/src/babel/transformation/transformers/es6/tail-call.js index 247d408754..543624e837 100644 --- a/src/babel/transformation/transformers/es6/tail-call.js +++ b/src/babel/transformation/transformers/es6/tail-call.js @@ -51,7 +51,7 @@ var visitor = { }, ReferencedIdentifier(node, parent, scope, state) { - if (node.name === "arguments" && !state.isShadowed) { + if (node.name === "arguments" && (!state.isShadowed || node._shadowedFunctionLiteral)) { state.needsArguments = true; state.argumentsPaths.push(this); } @@ -211,6 +211,7 @@ class TailCallTransformer { var decl = t.variableDeclarator(this.argumentsId); if (this.argumentsId) { decl.init = t.identifier("arguments"); + decl.init._shadowedFunctionLiteral = true; } topVars.push(decl); } @@ -291,7 +292,8 @@ class TailCallTransformer { } subTransformCallExpression(node) { - var callee = node.callee, thisBinding, args; + var callee = node.callee; + var thisBinding, args; if (t.isMemberExpression(callee, { computed: false }) && t.isIdentifier(callee.property)) { switch (callee.property.name) { @@ -301,6 +303,7 @@ class TailCallTransformer { case "apply": args = node.arguments[1] || t.identifier("undefined"); + this.needsArguments = true; break; default: @@ -334,6 +337,10 @@ class TailCallTransformer { args = t.arrayExpression(node.arguments); } + if (t.isArrayExpression(args) && args.elements.length > this.node.params.length) { + this.needsArguments = true; + } + var argumentsId = this.getArgumentsId(); var params = this.getParams(); diff --git a/test/core/fixtures/transformation/es6.tail-call/max-args/actual.js b/test/core/fixtures/transformation/es6.tail-call/max-args/actual.js new file mode 100644 index 0000000000..f616841038 --- /dev/null +++ b/test/core/fixtures/transformation/es6.tail-call/max-args/actual.js @@ -0,0 +1,9 @@ +var count = (i = 10) => { + if (!i) return; + return count(i - 1); +}; + +function count2(i = 10) { + if (!i) return; + return count2(i - 1); +} diff --git a/test/core/fixtures/transformation/es6.tail-call/max-args/expected.js b/test/core/fixtures/transformation/es6.tail-call/max-args/expected.js new file mode 100644 index 0000000000..2960fa52d1 --- /dev/null +++ b/test/core/fixtures/transformation/es6.tail-call/max-args/expected.js @@ -0,0 +1,33 @@ +"use strict"; + +var count = function count() { + var _arguments = arguments; + var _again = true; + + _function: while (_again) { + i = undefined; + _again = false; + var i = _arguments[0] === undefined ? 10 : _arguments[0]; + + if (!i) return; + _arguments = [i - 1]; + _again = true; + continue _function; + } +}; + +function count2() { + var _arguments2 = arguments; + var _again2 = true; + + _function2: while (_again2) { + i = undefined; + _again2 = false; + var i = _arguments2[0] === undefined ? 10 : _arguments2[0]; + + if (!i) return; + _arguments2 = [i - 1]; + _again2 = true; + continue _function2; + } +}