From 255c81972792aac594749cd8807c9db0dc4e9350 Mon Sep 17 00:00:00 2001 From: Sebastian McKenzie Date: Sun, 31 May 2015 15:40:41 +0100 Subject: [PATCH] optimise ES6 tail call transformer to only try TOC on functions that include a call to themselves --- .../transformers/es6/tail-call.js | 27 +++++++++++++++---- 1 file changed, 22 insertions(+), 5 deletions(-) diff --git a/src/babel/transformation/transformers/es6/tail-call.js b/src/babel/transformation/transformers/es6/tail-call.js index 78eb809380..cbe6ff95c2 100644 --- a/src/babel/transformation/transformers/es6/tail-call.js +++ b/src/babel/transformation/transformers/es6/tail-call.js @@ -9,18 +9,35 @@ export var metadata = { group: "builtin-trailing" }; -export function Func/*tion*/(node, parent, scope, file) { - if (node.generator || node.async) return; - var tailCall = new TailCallTransformer(this, scope, file); - tailCall.run(); +export function CallExpression(node) { + var callee = this.get("callee"); + if (!callee.isIdentifier()) return; + + var binding = this.scope.getBinding(callee.node.name); + if (!binding) return; + + if (!binding.path.isFunction()) return; + if (binding.identifier !== binding.path.node.id) return; + + binding.path.setData("shouldTryTCO", true); } +export var Func/*tion*/ = { + exit(node, parent, scope, file) { + if (node.generator || node.async) return; + if (!this.getData("shouldTryTCO")) return; + + var tailCall = new TailCallTransformer(this, scope, file); + tailCall.run(); + } +}; + function returnBlock(expr) { return t.blockStatement([t.returnStatement(expr)]); } var visitor = { - enter(node, parent) { + BlockStatement(node, parent) { if (t.isTryStatement(parent)) { if (node === parent.block) { this.skip();