handle TCO for calls that exceed the functions parameter count - fixes #1589
This commit is contained in:
parent
f2f6bbb02c
commit
348c0d2542
@ -51,7 +51,7 @@ var visitor = {
|
|||||||
},
|
},
|
||||||
|
|
||||||
ReferencedIdentifier(node, parent, scope, state) {
|
ReferencedIdentifier(node, parent, scope, state) {
|
||||||
if (node.name === "arguments" && !state.isShadowed) {
|
if (node.name === "arguments" && (!state.isShadowed || node._shadowedFunctionLiteral)) {
|
||||||
state.needsArguments = true;
|
state.needsArguments = true;
|
||||||
state.argumentsPaths.push(this);
|
state.argumentsPaths.push(this);
|
||||||
}
|
}
|
||||||
@ -211,6 +211,7 @@ class TailCallTransformer {
|
|||||||
var decl = t.variableDeclarator(this.argumentsId);
|
var decl = t.variableDeclarator(this.argumentsId);
|
||||||
if (this.argumentsId) {
|
if (this.argumentsId) {
|
||||||
decl.init = t.identifier("arguments");
|
decl.init = t.identifier("arguments");
|
||||||
|
decl.init._shadowedFunctionLiteral = true;
|
||||||
}
|
}
|
||||||
topVars.push(decl);
|
topVars.push(decl);
|
||||||
}
|
}
|
||||||
@ -291,7 +292,8 @@ class TailCallTransformer {
|
|||||||
}
|
}
|
||||||
|
|
||||||
subTransformCallExpression(node) {
|
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)) {
|
if (t.isMemberExpression(callee, { computed: false }) && t.isIdentifier(callee.property)) {
|
||||||
switch (callee.property.name) {
|
switch (callee.property.name) {
|
||||||
@ -301,6 +303,7 @@ class TailCallTransformer {
|
|||||||
|
|
||||||
case "apply":
|
case "apply":
|
||||||
args = node.arguments[1] || t.identifier("undefined");
|
args = node.arguments[1] || t.identifier("undefined");
|
||||||
|
this.needsArguments = true;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
@ -334,6 +337,10 @@ class TailCallTransformer {
|
|||||||
args = t.arrayExpression(node.arguments);
|
args = t.arrayExpression(node.arguments);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (t.isArrayExpression(args) && args.elements.length > this.node.params.length) {
|
||||||
|
this.needsArguments = true;
|
||||||
|
}
|
||||||
|
|
||||||
var argumentsId = this.getArgumentsId();
|
var argumentsId = this.getArgumentsId();
|
||||||
var params = this.getParams();
|
var params = this.getParams();
|
||||||
|
|
||||||
|
|||||||
@ -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);
|
||||||
|
}
|
||||||
@ -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;
|
||||||
|
}
|
||||||
|
}
|
||||||
Loading…
x
Reference in New Issue
Block a user