Skip to content

Commit 2e56592

Browse files
committed
Add TCO for ArrowFunctionExpressions
1 parent 816eca7 commit 2e56592

File tree

1 file changed

+18
-26
lines changed

1 file changed

+18
-26
lines changed

src/BabelPlugin.js

Lines changed: 18 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -124,10 +124,11 @@ function Plugin(babel) {
124124
);
125125
}
126126
// Instruction Token: Yield with argument
127-
function hzYieldArg(argExp) {
127+
function hzYieldArg(argExp, delegate) {
128128
const callExp = hzYield();
129129
callExp.callee.property.name = "yieldValue";
130130
callExp.arguments[0].properties[0].value = argExp;
131+
callExp.arguments[1] = delegate;
131132
return callExp;
132133
}
133134
// Instruction Token: Spawn without arguments
@@ -286,6 +287,9 @@ function Plugin(babel) {
286287
},
287288
// Detours an ArrowFunctionExpression
288289
"ArrowFunctionExpression": {
290+
enter: function (path) {
291+
if (path.node.body.type !== "BlockStatement") markTailCall(path.node.body);
292+
},
289293
exit: function (path) {
290294
path.replaceWith(hzArrowCoroutine(path.node));
291295
path.node.arguments[0].generator = true;
@@ -411,7 +415,8 @@ function Plugin(babel) {
411415
// Check for TCO validity if the call is within a TryStatement
412416
if (tryStack.length > 0) {
413417
const tryData = tryStack[tryStack.length - 1];
414-
if (path.getFunctionParent().node === tryData.functionParent) {
418+
const parentNode = path.getFunctionParent().node;
419+
if (parentNode === tryData.functionParent) {
415420
if (
416421
tryData.blockType === "finalizer"
417422
|| tryData.blockType === "catch"
@@ -436,29 +441,16 @@ function Plugin(babel) {
436441
// Transforms a ReturnStatement into an Instruction Token
437442
exit: function (path) {
438443
if (path.getFunctionParent().node.generator) {
439-
if (path.node.argument === null) {
440-
path.node.argument = hzReturnArg(t.ObjectExpression([
441-
t.ObjectProperty(
442-
t.identifier("value"),
443-
t.identifier("undefined")
444-
),
445-
t.ObjectProperty(
446-
t.identifier("done"),
447-
t.BooleanLiteral(true)
448-
)
449-
]));
450-
} else {
451-
path.node.argument = hzReturnArg(t.ObjectExpression([
452-
t.ObjectProperty(
453-
t.identifier("value"),
454-
path.node.argument.arguments[0]
455-
),
456-
t.ObjectProperty(
457-
t.identifier("done"),
458-
t.BooleanLiteral(true)
459-
)
460-
]));
461-
}
444+
path.node.argument = hzReturnArg(t.ObjectExpression([
445+
t.ObjectProperty(
446+
t.identifier("value"),
447+
path.node.argument === null ? t.identifier("undefined") : path.node.argument
448+
),
449+
t.ObjectProperty(
450+
t.identifier("done"),
451+
t.BooleanLiteral(true)
452+
)
453+
]));
462454
} else {
463455
if (path.node.argument === null) path.node.argument = hzReturn();
464456
else path.node.argument = hzReturnArg(path.node.argument);
@@ -510,7 +502,7 @@ function Plugin(babel) {
510502
// Transforms a YieldExpression into an Instruction Token
511503
exit: function (path) {
512504
if (path.node.argument === null) path.node.argument = hzYield();
513-
else path.node.argument = hzYieldArg(path.node.argument);
505+
else path.node.argument = hzYieldArg(path.node.argument, path.node.delegate);
514506
}
515507
}
516508
};

0 commit comments

Comments
 (0)