parent
8d92a75190
commit
6220fd9fc3
@ -1,3 +1,4 @@
|
||||
{
|
||||
FUNCTION_ID:while (true) BLOCK
|
||||
var AGAIN_ID = true;
|
||||
FUNCTION_ID: while (AGAIN_ID) BLOCK
|
||||
}
|
||||
|
||||
@ -1,23 +0,0 @@
|
||||
(function () {
|
||||
function Tail(func, args, context) {
|
||||
this.func = func;
|
||||
this.args = args;
|
||||
this.context = context;
|
||||
}
|
||||
|
||||
Tail.prototype._isTailDescriptor = true;
|
||||
|
||||
var isRunning = false;
|
||||
|
||||
return function (func, args, context) {
|
||||
var result = new Tail(func, args, context);
|
||||
if (!isRunning) {
|
||||
isRunning = true;
|
||||
do {
|
||||
result = result.func.apply(result.context, result.args);
|
||||
} while (result instanceof Tail || (result && result._isTailDescriptor));
|
||||
isRunning = false;
|
||||
}
|
||||
return result;
|
||||
};
|
||||
})()
|
||||
@ -40,6 +40,10 @@ TailCallTransformer.prototype.getFunctionId = function () {
|
||||
return this.functionId = this.functionId || this.scope.generateUidIdentifier("function");
|
||||
};
|
||||
|
||||
TailCallTransformer.prototype.getAgainId = function () {
|
||||
return this.againId = this.againId || this.scope.generateUidIdentifier("again");
|
||||
};
|
||||
|
||||
TailCallTransformer.prototype.getParams = function () {
|
||||
var params = this.params;
|
||||
|
||||
@ -112,9 +116,12 @@ TailCallTransformer.prototype.run = function () {
|
||||
body.unshift(t.variableDeclaration("var", paramDecls));
|
||||
}
|
||||
|
||||
body.push(t.returnStatement());
|
||||
body.unshift(t.expressionStatement(
|
||||
t.assignmentExpression("=", this.getAgainId(), t.literal(false)))
|
||||
);
|
||||
|
||||
node.body = util.template("tail-call-body", {
|
||||
AGAIN_ID: this.getAgainId(),
|
||||
THIS_ID: this.thisId,
|
||||
ARGUMENTS_ID: this.argumentsId,
|
||||
FUNCTION_ID: this.getFunctionId(),
|
||||
@ -288,6 +295,9 @@ TailCallTransformer.prototype.subTransformCallExpression = function (node) {
|
||||
}
|
||||
}
|
||||
|
||||
body.push(t.expressionStatement(
|
||||
t.assignmentExpression("=", this.getAgainId(), t.literal(true))
|
||||
));
|
||||
body.push(t.continueStatement(this.getFunctionId()));
|
||||
|
||||
return body;
|
||||
|
||||
@ -4,7 +4,10 @@
|
||||
var _this = this,
|
||||
_arguments = arguments;
|
||||
|
||||
_function: while (true) {
|
||||
var _again = true;
|
||||
|
||||
_function: while (_again) {
|
||||
_again = false;
|
||||
var n = _x;
|
||||
|
||||
if (n <= 0) {
|
||||
@ -14,10 +17,12 @@
|
||||
|
||||
if (Math.random() > 0.5) {
|
||||
_arguments = [_x = n - 1];
|
||||
_again = true;
|
||||
continue _function;
|
||||
} else {
|
||||
_arguments = [_x = n - 1];
|
||||
_again = true;
|
||||
continue _function;
|
||||
}return;
|
||||
}
|
||||
}
|
||||
})(1000000) === "foo";
|
||||
|
||||
@ -1,10 +1,14 @@
|
||||
"use strict";
|
||||
|
||||
function f() {
|
||||
_function: while (true) {
|
||||
var _again = true;
|
||||
|
||||
_function: while (_again) {
|
||||
_again = false;
|
||||
|
||||
if (true) {} else {
|
||||
_again = true;
|
||||
continue _function;
|
||||
}
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
@ -3,7 +3,10 @@
|
||||
(function f(_x) {
|
||||
var _left;
|
||||
|
||||
_function: while (true) {
|
||||
var _again = true;
|
||||
|
||||
_function: while (_again) {
|
||||
_again = false;
|
||||
var n = _x;
|
||||
if (n <= 0) {
|
||||
return "foo";
|
||||
@ -19,7 +22,8 @@
|
||||
}
|
||||
|
||||
_x = n - 1;
|
||||
_again = true;
|
||||
continue _function;
|
||||
}return;
|
||||
}
|
||||
}
|
||||
})(1000000, true) === "foo";
|
||||
})(1000000, true) === "foo";
|
||||
@ -2,16 +2,19 @@
|
||||
|
||||
function fact(_x2) {
|
||||
var _arguments = arguments;
|
||||
var _again = true;
|
||||
|
||||
_function: while (true) {
|
||||
_function: while (_again) {
|
||||
_again = false;
|
||||
var n = _x2;
|
||||
acc = undefined;
|
||||
var acc = _arguments[1] === undefined ? 1 : _arguments[1];
|
||||
if (n > 1) {
|
||||
_arguments = [_x2 = n - 1, acc * n];
|
||||
_again = true;
|
||||
continue _function;
|
||||
} else {
|
||||
return acc;
|
||||
}return;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -2,10 +2,12 @@
|
||||
|
||||
(function f(_x2) {
|
||||
var _arguments = arguments;
|
||||
var _again = true;
|
||||
|
||||
_function: while (true) {
|
||||
_function: while (_again) {
|
||||
var g = function g() {};
|
||||
|
||||
_again = false;
|
||||
var n = _x2;
|
||||
m = local1 = local2 = local3 = undefined;
|
||||
var m = _arguments[1] === undefined ? getDefaultValue() : _arguments[1];
|
||||
@ -21,7 +23,7 @@
|
||||
// `g` should be function here on each pass
|
||||
g = 123;
|
||||
_arguments = [_x2 = n - 1];
|
||||
_again = true;
|
||||
continue _function;
|
||||
return;
|
||||
}
|
||||
})(1000000, true) === "foo";
|
||||
})(1000000, true) === "foo";
|
||||
@ -11,7 +11,10 @@
|
||||
})(1000000) === "foo";
|
||||
|
||||
(function f(_x) {
|
||||
_function: while (true) {
|
||||
var _again = true;
|
||||
|
||||
_function: while (_again) {
|
||||
_again = false;
|
||||
var n = _x;
|
||||
|
||||
if (n <= 0) {
|
||||
@ -22,9 +25,9 @@
|
||||
throw new Error();
|
||||
} catch (e) {
|
||||
_x = n - 1;
|
||||
_again = true;
|
||||
continue _function;
|
||||
}
|
||||
return;
|
||||
}
|
||||
})(1000000) === "foo";
|
||||
|
||||
@ -41,7 +44,10 @@
|
||||
})(1000000) === "foo";
|
||||
|
||||
(function f(_x) {
|
||||
_function: while (true) {
|
||||
var _again = true;
|
||||
|
||||
_function: while (_again) {
|
||||
_again = false;
|
||||
var n = _x;
|
||||
|
||||
if (n <= 0) {
|
||||
@ -50,8 +56,8 @@
|
||||
|
||||
try {} finally {
|
||||
_x = n - 1;
|
||||
_again = true;
|
||||
continue _function;
|
||||
}
|
||||
return;
|
||||
}
|
||||
})(1000000) === "foo";
|
||||
})(1000000) === "foo";
|
||||
Loading…
x
Reference in New Issue
Block a user