<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN"
"http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head><meta http-equiv="content-type" content="text/html; charset=utf-8" />
<title>[186822] branches/jsc-tailcall/Source/JavaScriptCore</title>
</head>
<body>

<style type="text/css"><!--
#msg dl.meta { border: 1px #006 solid; background: #369; padding: 6px; color: #fff; }
#msg dl.meta dt { float: left; width: 6em; font-weight: bold; }
#msg dt:after { content:':';}
#msg dl, #msg dt, #msg ul, #msg li, #header, #footer, #logmsg { font-family: verdana,arial,helvetica,sans-serif; font-size: 10pt;  }
#msg dl a { font-weight: bold}
#msg dl a:link    { color:#fc3; }
#msg dl a:active  { color:#ff0; }
#msg dl a:visited { color:#cc6; }
h3 { font-family: verdana,arial,helvetica,sans-serif; font-size: 10pt; font-weight: bold; }
#msg pre { overflow: auto; background: #ffc; border: 1px #fa0 solid; padding: 6px; }
#logmsg { background: #ffc; border: 1px #fa0 solid; padding: 1em 1em 0 1em; }
#logmsg p, #logmsg pre, #logmsg blockquote { margin: 0 0 1em 0; }
#logmsg p, #logmsg li, #logmsg dt, #logmsg dd { line-height: 14pt; }
#logmsg h1, #logmsg h2, #logmsg h3, #logmsg h4, #logmsg h5, #logmsg h6 { margin: .5em 0; }
#logmsg h1:first-child, #logmsg h2:first-child, #logmsg h3:first-child, #logmsg h4:first-child, #logmsg h5:first-child, #logmsg h6:first-child { margin-top: 0; }
#logmsg ul, #logmsg ol { padding: 0; list-style-position: inside; margin: 0 0 0 1em; }
#logmsg ul { text-indent: -1em; padding-left: 1em; }#logmsg ol { text-indent: -1.5em; padding-left: 1.5em; }
#logmsg > ul, #logmsg > ol { margin: 0 0 1em 0; }
#logmsg pre { background: #eee; padding: 1em; }
#logmsg blockquote { border: 1px solid #fa0; border-left-width: 10px; padding: 1em 1em 0 1em; background: white;}
#logmsg dl { margin: 0; }
#logmsg dt { font-weight: bold; }
#logmsg dd { margin: 0; padding: 0 0 0.5em 0; }
#logmsg dd:before { content:'\00bb';}
#logmsg table { border-spacing: 0px; border-collapse: collapse; border-top: 4px solid #fa0; border-bottom: 1px solid #fa0; background: #fff; }
#logmsg table th { text-align: left; font-weight: normal; padding: 0.2em 0.5em; border-top: 1px dotted #fa0; }
#logmsg table td { text-align: right; border-top: 1px dotted #fa0; padding: 0.2em 0.5em; }
#logmsg table thead th { text-align: center; border-bottom: 1px solid #fa0; }
#logmsg table th.Corner { text-align: left; }
#logmsg hr { border: none 0; border-top: 2px dashed #fa0; height: 1px; }
#header, #footer { color: #fff; background: #636; border: 1px #300 solid; padding: 6px; }
#patch { width: 100%; }
#patch h4 {font-family: verdana,arial,helvetica,sans-serif;font-size:10pt;padding:8px;background:#369;color:#fff;margin:0;}
#patch .propset h4, #patch .binary h4 {margin:0;}
#patch pre {padding:0;line-height:1.2em;margin:0;}
#patch .diff {width:100%;background:#eee;padding: 0 0 10px 0;overflow:auto;}
#patch .propset .diff, #patch .binary .diff  {padding:10px 0;}
#patch span {display:block;padding:0 10px;}
#patch .modfile, #patch .addfile, #patch .delfile, #patch .propset, #patch .binary, #patch .copfile {border:1px solid #ccc;margin:10px 0;}
#patch ins {background:#dfd;text-decoration:none;display:block;padding:0 10px;}
#patch del {background:#fdd;text-decoration:none;display:block;padding:0 10px;}
#patch .lines, .info {color:#888;background:#fff;}
--></style>
<div id="msg">
<dl class="meta">
<dt>Revision</dt> <dd><a href="http://trac.webkit.org/projects/webkit/changeset/186822">186822</a></dd>
<dt>Author</dt> <dd>basile_clement@apple.com</dd>
<dt>Date</dt> <dd>2015-07-14 15:33:32 -0700 (Tue, 14 Jul 2015)</dd>
</dl>

<h3>Log Message</h3>
<pre>[ES6] Recognize calls in tail position
https://bugs.webkit.org/show_bug.cgi?id=146481

Reviewed by Saam Barati.

This patch adds the capability for the bytecode generator to recognize
and dispatch tail calls, as per ES6 spec:
http://www.ecma-international.org/ecma-262/6.0/#sec-isintailposition

This does not change the generated bytecode, but merely provides the
hook for generating tail calls in subsequent patches toward
https://bugs.webkit.org/show_bug.cgi?id=146477

* bytecompiler/BytecodeGenerator.cpp:
(JSC::BytecodeGenerator::emitTailCall):
(JSC::BytecodeGenerator::emitTailCallVarargs):
* bytecompiler/BytecodeGenerator.h:
(JSC::BytecodeGenerator::emitNode):
* bytecompiler/NodesCodegen.cpp:
(JSC::ConstantNode::emitBytecode):
(JSC::NumberNode::emitBytecode):
(JSC::RegExpNode::emitBytecode):
(JSC::ThisNode::emitBytecode):
(JSC::SuperNode::emitBytecode):
(JSC::ResolveNode::emitBytecode):
(JSC::TemplateStringNode::emitBytecode):
(JSC::TemplateLiteralNode::emitBytecode):
(JSC::TaggedTemplateNode::emitBytecode):
(JSC::ArrayNode::emitBytecode):
(JSC::ObjectLiteralNode::emitBytecode):
(JSC::PropertyListNode::emitBytecode):
(JSC::BracketAccessorNode::emitBytecode):
(JSC::DotAccessorNode::emitBytecode):
(JSC::ArgumentListNode::emitBytecode):
(JSC::NewExprNode::emitBytecode):
(JSC::EvalFunctionCallNode::emitBytecode):
(JSC::FunctionCallValueNode::emitBytecode):
(JSC::FunctionCallResolveNode::emitBytecode):
(JSC::BytecodeIntrinsicNode::emitBytecode):
(JSC::FunctionCallBracketNode::emitBytecode):
(JSC::FunctionCallDotNode::emitBytecode):
(JSC::CallFunctionCallDotNode::emitBytecode):
(JSC::ApplyFunctionCallDotNode::emitBytecode):
(JSC::PostfixNode::emitBytecode):
(JSC::DeleteResolveNode::emitBytecode):
(JSC::DeleteBracketNode::emitBytecode):
(JSC::DeleteDotNode::emitBytecode):
(JSC::DeleteValueNode::emitBytecode):
(JSC::VoidNode::emitBytecode):
(JSC::TypeOfResolveNode::emitBytecode):
(JSC::TypeOfValueNode::emitBytecode):
(JSC::PrefixNode::emitBytecode):
(JSC::UnaryOpNode::emitBytecode):
(JSC::BitwiseNotNode::emitBytecode):
(JSC::BinaryOpNode::emitBytecode):
(JSC::EqualNode::emitBytecode):
(JSC::StrictEqualNode::emitBytecode):
(JSC::ThrowableBinaryOpNode::emitBytecode):
(JSC::InstanceOfNode::emitBytecode):
(JSC::LogicalOpNode::emitBytecode):
(JSC::ConditionalNode::emitBytecode):
(JSC::ReadModifyResolveNode::emitBytecode):
(JSC::AssignResolveNode::emitBytecode):
(JSC::AssignDotNode::emitBytecode):
(JSC::ReadModifyDotNode::emitBytecode):
(JSC::AssignErrorNode::emitBytecode):
(JSC::AssignBracketNode::emitBytecode):
(JSC::ReadModifyBracketNode::emitBytecode):
(JSC::CommaNode::emitBytecode):
(JSC::ConstDeclNode::emitBytecode):
(JSC::ConstStatementNode::emitBytecode):
(JSC::SourceElements::emitBytecode):
(JSC::BlockNode::emitBytecode):
(JSC::EmptyStatementNode::emitBytecode):
(JSC::DebuggerStatementNode::emitBytecode):
(JSC::ExprStatementNode::emitBytecode):
(JSC::VarStatementNode::emitBytecode):
(JSC::EmptyVarExpression::emitBytecode):
(JSC::IfElseNode::emitBytecode):
(JSC::DoWhileNode::emitBytecode):
(JSC::WhileNode::emitBytecode):
(JSC::ForNode::emitBytecode):
(JSC::ForInNode::emitBytecode):
(JSC::ForOfNode::emitBytecode):
(JSC::ContinueNode::emitBytecode):
(JSC::BreakNode::emitBytecode):
(JSC::ReturnNode::emitBytecode):
(JSC::WithNode::emitBytecode):
(JSC::CaseClauseNode::emitBytecode):
(JSC::CaseBlockNode::emitBytecodeForBlock):
(JSC::SwitchNode::emitBytecode):
(JSC::LabelNode::emitBytecode):
(JSC::ThrowNode::emitBytecode):
(JSC::TryNode::emitBytecode):
(JSC::ScopeNode::emitStatementsBytecode):
(JSC::ProgramNode::emitBytecode):
(JSC::EvalNode::emitBytecode):
(JSC::FunctionBodyNode::emitBytecode):
(JSC::FunctionNode::emitBytecode):
(JSC::FuncDeclNode::emitBytecode):
(JSC::FuncExprNode::emitBytecode):
(JSC::ClassDeclNode::emitBytecode):
(JSC::ClassExprNode::emitBytecode):
(JSC::DestructuringAssignmentNode::emitBytecode):
(JSC::SpreadExpressionNode::emitBytecode):
* parser/Nodes.h:</pre>

<h3>Modified Paths</h3>
<ul>
<li><a href="#branchesjsctailcallSourceJavaScriptCoreChangeLog">branches/jsc-tailcall/Source/JavaScriptCore/ChangeLog</a></li>
<li><a href="#branchesjsctailcallSourceJavaScriptCorebytecompilerBytecodeGeneratorcpp">branches/jsc-tailcall/Source/JavaScriptCore/bytecompiler/BytecodeGenerator.cpp</a></li>
<li><a href="#branchesjsctailcallSourceJavaScriptCorebytecompilerBytecodeGeneratorh">branches/jsc-tailcall/Source/JavaScriptCore/bytecompiler/BytecodeGenerator.h</a></li>
<li><a href="#branchesjsctailcallSourceJavaScriptCorebytecompilerNodesCodegencpp">branches/jsc-tailcall/Source/JavaScriptCore/bytecompiler/NodesCodegen.cpp</a></li>
<li><a href="#branchesjsctailcallSourceJavaScriptCoreparserNodesh">branches/jsc-tailcall/Source/JavaScriptCore/parser/Nodes.h</a></li>
</ul>

</div>
<div id="patch">
<h3>Diff</h3>
<a id="branchesjsctailcallSourceJavaScriptCoreChangeLog"></a>
<div class="modfile"><h4>Modified: branches/jsc-tailcall/Source/JavaScriptCore/ChangeLog (186821 => 186822)</h4>
<pre class="diff"><span>
<span class="info">--- branches/jsc-tailcall/Source/JavaScriptCore/ChangeLog        2015-07-14 22:24:54 UTC (rev 186821)
+++ branches/jsc-tailcall/Source/JavaScriptCore/ChangeLog        2015-07-14 22:33:32 UTC (rev 186822)
</span><span class="lines">@@ -1,3 +1,112 @@
</span><ins>+2015-07-14  Basile Clement  &lt;basile_clement@apple.com&gt;
+
+        [ES6] Recognize calls in tail position
+        https://bugs.webkit.org/show_bug.cgi?id=146481
+
+        Reviewed by Saam Barati.
+
+        This patch adds the capability for the bytecode generator to recognize
+        and dispatch tail calls, as per ES6 spec:
+        http://www.ecma-international.org/ecma-262/6.0/#sec-isintailposition
+
+        This does not change the generated bytecode, but merely provides the
+        hook for generating tail calls in subsequent patches toward
+        https://bugs.webkit.org/show_bug.cgi?id=146477
+
+        * bytecompiler/BytecodeGenerator.cpp:
+        (JSC::BytecodeGenerator::emitTailCall):
+        (JSC::BytecodeGenerator::emitTailCallVarargs):
+        * bytecompiler/BytecodeGenerator.h:
+        (JSC::BytecodeGenerator::emitNode):
+        * bytecompiler/NodesCodegen.cpp:
+        (JSC::ConstantNode::emitBytecode):
+        (JSC::NumberNode::emitBytecode):
+        (JSC::RegExpNode::emitBytecode):
+        (JSC::ThisNode::emitBytecode):
+        (JSC::SuperNode::emitBytecode):
+        (JSC::ResolveNode::emitBytecode):
+        (JSC::TemplateStringNode::emitBytecode):
+        (JSC::TemplateLiteralNode::emitBytecode):
+        (JSC::TaggedTemplateNode::emitBytecode):
+        (JSC::ArrayNode::emitBytecode):
+        (JSC::ObjectLiteralNode::emitBytecode):
+        (JSC::PropertyListNode::emitBytecode):
+        (JSC::BracketAccessorNode::emitBytecode):
+        (JSC::DotAccessorNode::emitBytecode):
+        (JSC::ArgumentListNode::emitBytecode):
+        (JSC::NewExprNode::emitBytecode):
+        (JSC::EvalFunctionCallNode::emitBytecode):
+        (JSC::FunctionCallValueNode::emitBytecode):
+        (JSC::FunctionCallResolveNode::emitBytecode):
+        (JSC::BytecodeIntrinsicNode::emitBytecode):
+        (JSC::FunctionCallBracketNode::emitBytecode):
+        (JSC::FunctionCallDotNode::emitBytecode):
+        (JSC::CallFunctionCallDotNode::emitBytecode):
+        (JSC::ApplyFunctionCallDotNode::emitBytecode):
+        (JSC::PostfixNode::emitBytecode):
+        (JSC::DeleteResolveNode::emitBytecode):
+        (JSC::DeleteBracketNode::emitBytecode):
+        (JSC::DeleteDotNode::emitBytecode):
+        (JSC::DeleteValueNode::emitBytecode):
+        (JSC::VoidNode::emitBytecode):
+        (JSC::TypeOfResolveNode::emitBytecode):
+        (JSC::TypeOfValueNode::emitBytecode):
+        (JSC::PrefixNode::emitBytecode):
+        (JSC::UnaryOpNode::emitBytecode):
+        (JSC::BitwiseNotNode::emitBytecode):
+        (JSC::BinaryOpNode::emitBytecode):
+        (JSC::EqualNode::emitBytecode):
+        (JSC::StrictEqualNode::emitBytecode):
+        (JSC::ThrowableBinaryOpNode::emitBytecode):
+        (JSC::InstanceOfNode::emitBytecode):
+        (JSC::LogicalOpNode::emitBytecode):
+        (JSC::ConditionalNode::emitBytecode):
+        (JSC::ReadModifyResolveNode::emitBytecode):
+        (JSC::AssignResolveNode::emitBytecode):
+        (JSC::AssignDotNode::emitBytecode):
+        (JSC::ReadModifyDotNode::emitBytecode):
+        (JSC::AssignErrorNode::emitBytecode):
+        (JSC::AssignBracketNode::emitBytecode):
+        (JSC::ReadModifyBracketNode::emitBytecode):
+        (JSC::CommaNode::emitBytecode):
+        (JSC::ConstDeclNode::emitBytecode):
+        (JSC::ConstStatementNode::emitBytecode):
+        (JSC::SourceElements::emitBytecode):
+        (JSC::BlockNode::emitBytecode):
+        (JSC::EmptyStatementNode::emitBytecode):
+        (JSC::DebuggerStatementNode::emitBytecode):
+        (JSC::ExprStatementNode::emitBytecode):
+        (JSC::VarStatementNode::emitBytecode):
+        (JSC::EmptyVarExpression::emitBytecode):
+        (JSC::IfElseNode::emitBytecode):
+        (JSC::DoWhileNode::emitBytecode):
+        (JSC::WhileNode::emitBytecode):
+        (JSC::ForNode::emitBytecode):
+        (JSC::ForInNode::emitBytecode):
+        (JSC::ForOfNode::emitBytecode):
+        (JSC::ContinueNode::emitBytecode):
+        (JSC::BreakNode::emitBytecode):
+        (JSC::ReturnNode::emitBytecode):
+        (JSC::WithNode::emitBytecode):
+        (JSC::CaseClauseNode::emitBytecode):
+        (JSC::CaseBlockNode::emitBytecodeForBlock):
+        (JSC::SwitchNode::emitBytecode):
+        (JSC::LabelNode::emitBytecode):
+        (JSC::ThrowNode::emitBytecode):
+        (JSC::TryNode::emitBytecode):
+        (JSC::ScopeNode::emitStatementsBytecode):
+        (JSC::ProgramNode::emitBytecode):
+        (JSC::EvalNode::emitBytecode):
+        (JSC::FunctionBodyNode::emitBytecode):
+        (JSC::FunctionNode::emitBytecode):
+        (JSC::FuncDeclNode::emitBytecode):
+        (JSC::FuncExprNode::emitBytecode):
+        (JSC::ClassDeclNode::emitBytecode):
+        (JSC::ClassExprNode::emitBytecode):
+        (JSC::DestructuringAssignmentNode::emitBytecode):
+        (JSC::SpreadExpressionNode::emitBytecode):
+        * parser/Nodes.h:
+
</ins><span class="cx"> 2015-07-13  Basile Clement  &lt;basile_clement@apple.com&gt;
</span><span class="cx"> 
</span><span class="cx">         jsc-tailcall: Get rid of the arity fixup return thunk
</span></span></pre></div>
<a id="branchesjsctailcallSourceJavaScriptCorebytecompilerBytecodeGeneratorcpp"></a>
<div class="modfile"><h4>Modified: branches/jsc-tailcall/Source/JavaScriptCore/bytecompiler/BytecodeGenerator.cpp (186821 => 186822)</h4>
<pre class="diff"><span>
<span class="info">--- branches/jsc-tailcall/Source/JavaScriptCore/bytecompiler/BytecodeGenerator.cpp        2015-07-14 22:24:54 UTC (rev 186821)
+++ branches/jsc-tailcall/Source/JavaScriptCore/bytecompiler/BytecodeGenerator.cpp        2015-07-14 22:33:32 UTC (rev 186822)
</span><span class="lines">@@ -1836,6 +1836,13 @@
</span><span class="cx">     return emitCall(op_call, dst, func, expectedFunction, callArguments, divot, divotStart, divotEnd);
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+RegisterID* BytecodeGenerator::emitTailCall(RegisterID* dst, RegisterID* func, ExpectedFunction expectedFunction, CallArguments&amp; callArguments, const JSTextPosition&amp; divot, const JSTextPosition&amp; divotStart, const JSTextPosition&amp; divotEnd)
+{
+    // FIXME: We should be emitting a new op_tail_call here
+    // https://bugs.webkit.org/show_bug.cgi?id=146484
+    return emitCall(op_call, dst, func, expectedFunction, callArguments, divot, divotStart, divotEnd);
+}
+
</ins><span class="cx"> RegisterID* BytecodeGenerator::emitCallEval(RegisterID* dst, RegisterID* func, CallArguments&amp; callArguments, const JSTextPosition&amp; divot, const JSTextPosition&amp; divotStart, const JSTextPosition&amp; divotEnd)
</span><span class="cx"> {
</span><span class="cx">     return emitCall(op_call_eval, dst, func, NoExpectedFunction, callArguments, divot, divotStart, divotEnd);
</span><span class="lines">@@ -1985,6 +1992,13 @@
</span><span class="cx">     return emitCallVarargs(op_call_varargs, dst, func, thisRegister, arguments, firstFreeRegister, firstVarArgOffset, profileHookRegister, divot, divotStart, divotEnd);
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+RegisterID* BytecodeGenerator::emitTailCallVarargs(RegisterID* dst, RegisterID* func, RegisterID* thisRegister, RegisterID* arguments, RegisterID* firstFreeRegister, int32_t firstVarArgOffset, RegisterID* profileHookRegister, const JSTextPosition&amp; divot, const JSTextPosition&amp; divotStart, const JSTextPosition&amp; divotEnd)
+{
+    // FIXME: We should be emitting a new op_tail_call_varargs here
+    // https://bugs.webkit.org/show_bug.cgi?id=146484
+    return emitCallVarargs(op_call_varargs, dst, func, thisRegister, arguments, firstFreeRegister, firstVarArgOffset, profileHookRegister, divot, divotStart, divotEnd);
+}
+
</ins><span class="cx"> RegisterID* BytecodeGenerator::emitConstructVarargs(RegisterID* dst, RegisterID* func, RegisterID* thisRegister, RegisterID* arguments, RegisterID* firstFreeRegister, int32_t firstVarArgOffset, RegisterID* profileHookRegister, const JSTextPosition&amp; divot, const JSTextPosition&amp; divotStart, const JSTextPosition&amp; divotEnd)
</span><span class="cx"> {
</span><span class="cx">     return emitCallVarargs(op_construct_varargs, dst, func, thisRegister, arguments, firstFreeRegister, firstVarArgOffset, profileHookRegister, divot, divotStart, divotEnd);
</span></span></pre></div>
<a id="branchesjsctailcallSourceJavaScriptCorebytecompilerBytecodeGeneratorh"></a>
<div class="modfile"><h4>Modified: branches/jsc-tailcall/Source/JavaScriptCore/bytecompiler/BytecodeGenerator.h (186821 => 186822)</h4>
<pre class="diff"><span>
<span class="info">--- branches/jsc-tailcall/Source/JavaScriptCore/bytecompiler/BytecodeGenerator.h        2015-07-14 22:24:54 UTC (rev 186821)
+++ branches/jsc-tailcall/Source/JavaScriptCore/bytecompiler/BytecodeGenerator.h        2015-07-14 22:33:32 UTC (rev 186822)
</span><span class="lines">@@ -344,7 +344,7 @@
</span><span class="cx">         LabelScopePtr newLabelScope(LabelScope::Type, const Identifier* = 0);
</span><span class="cx">         PassRefPtr&lt;Label&gt; newLabel();
</span><span class="cx"> 
</span><del>-        void emitNode(RegisterID* dst, StatementNode* n)
</del><ins>+        void emitNode(RegisterID* dst, StatementNode* n, TailCallMode tailCallMode = NoTailCalls)
</ins><span class="cx">         {
</span><span class="cx">             // Node::emitCode assumes that dst, if provided, is either a local or a referenced temporary.
</span><span class="cx">             ASSERT(!dst || dst == ignoredResult() || !dst-&gt;isTemporary() || dst-&gt;refCount());
</span><span class="lines">@@ -352,7 +352,7 @@
</span><span class="cx">                 emitThrowExpressionTooDeepException();
</span><span class="cx">                 return;
</span><span class="cx">             }
</span><del>-            n-&gt;emitBytecode(*this, dst);
</del><ins>+            n-&gt;emitBytecode(*this, dst, tailCallMode);
</ins><span class="cx">         }
</span><span class="cx"> 
</span><span class="cx">         void emitNode(StatementNode* n)
</span><span class="lines">@@ -360,13 +360,13 @@
</span><span class="cx">             emitNode(0, n);
</span><span class="cx">         }
</span><span class="cx"> 
</span><del>-        RegisterID* emitNode(RegisterID* dst, ExpressionNode* n)
</del><ins>+        RegisterID* emitNode(RegisterID* dst, ExpressionNode* n, TailCallMode tailCallMode = NoTailCalls)
</ins><span class="cx">         {
</span><span class="cx">             // Node::emitCode assumes that dst, if provided, is either a local or a referenced temporary.
</span><span class="cx">             ASSERT(!dst || dst == ignoredResult() || !dst-&gt;isTemporary() || dst-&gt;refCount());
</span><span class="cx">             if (!m_vm-&gt;isSafeToRecurse())
</span><span class="cx">                 return emitThrowExpressionTooDeepException();
</span><del>-            return n-&gt;emitBytecode(*this, dst);
</del><ins>+            return n-&gt;emitBytecode(*this, dst, tailCallMode);
</ins><span class="cx">         }
</span><span class="cx"> 
</span><span class="cx">         RegisterID* emitNode(ExpressionNode* n)
</span><span class="lines">@@ -492,8 +492,10 @@
</span><span class="cx">         
</span><span class="cx">         ExpectedFunction expectedFunctionForIdentifier(const Identifier&amp;);
</span><span class="cx">         RegisterID* emitCall(RegisterID* dst, RegisterID* func, ExpectedFunction, CallArguments&amp;, const JSTextPosition&amp; divot, const JSTextPosition&amp; divotStart, const JSTextPosition&amp; divotEnd);
</span><ins>+        RegisterID* emitTailCall(RegisterID* dst, RegisterID* func, ExpectedFunction, CallArguments&amp;, const JSTextPosition&amp; divot, const JSTextPosition&amp; divotStart, const JSTextPosition&amp; divotEnd);
</ins><span class="cx">         RegisterID* emitCallEval(RegisterID* dst, RegisterID* func, CallArguments&amp;, const JSTextPosition&amp; divot, const JSTextPosition&amp; divotStart, const JSTextPosition&amp; divotEnd);
</span><span class="cx">         RegisterID* emitCallVarargs(RegisterID* dst, RegisterID* func, RegisterID* thisRegister, RegisterID* arguments, RegisterID* firstFreeRegister, int32_t firstVarArgOffset, RegisterID* profileHookRegister, const JSTextPosition&amp; divot, const JSTextPosition&amp; divotStart, const JSTextPosition&amp; divotEnd);
</span><ins>+        RegisterID* emitTailCallVarargs(RegisterID* dst, RegisterID* func, RegisterID* thisRegister, RegisterID* arguments, RegisterID* firstFreeRegister, int32_t firstVarArgOffset, RegisterID* profileHookRegister, const JSTextPosition&amp; divot, const JSTextPosition&amp; divotStart, const JSTextPosition&amp; divotEnd);
</ins><span class="cx"> 
</span><span class="cx">         enum PropertyDescriptorOption {
</span><span class="cx">             PropertyConfigurable = 1,
</span></span></pre></div>
<a id="branchesjsctailcallSourceJavaScriptCorebytecompilerNodesCodegencpp"></a>
<div class="modfile"><h4>Modified: branches/jsc-tailcall/Source/JavaScriptCore/bytecompiler/NodesCodegen.cpp (186821 => 186822)</h4>
<pre class="diff"><span>
<span class="info">--- branches/jsc-tailcall/Source/JavaScriptCore/bytecompiler/NodesCodegen.cpp        2015-07-14 22:24:54 UTC (rev 186821)
+++ branches/jsc-tailcall/Source/JavaScriptCore/bytecompiler/NodesCodegen.cpp        2015-07-14 22:33:32 UTC (rev 186822)
</span><span class="lines">@@ -112,7 +112,7 @@
</span><span class="cx">     // All other cases are unconditional fall-throughs, like &quot;if (true)&quot;.
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-RegisterID* ConstantNode::emitBytecode(BytecodeGenerator&amp; generator, RegisterID* dst)
</del><ins>+RegisterID* ConstantNode::emitBytecode(BytecodeGenerator&amp; generator, RegisterID* dst, TailCallMode)
</ins><span class="cx"> {
</span><span class="cx">     if (dst == generator.ignoredResult())
</span><span class="cx">         return 0;
</span><span class="lines">@@ -126,7 +126,7 @@
</span><span class="cx"> 
</span><span class="cx"> // ------------------------------ NumberNode ----------------------------------
</span><span class="cx"> 
</span><del>-RegisterID* NumberNode::emitBytecode(BytecodeGenerator&amp; generator, RegisterID* dst)
</del><ins>+RegisterID* NumberNode::emitBytecode(BytecodeGenerator&amp; generator, RegisterID* dst, TailCallMode)
</ins><span class="cx"> {
</span><span class="cx">     if (dst == generator.ignoredResult())
</span><span class="cx">         return nullptr;
</span><span class="lines">@@ -135,7 +135,7 @@
</span><span class="cx"> 
</span><span class="cx"> // ------------------------------ RegExpNode -----------------------------------
</span><span class="cx"> 
</span><del>-RegisterID* RegExpNode::emitBytecode(BytecodeGenerator&amp; generator, RegisterID* dst)
</del><ins>+RegisterID* RegExpNode::emitBytecode(BytecodeGenerator&amp; generator, RegisterID* dst, TailCallMode)
</ins><span class="cx"> {
</span><span class="cx">     if (dst == generator.ignoredResult())
</span><span class="cx">         return 0;
</span><span class="lines">@@ -144,7 +144,7 @@
</span><span class="cx"> 
</span><span class="cx"> // ------------------------------ ThisNode -------------------------------------
</span><span class="cx"> 
</span><del>-RegisterID* ThisNode::emitBytecode(BytecodeGenerator&amp; generator, RegisterID* dst)
</del><ins>+RegisterID* ThisNode::emitBytecode(BytecodeGenerator&amp; generator, RegisterID* dst, TailCallMode)
</ins><span class="cx"> {
</span><span class="cx">     if (m_shouldAlwaysEmitTDZCheck || generator.constructorKind() == ConstructorKind::Derived)
</span><span class="cx">         generator.emitTDZCheck(generator.thisRegister());
</span><span class="lines">@@ -163,7 +163,7 @@
</span><span class="cx"> 
</span><span class="cx"> // ------------------------------ SuperNode -------------------------------------
</span><span class="cx"> 
</span><del>-RegisterID* SuperNode::emitBytecode(BytecodeGenerator&amp; generator, RegisterID* dst)
</del><ins>+RegisterID* SuperNode::emitBytecode(BytecodeGenerator&amp; generator, RegisterID* dst, TailCallMode)
</ins><span class="cx"> {
</span><span class="cx">     if (dst == generator.ignoredResult())
</span><span class="cx">         return 0;
</span><span class="lines">@@ -192,7 +192,7 @@
</span><span class="cx">     return generator.variable(m_ident).offset().isStack();
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-RegisterID* ResolveNode::emitBytecode(BytecodeGenerator&amp; generator, RegisterID* dst)
</del><ins>+RegisterID* ResolveNode::emitBytecode(BytecodeGenerator&amp; generator, RegisterID* dst, TailCallMode)
</ins><span class="cx"> {
</span><span class="cx">     Variable var = generator.variable(m_ident);
</span><span class="cx">     if (RegisterID* local = var.local()) {
</span><span class="lines">@@ -220,7 +220,7 @@
</span><span class="cx"> #if ENABLE(ES6_TEMPLATE_LITERAL_SYNTAX)
</span><span class="cx"> // ------------------------------ TemplateStringNode -----------------------------------
</span><span class="cx"> 
</span><del>-RegisterID* TemplateStringNode::emitBytecode(BytecodeGenerator&amp; generator, RegisterID* dst)
</del><ins>+RegisterID* TemplateStringNode::emitBytecode(BytecodeGenerator&amp; generator, RegisterID* dst, TailCallMode)
</ins><span class="cx"> {
</span><span class="cx">     if (dst == generator.ignoredResult())
</span><span class="cx">         return nullptr;
</span><span class="lines">@@ -229,7 +229,7 @@
</span><span class="cx"> 
</span><span class="cx"> // ------------------------------ TemplateLiteralNode -----------------------------------
</span><span class="cx"> 
</span><del>-RegisterID* TemplateLiteralNode::emitBytecode(BytecodeGenerator&amp; generator, RegisterID* dst)
</del><ins>+RegisterID* TemplateLiteralNode::emitBytecode(BytecodeGenerator&amp; generator, RegisterID* dst, TailCallMode)
</ins><span class="cx"> {
</span><span class="cx">     if (!m_templateExpressions) {
</span><span class="cx">         TemplateStringNode* templateString = m_templateStrings-&gt;value();
</span><span class="lines">@@ -265,7 +265,7 @@
</span><span class="cx"> 
</span><span class="cx"> // ------------------------------ TaggedTemplateNode -----------------------------------
</span><span class="cx"> 
</span><del>-RegisterID* TaggedTemplateNode::emitBytecode(BytecodeGenerator&amp; generator, RegisterID* dst)
</del><ins>+RegisterID* TaggedTemplateNode::emitBytecode(BytecodeGenerator&amp; generator, RegisterID* dst, TailCallMode)
</ins><span class="cx"> {
</span><span class="cx">     ExpectedFunction expectedFunction = NoExpectedFunction;
</span><span class="cx">     RefPtr&lt;RegisterID&gt; tag = nullptr;
</span><span class="lines">@@ -327,7 +327,7 @@
</span><span class="cx"> 
</span><span class="cx"> // ------------------------------ ArrayNode ------------------------------------
</span><span class="cx"> 
</span><del>-RegisterID* ArrayNode::emitBytecode(BytecodeGenerator&amp; generator, RegisterID* dst)
</del><ins>+RegisterID* ArrayNode::emitBytecode(BytecodeGenerator&amp; generator, RegisterID* dst, TailCallMode)
</ins><span class="cx"> {
</span><span class="cx">     // FIXME: Should we put all of this code into emitNewArray?
</span><span class="cx"> 
</span><span class="lines">@@ -417,7 +417,7 @@
</span><span class="cx"> 
</span><span class="cx"> // ------------------------------ ObjectLiteralNode ----------------------------
</span><span class="cx"> 
</span><del>-RegisterID* ObjectLiteralNode::emitBytecode(BytecodeGenerator&amp; generator, RegisterID* dst)
</del><ins>+RegisterID* ObjectLiteralNode::emitBytecode(BytecodeGenerator&amp; generator, RegisterID* dst, TailCallMode)
</ins><span class="cx"> {
</span><span class="cx">     if (!m_list) {
</span><span class="cx">         if (dst == generator.ignoredResult())
</span><span class="lines">@@ -436,7 +436,7 @@
</span><span class="cx">     generator.emitPutById(function, generator.propertyNames().homeObjectPrivateName, homeObject);
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-RegisterID* PropertyListNode::emitBytecode(BytecodeGenerator&amp; generator, RegisterID* dst)
</del><ins>+RegisterID* PropertyListNode::emitBytecode(BytecodeGenerator&amp; generator, RegisterID* dst, TailCallMode)
</ins><span class="cx"> {
</span><span class="cx">     // Fast case: this loop just handles regular value properties.
</span><span class="cx">     PropertyListNode* p = this;
</span><span class="lines">@@ -586,7 +586,7 @@
</span><span class="cx"> 
</span><span class="cx"> // ------------------------------ BracketAccessorNode --------------------------------
</span><span class="cx"> 
</span><del>-RegisterID* BracketAccessorNode::emitBytecode(BytecodeGenerator&amp; generator, RegisterID* dst)
</del><ins>+RegisterID* BracketAccessorNode::emitBytecode(BytecodeGenerator&amp; generator, RegisterID* dst, TailCallMode)
</ins><span class="cx"> {
</span><span class="cx">     if (m_base-&gt;isSuperNode()) {
</span><span class="cx">         // FIXME: Should we generate the profiler info?
</span><span class="lines">@@ -620,7 +620,7 @@
</span><span class="cx"> 
</span><span class="cx"> // ------------------------------ DotAccessorNode --------------------------------
</span><span class="cx"> 
</span><del>-RegisterID* DotAccessorNode::emitBytecode(BytecodeGenerator&amp; generator, RegisterID* dst)
</del><ins>+RegisterID* DotAccessorNode::emitBytecode(BytecodeGenerator&amp; generator, RegisterID* dst, TailCallMode)
</ins><span class="cx"> {
</span><span class="cx">     RefPtr&lt;RegisterID&gt; base = m_base-&gt;isSuperNode() ? emitSuperBaseForCallee(generator) : generator.emitNode(m_base);
</span><span class="cx">     generator.emitExpressionInfo(divot(), divotStart(), divotEnd());
</span><span class="lines">@@ -635,7 +635,7 @@
</span><span class="cx"> 
</span><span class="cx"> // ------------------------------ ArgumentListNode -----------------------------
</span><span class="cx"> 
</span><del>-RegisterID* ArgumentListNode::emitBytecode(BytecodeGenerator&amp; generator, RegisterID* dst)
</del><ins>+RegisterID* ArgumentListNode::emitBytecode(BytecodeGenerator&amp; generator, RegisterID* dst, TailCallMode)
</ins><span class="cx"> {
</span><span class="cx">     ASSERT(m_expr);
</span><span class="cx">     return generator.emitNode(dst, m_expr);
</span><span class="lines">@@ -643,7 +643,7 @@
</span><span class="cx"> 
</span><span class="cx"> // ------------------------------ NewExprNode ----------------------------------
</span><span class="cx"> 
</span><del>-RegisterID* NewExprNode::emitBytecode(BytecodeGenerator&amp; generator, RegisterID* dst)
</del><ins>+RegisterID* NewExprNode::emitBytecode(BytecodeGenerator&amp; generator, RegisterID* dst, TailCallMode)
</ins><span class="cx"> {
</span><span class="cx">     ExpectedFunction expectedFunction;
</span><span class="cx">     if (m_expr-&gt;isResolveNode())
</span><span class="lines">@@ -684,7 +684,7 @@
</span><span class="cx"> 
</span><span class="cx"> // ------------------------------ EvalFunctionCallNode ----------------------------------
</span><span class="cx"> 
</span><del>-RegisterID* EvalFunctionCallNode::emitBytecode(BytecodeGenerator&amp; generator, RegisterID* dst)
</del><ins>+RegisterID* EvalFunctionCallNode::emitBytecode(BytecodeGenerator&amp; generator, RegisterID* dst, TailCallMode)
</ins><span class="cx"> {
</span><span class="cx">     Variable var = generator.variable(generator.propertyNames().eval);
</span><span class="cx">     if (RegisterID* local = var.local()) {
</span><span class="lines">@@ -707,7 +707,7 @@
</span><span class="cx"> 
</span><span class="cx"> // ------------------------------ FunctionCallValueNode ----------------------------------
</span><span class="cx"> 
</span><del>-RegisterID* FunctionCallValueNode::emitBytecode(BytecodeGenerator&amp; generator, RegisterID* dst)
</del><ins>+RegisterID* FunctionCallValueNode::emitBytecode(BytecodeGenerator&amp; generator, RegisterID* dst, TailCallMode tailCallMode)
</ins><span class="cx"> {
</span><span class="cx">     RefPtr&lt;RegisterID&gt; func = generator.emitNode(m_expr);
</span><span class="cx">     RefPtr&lt;RegisterID&gt; returnValue = generator.finalDestination(dst, func.get());
</span><span class="lines">@@ -721,7 +721,11 @@
</span><span class="cx">         return ret;
</span><span class="cx">     }
</span><span class="cx">     generator.emitLoad(callArguments.thisRegister(), jsUndefined());
</span><del>-    RegisterID* ret = generator.emitCall(returnValue.get(), func.get(), NoExpectedFunction, callArguments, divot(), divotStart(), divotEnd());
</del><ins>+    RegisterID* ret;
+    if (tailCallMode == CanHaveTailCalls)
+        ret = generator.emitTailCall(returnValue.get(), func.get(), NoExpectedFunction, callArguments, divot(), divotStart(), divotEnd());
+    else
+        ret = generator.emitCall(returnValue.get(), func.get(), NoExpectedFunction, callArguments, divot(), divotStart(), divotEnd());
</ins><span class="cx">     if (generator.vm()-&gt;typeProfiler()) {
</span><span class="cx">         generator.emitProfileType(returnValue.get(), ProfileTypeBytecodeDoesNotHaveGlobalID, nullptr);
</span><span class="cx">         generator.emitTypeProfilerExpressionInfo(divotStart(), divotEnd());
</span><span class="lines">@@ -731,7 +735,7 @@
</span><span class="cx"> 
</span><span class="cx"> // ------------------------------ FunctionCallResolveNode ----------------------------------
</span><span class="cx"> 
</span><del>-RegisterID* FunctionCallResolveNode::emitBytecode(BytecodeGenerator&amp; generator, RegisterID* dst)
</del><ins>+RegisterID* FunctionCallResolveNode::emitBytecode(BytecodeGenerator&amp; generator, RegisterID* dst, TailCallMode tailCallMode)
</ins><span class="cx"> {
</span><span class="cx">     ExpectedFunction expectedFunction = generator.expectedFunctionForIdentifier(m_ident);
</span><span class="cx"> 
</span><span class="lines">@@ -743,7 +747,11 @@
</span><span class="cx">         generator.emitLoad(callArguments.thisRegister(), jsUndefined());
</span><span class="cx">         // This passes NoExpectedFunction because we expect that if the function is in a
</span><span class="cx">         // local variable, then it's not one of our built-in constructors.
</span><del>-        RegisterID* ret = generator.emitCall(returnValue.get(), func.get(), NoExpectedFunction, callArguments, divot(), divotStart(), divotEnd());
</del><ins>+        RegisterID* ret;
+        if (tailCallMode == CanHaveTailCalls)
+            ret = generator.emitTailCall(returnValue.get(), func.get(), NoExpectedFunction, callArguments, divot(), divotStart(), divotEnd());
+        else
+            ret = generator.emitCall(returnValue.get(), func.get(), NoExpectedFunction, callArguments, divot(), divotStart(), divotEnd());
</ins><span class="cx">         if (generator.vm()-&gt;typeProfiler()) {
</span><span class="cx">             generator.emitProfileType(returnValue.get(), ProfileTypeBytecodeDoesNotHaveGlobalID, nullptr);
</span><span class="cx">             generator.emitTypeProfilerExpressionInfo(divotStart(), divotEnd());
</span><span class="lines">@@ -761,7 +769,11 @@
</span><span class="cx">         callArguments.thisRegister(),
</span><span class="cx">         generator.emitResolveScope(callArguments.thisRegister(), var));
</span><span class="cx">     generator.emitGetFromScope(func.get(), callArguments.thisRegister(), var, ThrowIfNotFound);
</span><del>-    RegisterID* ret = generator.emitCall(returnValue.get(), func.get(), expectedFunction, callArguments, divot(), divotStart(), divotEnd());
</del><ins>+    RegisterID* ret;
+    if (tailCallMode == CanHaveTailCalls)
+        ret = generator.emitTailCall(returnValue.get(), func.get(), expectedFunction, callArguments, divot(), divotStart(), divotEnd());
+    else
+        ret = generator.emitCall(returnValue.get(), func.get(), expectedFunction, callArguments, divot(), divotStart(), divotEnd());
</ins><span class="cx">     if (generator.vm()-&gt;typeProfiler()) {
</span><span class="cx">         generator.emitProfileType(returnValue.get(), ProfileTypeBytecodeDoesNotHaveGlobalID, nullptr);
</span><span class="cx">         generator.emitTypeProfilerExpressionInfo(divotStart(), divotEnd());
</span><span class="lines">@@ -771,7 +783,7 @@
</span><span class="cx"> 
</span><span class="cx"> // ------------------------------ BytecodeIntrinsicNode ----------------------------------
</span><span class="cx"> 
</span><del>-RegisterID* BytecodeIntrinsicNode::emitBytecode(BytecodeGenerator&amp; generator, RegisterID* dst)
</del><ins>+RegisterID* BytecodeIntrinsicNode::emitBytecode(BytecodeGenerator&amp; generator, RegisterID* dst, TailCallMode)
</ins><span class="cx"> {
</span><span class="cx">     return (this-&gt;*m_emitter)(generator, dst);
</span><span class="cx"> }
</span><span class="lines">@@ -801,7 +813,7 @@
</span><span class="cx"> 
</span><span class="cx"> // ------------------------------ FunctionCallBracketNode ----------------------------------
</span><span class="cx"> 
</span><del>-RegisterID* FunctionCallBracketNode::emitBytecode(BytecodeGenerator&amp; generator, RegisterID* dst)
</del><ins>+RegisterID* FunctionCallBracketNode::emitBytecode(BytecodeGenerator&amp; generator, RegisterID* dst, TailCallMode tailCallMode)
</ins><span class="cx"> {
</span><span class="cx">     bool baseIsSuper = m_base-&gt;isSuperNode();
</span><span class="cx">     bool subscriptIsString = m_subscript-&gt;isString();
</span><span class="lines">@@ -832,7 +844,11 @@
</span><span class="cx">         generator.emitMove(callArguments.thisRegister(), generator.thisRegister());
</span><span class="cx">     else
</span><span class="cx">         generator.emitMove(callArguments.thisRegister(), base.get());
</span><del>-    RegisterID* ret = generator.emitCall(returnValue.get(), function.get(), NoExpectedFunction, callArguments, divot(), divotStart(), divotEnd());
</del><ins>+    RegisterID* ret;
+    if (tailCallMode == CanHaveTailCalls)
+        ret = generator.emitTailCall(returnValue.get(), function.get(), NoExpectedFunction, callArguments, divot(), divotStart(), divotEnd());
+    else
+        ret = generator.emitCall(returnValue.get(), function.get(), NoExpectedFunction, callArguments, divot(), divotStart(), divotEnd());
</ins><span class="cx">     if (generator.vm()-&gt;typeProfiler()) {
</span><span class="cx">         generator.emitProfileType(returnValue.get(), ProfileTypeBytecodeDoesNotHaveGlobalID, nullptr);
</span><span class="cx">         generator.emitTypeProfilerExpressionInfo(divotStart(), divotEnd());
</span><span class="lines">@@ -842,7 +858,7 @@
</span><span class="cx"> 
</span><span class="cx"> // ------------------------------ FunctionCallDotNode ----------------------------------
</span><span class="cx"> 
</span><del>-RegisterID* FunctionCallDotNode::emitBytecode(BytecodeGenerator&amp; generator, RegisterID* dst)
</del><ins>+RegisterID* FunctionCallDotNode::emitBytecode(BytecodeGenerator&amp; generator, RegisterID* dst, TailCallMode tailCallMode)
</ins><span class="cx"> {
</span><span class="cx">     RefPtr&lt;RegisterID&gt; function = generator.tempDestination(dst);
</span><span class="cx">     RefPtr&lt;RegisterID&gt; returnValue = generator.finalDestination(dst, function.get());
</span><span class="lines">@@ -854,7 +870,11 @@
</span><span class="cx">         generator.emitNode(callArguments.thisRegister(), m_base);
</span><span class="cx">     generator.emitExpressionInfo(subexpressionDivot(), subexpressionStart(), subexpressionEnd());
</span><span class="cx">     generator.emitGetById(function.get(), baseIsSuper ? emitSuperBaseForCallee(generator) : callArguments.thisRegister(), m_ident);
</span><del>-    RegisterID* ret = generator.emitCall(returnValue.get(), function.get(), NoExpectedFunction, callArguments, divot(), divotStart(), divotEnd());
</del><ins>+    RegisterID* ret;
+    if (tailCallMode == CanHaveTailCalls)
+        ret = generator.emitTailCall(returnValue.get(), function.get(), NoExpectedFunction, callArguments, divot(), divotStart(), divotEnd());
+    else
+        ret = generator.emitCall(returnValue.get(), function.get(), NoExpectedFunction, callArguments, divot(), divotStart(), divotEnd());
</ins><span class="cx">     if (generator.vm()-&gt;typeProfiler()) {
</span><span class="cx">         generator.emitProfileType(returnValue.get(), ProfileTypeBytecodeDoesNotHaveGlobalID, nullptr);
</span><span class="cx">         generator.emitTypeProfilerExpressionInfo(divotStart(), divotEnd());
</span><span class="lines">@@ -862,7 +882,7 @@
</span><span class="cx">     return ret;
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-RegisterID* CallFunctionCallDotNode::emitBytecode(BytecodeGenerator&amp; generator, RegisterID* dst)
</del><ins>+RegisterID* CallFunctionCallDotNode::emitBytecode(BytecodeGenerator&amp; generator, RegisterID* dst, TailCallMode tailCallMode)
</ins><span class="cx"> {
</span><span class="cx">     RefPtr&lt;Label&gt; realCall = generator.newLabel();
</span><span class="cx">     RefPtr&lt;Label&gt; end = generator.newLabel();
</span><span class="lines">@@ -886,7 +906,10 @@
</span><span class="cx">             argumentsRegister = generator.emitNode(subject);
</span><span class="cx">             generator.emitExpressionInfo(spread-&gt;divot(), spread-&gt;divotStart(), spread-&gt;divotEnd());
</span><span class="cx">             RefPtr&lt;RegisterID&gt; thisRegister = generator.emitGetByVal(generator.newTemporary(), argumentsRegister.get(), generator.emitLoad(0, jsNumber(0)));
</span><del>-            generator.emitCallVarargs(returnValue.get(), base.get(), thisRegister.get(), argumentsRegister.get(), generator.newTemporary(), 1, profileHookRegister.get(), divot(), divotStart(), divotEnd());
</del><ins>+            if (tailCallMode == CanHaveTailCalls)
+                generator.emitTailCallVarargs(returnValue.get(), base.get(), thisRegister.get(), argumentsRegister.get(), generator.newTemporary(), 1, profileHookRegister.get(), divot(), divotStart(), divotEnd());
+            else
+                generator.emitCallVarargs(returnValue.get(), base.get(), thisRegister.get(), argumentsRegister.get(), generator.newTemporary(), 1, profileHookRegister.get(), divot(), divotStart(), divotEnd());
</ins><span class="cx">         } else if (m_args-&gt;m_listNode &amp;&amp; m_args-&gt;m_listNode-&gt;m_expr) {
</span><span class="cx">             ArgumentListNode* oldList = m_args-&gt;m_listNode;
</span><span class="cx">             m_args-&gt;m_listNode = m_args-&gt;m_listNode-&gt;m_next;
</span><span class="lines">@@ -894,13 +917,19 @@
</span><span class="cx">             RefPtr&lt;RegisterID&gt; realFunction = generator.emitMove(generator.tempDestination(dst), base.get());
</span><span class="cx">             CallArguments callArguments(generator, m_args);
</span><span class="cx">             generator.emitNode(callArguments.thisRegister(), oldList-&gt;m_expr);
</span><del>-            generator.emitCall(returnValue.get(), realFunction.get(), NoExpectedFunction, callArguments, divot(), divotStart(), divotEnd());
</del><ins>+            if (tailCallMode == CanHaveTailCalls)
+                generator.emitTailCall(returnValue.get(), realFunction.get(), NoExpectedFunction, callArguments, divot(), divotStart(), divotEnd());
+            else
+                generator.emitCall(returnValue.get(), realFunction.get(), NoExpectedFunction, callArguments, divot(), divotStart(), divotEnd());
</ins><span class="cx">             m_args-&gt;m_listNode = oldList;
</span><span class="cx">         } else {
</span><span class="cx">             RefPtr&lt;RegisterID&gt; realFunction = generator.emitMove(generator.tempDestination(dst), base.get());
</span><span class="cx">             CallArguments callArguments(generator, m_args);
</span><span class="cx">             generator.emitLoad(callArguments.thisRegister(), jsUndefined());
</span><del>-            generator.emitCall(returnValue.get(), realFunction.get(), NoExpectedFunction, callArguments, divot(), divotStart(), divotEnd());
</del><ins>+            if (tailCallMode == CanHaveTailCalls)
+                generator.emitTailCall(returnValue.get(), realFunction.get(), NoExpectedFunction, callArguments, divot(), divotStart(), divotEnd());
+            else
+                generator.emitCall(returnValue.get(), realFunction.get(), NoExpectedFunction, callArguments, divot(), divotStart(), divotEnd());
</ins><span class="cx">         }
</span><span class="cx">     }
</span><span class="cx">     if (emitCallCheck) {
</span><span class="lines">@@ -909,7 +938,10 @@
</span><span class="cx">         {
</span><span class="cx">             CallArguments callArguments(generator, m_args);
</span><span class="cx">             generator.emitMove(callArguments.thisRegister(), base.get());
</span><del>-            generator.emitCall(returnValue.get(), function.get(), NoExpectedFunction, callArguments, divot(), divotStart(), divotEnd());
</del><ins>+            if (tailCallMode == CanHaveTailCalls)
+                generator.emitTailCall(returnValue.get(), function.get(), NoExpectedFunction, callArguments, divot(), divotStart(), divotEnd());
+            else
+                generator.emitCall(returnValue.get(), function.get(), NoExpectedFunction, callArguments, divot(), divotStart(), divotEnd());
</ins><span class="cx">         }
</span><span class="cx">         generator.emitLabel(end.get());
</span><span class="cx">     }
</span><span class="lines">@@ -926,7 +958,7 @@
</span><span class="cx">         || (!args-&gt;m_listNode-&gt;m_next-&gt;m_next &amp;&amp; args-&gt;m_listNode-&gt;m_next-&gt;m_expr-&gt;isSimpleArray());
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-RegisterID* ApplyFunctionCallDotNode::emitBytecode(BytecodeGenerator&amp; generator, RegisterID* dst)
</del><ins>+RegisterID* ApplyFunctionCallDotNode::emitBytecode(BytecodeGenerator&amp; generator, RegisterID* dst, TailCallMode tailCallMode)
</ins><span class="cx"> {
</span><span class="cx">     // A few simple cases can be trivially handled as ordinary function calls.
</span><span class="cx">     // function.apply(), function.apply(arg) -&gt; identical to function.call
</span><span class="lines">@@ -975,7 +1007,10 @@
</span><span class="cx">                     generator.emitLabel(end.get());
</span><span class="cx">                 };
</span><span class="cx">                 generator.emitEnumeration(this, spread-&gt;expression(), extractor);
</span><del>-                generator.emitCallVarargs(returnValue.get(), realFunction.get(), thisRegister.get(), argumentsRegister.get(), generator.newTemporary(), 0, profileHookRegister.get(), divot(), divotStart(), divotEnd());
</del><ins>+                if (tailCallMode == CanHaveTailCalls)
+                    generator.emitTailCallVarargs(returnValue.get(), realFunction.get(), thisRegister.get(), argumentsRegister.get(), generator.newTemporary(), 0, profileHookRegister.get(), divot(), divotStart(), divotEnd());
+                else
+                    generator.emitCallVarargs(returnValue.get(), realFunction.get(), thisRegister.get(), argumentsRegister.get(), generator.newTemporary(), 0, profileHookRegister.get(), divot(), divotStart(), divotEnd());
</ins><span class="cx">             } else if (m_args-&gt;m_listNode-&gt;m_next) {
</span><span class="cx">                 ASSERT(m_args-&gt;m_listNode-&gt;m_next-&gt;m_expr-&gt;isSimpleArray());
</span><span class="cx">                 ASSERT(!m_args-&gt;m_listNode-&gt;m_next-&gt;m_next);
</span><span class="lines">@@ -983,20 +1018,29 @@
</span><span class="cx">                 RefPtr&lt;RegisterID&gt; realFunction = generator.emitMove(generator.tempDestination(dst), base.get());
</span><span class="cx">                 CallArguments callArguments(generator, m_args);
</span><span class="cx">                 generator.emitNode(callArguments.thisRegister(), oldList-&gt;m_expr);
</span><del>-                generator.emitCall(returnValue.get(), realFunction.get(), NoExpectedFunction, callArguments, divot(), divotStart(), divotEnd());
</del><ins>+                if (tailCallMode == CanHaveTailCalls)
+                    generator.emitTailCall(returnValue.get(), realFunction.get(), NoExpectedFunction, callArguments, divot(), divotStart(), divotEnd());
+                else
+                    generator.emitCall(returnValue.get(), realFunction.get(), NoExpectedFunction, callArguments, divot(), divotStart(), divotEnd());
</ins><span class="cx">             } else {
</span><span class="cx">                 m_args-&gt;m_listNode = m_args-&gt;m_listNode-&gt;m_next;
</span><span class="cx">                 RefPtr&lt;RegisterID&gt; realFunction = generator.emitMove(generator.tempDestination(dst), base.get());
</span><span class="cx">                 CallArguments callArguments(generator, m_args);
</span><span class="cx">                 generator.emitNode(callArguments.thisRegister(), oldList-&gt;m_expr);
</span><del>-                generator.emitCall(returnValue.get(), realFunction.get(), NoExpectedFunction, callArguments, divot(), divotStart(), divotEnd());
</del><ins>+                if (tailCallMode == CanHaveTailCalls)
+                    generator.emitTailCall(returnValue.get(), realFunction.get(), NoExpectedFunction, callArguments, divot(), divotStart(), divotEnd());
+                else
+                    generator.emitCall(returnValue.get(), realFunction.get(), NoExpectedFunction, callArguments, divot(), divotStart(), divotEnd());
</ins><span class="cx">             }
</span><span class="cx">             m_args-&gt;m_listNode = oldList;
</span><span class="cx">         } else {
</span><span class="cx">             RefPtr&lt;RegisterID&gt; realFunction = generator.emitMove(generator.tempDestination(dst), base.get());
</span><span class="cx">             CallArguments callArguments(generator, m_args);
</span><span class="cx">             generator.emitLoad(callArguments.thisRegister(), jsUndefined());
</span><del>-            generator.emitCall(returnValue.get(), realFunction.get(), NoExpectedFunction, callArguments, divot(), divotStart(), divotEnd());
</del><ins>+            if (tailCallMode == CanHaveTailCalls)
+                generator.emitTailCall(returnValue.get(), realFunction.get(), NoExpectedFunction, callArguments, divot(), divotStart(), divotEnd());
+            else
+                generator.emitCall(returnValue.get(), realFunction.get(), NoExpectedFunction, callArguments, divot(), divotStart(), divotEnd());
</ins><span class="cx">         }
</span><span class="cx">     } else {
</span><span class="cx">         ASSERT(m_args-&gt;m_listNode &amp;&amp; m_args-&gt;m_listNode-&gt;m_next);
</span><span class="lines">@@ -1014,14 +1058,20 @@
</span><span class="cx">         while ((args = args-&gt;m_next))
</span><span class="cx">             generator.emitNode(args-&gt;m_expr);
</span><span class="cx"> 
</span><del>-        generator.emitCallVarargs(returnValue.get(), realFunction.get(), thisRegister.get(), argsRegister.get(), generator.newTemporary(), 0, profileHookRegister.get(), divot(), divotStart(), divotEnd());
</del><ins>+        if (tailCallMode == CanHaveTailCalls)
+            generator.emitTailCallVarargs(returnValue.get(), realFunction.get(), thisRegister.get(), argsRegister.get(), generator.newTemporary(), 0, profileHookRegister.get(), divot(), divotStart(), divotEnd());
+        else
+            generator.emitCallVarargs(returnValue.get(), realFunction.get(), thisRegister.get(), argsRegister.get(), generator.newTemporary(), 0, profileHookRegister.get(), divot(), divotStart(), divotEnd());
</ins><span class="cx">     }
</span><span class="cx">     if (emitCallCheck) {
</span><span class="cx">         generator.emitJump(end.get());
</span><span class="cx">         generator.emitLabel(realCall.get());
</span><span class="cx">         CallArguments callArguments(generator, m_args);
</span><span class="cx">         generator.emitMove(callArguments.thisRegister(), base.get());
</span><del>-        generator.emitCall(returnValue.get(), function.get(), NoExpectedFunction, callArguments, divot(), divotStart(), divotEnd());
</del><ins>+        if (tailCallMode == CanHaveTailCalls)
+            generator.emitTailCall(returnValue.get(), function.get(), NoExpectedFunction, callArguments, divot(), divotStart(), divotEnd());
+        else
+            generator.emitCall(returnValue.get(), function.get(), NoExpectedFunction, callArguments, divot(), divotStart(), divotEnd());
</ins><span class="cx">         generator.emitLabel(end.get());
</span><span class="cx">     }
</span><span class="cx">     if (generator.vm()-&gt;typeProfiler()) {
</span><span class="lines">@@ -1139,7 +1189,7 @@
</span><span class="cx">     return generator.moveToDestinationIfNeeded(dst, oldValue);
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-RegisterID* PostfixNode::emitBytecode(BytecodeGenerator&amp; generator, RegisterID* dst)
</del><ins>+RegisterID* PostfixNode::emitBytecode(BytecodeGenerator&amp; generator, RegisterID* dst, TailCallMode)
</ins><span class="cx"> {
</span><span class="cx">     if (m_expr-&gt;isResolveNode())
</span><span class="cx">         return emitResolve(generator, dst);
</span><span class="lines">@@ -1157,7 +1207,7 @@
</span><span class="cx"> 
</span><span class="cx"> // ------------------------------ DeleteResolveNode -----------------------------------
</span><span class="cx"> 
</span><del>-RegisterID* DeleteResolveNode::emitBytecode(BytecodeGenerator&amp; generator, RegisterID* dst)
</del><ins>+RegisterID* DeleteResolveNode::emitBytecode(BytecodeGenerator&amp; generator, RegisterID* dst, TailCallMode)
</ins><span class="cx"> {
</span><span class="cx">     Variable var = generator.variable(m_ident);
</span><span class="cx">     if (var.local())
</span><span class="lines">@@ -1170,7 +1220,7 @@
</span><span class="cx"> 
</span><span class="cx"> // ------------------------------ DeleteBracketNode -----------------------------------
</span><span class="cx"> 
</span><del>-RegisterID* DeleteBracketNode::emitBytecode(BytecodeGenerator&amp; generator, RegisterID* dst)
</del><ins>+RegisterID* DeleteBracketNode::emitBytecode(BytecodeGenerator&amp; generator, RegisterID* dst, TailCallMode)
</ins><span class="cx"> {
</span><span class="cx">     RefPtr&lt;RegisterID&gt; r0 = generator.emitNode(m_base);
</span><span class="cx">     RefPtr&lt;RegisterID&gt; r1 = generator.emitNode(m_subscript);
</span><span class="lines">@@ -1183,7 +1233,7 @@
</span><span class="cx"> 
</span><span class="cx"> // ------------------------------ DeleteDotNode -----------------------------------
</span><span class="cx"> 
</span><del>-RegisterID* DeleteDotNode::emitBytecode(BytecodeGenerator&amp; generator, RegisterID* dst)
</del><ins>+RegisterID* DeleteDotNode::emitBytecode(BytecodeGenerator&amp; generator, RegisterID* dst, TailCallMode)
</ins><span class="cx"> {
</span><span class="cx">     RefPtr&lt;RegisterID&gt; r0 = generator.emitNode(m_base);
</span><span class="cx"> 
</span><span class="lines">@@ -1195,7 +1245,7 @@
</span><span class="cx"> 
</span><span class="cx"> // ------------------------------ DeleteValueNode -----------------------------------
</span><span class="cx"> 
</span><del>-RegisterID* DeleteValueNode::emitBytecode(BytecodeGenerator&amp; generator, RegisterID* dst)
</del><ins>+RegisterID* DeleteValueNode::emitBytecode(BytecodeGenerator&amp; generator, RegisterID* dst, TailCallMode)
</ins><span class="cx"> {
</span><span class="cx">     generator.emitNode(generator.ignoredResult(), m_expr);
</span><span class="cx"> 
</span><span class="lines">@@ -1205,7 +1255,7 @@
</span><span class="cx"> 
</span><span class="cx"> // ------------------------------ VoidNode -------------------------------------
</span><span class="cx"> 
</span><del>-RegisterID* VoidNode::emitBytecode(BytecodeGenerator&amp; generator, RegisterID* dst)
</del><ins>+RegisterID* VoidNode::emitBytecode(BytecodeGenerator&amp; generator, RegisterID* dst, TailCallMode)
</ins><span class="cx"> {
</span><span class="cx">     if (dst == generator.ignoredResult()) {
</span><span class="cx">         generator.emitNode(generator.ignoredResult(), m_expr);
</span><span class="lines">@@ -1217,7 +1267,7 @@
</span><span class="cx"> 
</span><span class="cx"> // ------------------------------ TypeOfResolveNode -----------------------------------
</span><span class="cx"> 
</span><del>-RegisterID* TypeOfResolveNode::emitBytecode(BytecodeGenerator&amp; generator, RegisterID* dst)
</del><ins>+RegisterID* TypeOfResolveNode::emitBytecode(BytecodeGenerator&amp; generator, RegisterID* dst, TailCallMode)
</ins><span class="cx"> {
</span><span class="cx">     Variable var = generator.variable(m_ident);
</span><span class="cx">     if (RegisterID* local = var.local()) {
</span><span class="lines">@@ -1235,7 +1285,7 @@
</span><span class="cx"> 
</span><span class="cx"> // ------------------------------ TypeOfValueNode -----------------------------------
</span><span class="cx"> 
</span><del>-RegisterID* TypeOfValueNode::emitBytecode(BytecodeGenerator&amp; generator, RegisterID* dst)
</del><ins>+RegisterID* TypeOfValueNode::emitBytecode(BytecodeGenerator&amp; generator, RegisterID* dst, TailCallMode)
</ins><span class="cx"> {
</span><span class="cx">     if (dst == generator.ignoredResult()) {
</span><span class="cx">         generator.emitNode(generator.ignoredResult(), m_expr);
</span><span class="lines">@@ -1329,7 +1379,7 @@
</span><span class="cx">     return generator.moveToDestinationIfNeeded(dst, propDst.get());
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-RegisterID* PrefixNode::emitBytecode(BytecodeGenerator&amp; generator, RegisterID* dst)
</del><ins>+RegisterID* PrefixNode::emitBytecode(BytecodeGenerator&amp; generator, RegisterID* dst, TailCallMode)
</ins><span class="cx"> {
</span><span class="cx">     if (m_expr-&gt;isResolveNode())
</span><span class="cx">         return emitResolve(generator, dst);
</span><span class="lines">@@ -1347,7 +1397,7 @@
</span><span class="cx"> 
</span><span class="cx"> // ------------------------------ Unary Operation Nodes -----------------------------------
</span><span class="cx"> 
</span><del>-RegisterID* UnaryOpNode::emitBytecode(BytecodeGenerator&amp; generator, RegisterID* dst)
</del><ins>+RegisterID* UnaryOpNode::emitBytecode(BytecodeGenerator&amp; generator, RegisterID* dst, TailCallMode)
</ins><span class="cx"> {
</span><span class="cx">     RefPtr&lt;RegisterID&gt; src = generator.emitNode(m_expr);
</span><span class="cx">     generator.emitExpressionInfo(position(), position(), position());
</span><span class="lines">@@ -1356,7 +1406,7 @@
</span><span class="cx"> 
</span><span class="cx"> // ------------------------------ BitwiseNotNode -----------------------------------
</span><span class="cx">  
</span><del>-RegisterID* BitwiseNotNode::emitBytecode(BytecodeGenerator&amp; generator, RegisterID* dst)
</del><ins>+RegisterID* BitwiseNotNode::emitBytecode(BytecodeGenerator&amp; generator, RegisterID* dst, TailCallMode)
</ins><span class="cx"> {
</span><span class="cx">     RefPtr&lt;RegisterID&gt; src2 = generator.emitLoad(generator.newTemporary(), jsNumber(-1));
</span><span class="cx">     RefPtr&lt;RegisterID&gt; src1 = generator.emitNode(m_expr);
</span><span class="lines">@@ -1549,7 +1599,7 @@
</span><span class="cx">         branchCondition = triState(!value.pureToBoolean());
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-RegisterID* BinaryOpNode::emitBytecode(BytecodeGenerator&amp; generator, RegisterID* dst)
</del><ins>+RegisterID* BinaryOpNode::emitBytecode(BytecodeGenerator&amp; generator, RegisterID* dst, TailCallMode)
</ins><span class="cx"> {
</span><span class="cx">     OpcodeID opcodeID = this-&gt;opcodeID();
</span><span class="cx"> 
</span><span class="lines">@@ -1593,7 +1643,7 @@
</span><span class="cx">     return result;
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-RegisterID* EqualNode::emitBytecode(BytecodeGenerator&amp; generator, RegisterID* dst)
</del><ins>+RegisterID* EqualNode::emitBytecode(BytecodeGenerator&amp; generator, RegisterID* dst, TailCallMode)
</ins><span class="cx"> {
</span><span class="cx">     if (m_expr1-&gt;isNull() || m_expr2-&gt;isNull()) {
</span><span class="cx">         RefPtr&lt;RegisterID&gt; src = generator.tempDestination(dst);
</span><span class="lines">@@ -1611,7 +1661,7 @@
</span><span class="cx">     return generator.emitEqualityOp(op_eq, generator.finalDestination(dst, src1.get()), src1.get(), src2.get());
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-RegisterID* StrictEqualNode::emitBytecode(BytecodeGenerator&amp; generator, RegisterID* dst)
</del><ins>+RegisterID* StrictEqualNode::emitBytecode(BytecodeGenerator&amp; generator, RegisterID* dst, TailCallMode)
</ins><span class="cx"> {
</span><span class="cx">     ExpressionNode* left = m_expr1;
</span><span class="cx">     ExpressionNode* right = m_expr2;
</span><span class="lines">@@ -1623,7 +1673,7 @@
</span><span class="cx">     return generator.emitEqualityOp(op_stricteq, generator.finalDestination(dst, src1.get()), src1.get(), src2.get());
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-RegisterID* ThrowableBinaryOpNode::emitBytecode(BytecodeGenerator&amp; generator, RegisterID* dst)
</del><ins>+RegisterID* ThrowableBinaryOpNode::emitBytecode(BytecodeGenerator&amp; generator, RegisterID* dst, TailCallMode)
</ins><span class="cx"> {
</span><span class="cx">     RefPtr&lt;RegisterID&gt; src1 = generator.emitNodeForLeftHandSide(m_expr1, m_rightHasAssignments, m_expr2-&gt;isPure(generator));
</span><span class="cx">     RefPtr&lt;RegisterID&gt; src2 = generator.emitNode(m_expr2);
</span><span class="lines">@@ -1631,7 +1681,7 @@
</span><span class="cx">     return generator.emitBinaryOp(opcodeID(), generator.finalDestination(dst, src1.get()), src1.get(), src2.get(), OperandTypes(m_expr1-&gt;resultDescriptor(), m_expr2-&gt;resultDescriptor()));
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-RegisterID* InstanceOfNode::emitBytecode(BytecodeGenerator&amp; generator, RegisterID* dst)
</del><ins>+RegisterID* InstanceOfNode::emitBytecode(BytecodeGenerator&amp; generator, RegisterID* dst, TailCallMode)
</ins><span class="cx"> {
</span><span class="cx">     RefPtr&lt;RegisterID&gt; src1 = generator.emitNodeForLeftHandSide(m_expr1, m_rightHasAssignments, m_expr2-&gt;isPure(generator));
</span><span class="cx">     RefPtr&lt;RegisterID&gt; src2 = generator.emitNode(m_expr2);
</span><span class="lines">@@ -1653,7 +1703,7 @@
</span><span class="cx"> 
</span><span class="cx"> // ------------------------------ LogicalOpNode ----------------------------
</span><span class="cx"> 
</span><del>-RegisterID* LogicalOpNode::emitBytecode(BytecodeGenerator&amp; generator, RegisterID* dst)
</del><ins>+RegisterID* LogicalOpNode::emitBytecode(BytecodeGenerator&amp; generator, RegisterID* dst, TailCallMode tailCallMode)
</ins><span class="cx"> {
</span><span class="cx">     RefPtr&lt;RegisterID&gt; temp = generator.tempDestination(dst);
</span><span class="cx">     RefPtr&lt;Label&gt; target = generator.newLabel();
</span><span class="lines">@@ -1663,7 +1713,7 @@
</span><span class="cx">         generator.emitJumpIfFalse(temp.get(), target.get());
</span><span class="cx">     else
</span><span class="cx">         generator.emitJumpIfTrue(temp.get(), target.get());
</span><del>-    generator.emitNode(temp.get(), m_expr2);
</del><ins>+    generator.emitNode(temp.get(), m_expr2, tailCallMode);
</ins><span class="cx">     generator.emitLabel(target.get());
</span><span class="cx"> 
</span><span class="cx">     return generator.moveToDestinationIfNeeded(dst, temp.get());
</span><span class="lines">@@ -1683,7 +1733,7 @@
</span><span class="cx"> 
</span><span class="cx"> // ------------------------------ ConditionalNode ------------------------------
</span><span class="cx"> 
</span><del>-RegisterID* ConditionalNode::emitBytecode(BytecodeGenerator&amp; generator, RegisterID* dst)
</del><ins>+RegisterID* ConditionalNode::emitBytecode(BytecodeGenerator&amp; generator, RegisterID* dst, TailCallMode tailCallMode)
</ins><span class="cx"> {
</span><span class="cx">     RefPtr&lt;RegisterID&gt; newDst = generator.finalDestination(dst);
</span><span class="cx">     RefPtr&lt;Label&gt; beforeElse = generator.newLabel();
</span><span class="lines">@@ -1694,12 +1744,12 @@
</span><span class="cx">     generator.emitLabel(beforeThen.get());
</span><span class="cx"> 
</span><span class="cx">     generator.emitProfileControlFlow(m_expr1-&gt;startOffset());
</span><del>-    generator.emitNode(newDst.get(), m_expr1);
</del><ins>+    generator.emitNode(newDst.get(), m_expr1, tailCallMode);
</ins><span class="cx">     generator.emitJump(afterElse.get());
</span><span class="cx"> 
</span><span class="cx">     generator.emitLabel(beforeElse.get());
</span><span class="cx">     generator.emitProfileControlFlow(m_expr1-&gt;endOffset() + 1);
</span><del>-    generator.emitNode(newDst.get(), m_expr2);
</del><ins>+    generator.emitNode(newDst.get(), m_expr2, tailCallMode);
</ins><span class="cx"> 
</span><span class="cx">     generator.emitLabel(afterElse.get());
</span><span class="cx"> 
</span><span class="lines">@@ -1767,7 +1817,7 @@
</span><span class="cx">     return result;
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-RegisterID* ReadModifyResolveNode::emitBytecode(BytecodeGenerator&amp; generator, RegisterID* dst)
</del><ins>+RegisterID* ReadModifyResolveNode::emitBytecode(BytecodeGenerator&amp; generator, RegisterID* dst, TailCallMode)
</ins><span class="cx"> {
</span><span class="cx">     JSTextPosition newDivot = divotStart() + m_ident.length();
</span><span class="cx">     Variable var = generator.variable(m_ident);
</span><span class="lines">@@ -1808,7 +1858,7 @@
</span><span class="cx"> 
</span><span class="cx"> // ------------------------------ AssignResolveNode -----------------------------------
</span><span class="cx"> 
</span><del>-RegisterID* AssignResolveNode::emitBytecode(BytecodeGenerator&amp; generator, RegisterID* dst)
</del><ins>+RegisterID* AssignResolveNode::emitBytecode(BytecodeGenerator&amp; generator, RegisterID* dst, TailCallMode)
</ins><span class="cx"> {
</span><span class="cx">     Variable var = generator.variable(m_ident);
</span><span class="cx">     if (RegisterID* local = var.local()) {
</span><span class="lines">@@ -1847,7 +1897,7 @@
</span><span class="cx"> 
</span><span class="cx"> // ------------------------------ AssignDotNode -----------------------------------
</span><span class="cx"> 
</span><del>-RegisterID* AssignDotNode::emitBytecode(BytecodeGenerator&amp; generator, RegisterID* dst)
</del><ins>+RegisterID* AssignDotNode::emitBytecode(BytecodeGenerator&amp; generator, RegisterID* dst, TailCallMode)
</ins><span class="cx"> {
</span><span class="cx">     RefPtr&lt;RegisterID&gt; base = generator.emitNodeForLeftHandSide(m_base, m_rightHasAssignments, m_right-&gt;isPure(generator));
</span><span class="cx">     RefPtr&lt;RegisterID&gt; value = generator.destinationForAssignResult(dst);
</span><span class="lines">@@ -1864,7 +1914,7 @@
</span><span class="cx"> 
</span><span class="cx"> // ------------------------------ ReadModifyDotNode -----------------------------------
</span><span class="cx"> 
</span><del>-RegisterID* ReadModifyDotNode::emitBytecode(BytecodeGenerator&amp; generator, RegisterID* dst)
</del><ins>+RegisterID* ReadModifyDotNode::emitBytecode(BytecodeGenerator&amp; generator, RegisterID* dst, TailCallMode)
</ins><span class="cx"> {
</span><span class="cx">     RefPtr&lt;RegisterID&gt; base = generator.emitNodeForLeftHandSide(m_base, m_rightHasAssignments, m_right-&gt;isPure(generator));
</span><span class="cx"> 
</span><span class="lines">@@ -1883,14 +1933,14 @@
</span><span class="cx"> 
</span><span class="cx"> // ------------------------------ AssignErrorNode -----------------------------------
</span><span class="cx"> 
</span><del>-RegisterID* AssignErrorNode::emitBytecode(BytecodeGenerator&amp; generator, RegisterID*)
</del><ins>+RegisterID* AssignErrorNode::emitBytecode(BytecodeGenerator&amp; generator, RegisterID*, TailCallMode)
</ins><span class="cx"> {
</span><span class="cx">     return emitThrowReferenceError(generator, ASCIILiteral(&quot;Left side of assignment is not a reference.&quot;));
</span><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> // ------------------------------ AssignBracketNode -----------------------------------
</span><span class="cx"> 
</span><del>-RegisterID* AssignBracketNode::emitBytecode(BytecodeGenerator&amp; generator, RegisterID* dst)
</del><ins>+RegisterID* AssignBracketNode::emitBytecode(BytecodeGenerator&amp; generator, RegisterID* dst, TailCallMode)
</ins><span class="cx"> {
</span><span class="cx">     RefPtr&lt;RegisterID&gt; base = generator.emitNodeForLeftHandSide(m_base, m_subscriptHasAssignments || m_rightHasAssignments, m_subscript-&gt;isPure(generator) &amp;&amp; m_right-&gt;isPure(generator));
</span><span class="cx">     RefPtr&lt;RegisterID&gt; property = generator.emitNodeForLeftHandSide(m_subscript, m_rightHasAssignments, m_right-&gt;isPure(generator));
</span><span class="lines">@@ -1914,7 +1964,7 @@
</span><span class="cx"> 
</span><span class="cx"> // ------------------------------ ReadModifyBracketNode -----------------------------------
</span><span class="cx"> 
</span><del>-RegisterID* ReadModifyBracketNode::emitBytecode(BytecodeGenerator&amp; generator, RegisterID* dst)
</del><ins>+RegisterID* ReadModifyBracketNode::emitBytecode(BytecodeGenerator&amp; generator, RegisterID* dst, TailCallMode)
</ins><span class="cx"> {
</span><span class="cx">     RefPtr&lt;RegisterID&gt; base = generator.emitNodeForLeftHandSide(m_base, m_subscriptHasAssignments || m_rightHasAssignments, m_subscript-&gt;isPure(generator) &amp;&amp; m_right-&gt;isPure(generator));
</span><span class="cx">     RefPtr&lt;RegisterID&gt; property = generator.emitNodeForLeftHandSide(m_subscript, m_rightHasAssignments, m_right-&gt;isPure(generator));
</span><span class="lines">@@ -1935,12 +1985,12 @@
</span><span class="cx"> 
</span><span class="cx"> // ------------------------------ CommaNode ------------------------------------
</span><span class="cx"> 
</span><del>-RegisterID* CommaNode::emitBytecode(BytecodeGenerator&amp; generator, RegisterID* dst)
</del><ins>+RegisterID* CommaNode::emitBytecode(BytecodeGenerator&amp; generator, RegisterID* dst, TailCallMode tailCallMode)
</ins><span class="cx"> {
</span><span class="cx">     CommaNode* node = this;
</span><span class="cx">     for (; node &amp;&amp; node-&gt;next(); node = node-&gt;next())
</span><span class="cx">         generator.emitNode(generator.ignoredResult(), node-&gt;m_expr);
</span><del>-    return generator.emitNode(dst, node-&gt;m_expr);
</del><ins>+    return generator.emitNode(dst, node-&gt;m_expr, tailCallMode);
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> // ------------------------------ ConstDeclNode ------------------------------------
</span><span class="lines">@@ -1988,7 +2038,7 @@
</span><span class="cx">     return generator.emitPutToScope(scope.get(), var, value.get(), DoNotThrowIfNotFound);
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-RegisterID* ConstDeclNode::emitBytecode(BytecodeGenerator&amp; generator, RegisterID*)
</del><ins>+RegisterID* ConstDeclNode::emitBytecode(BytecodeGenerator&amp; generator, RegisterID*, TailCallMode)
</ins><span class="cx"> {
</span><span class="cx">     RegisterID* result = 0;
</span><span class="cx">     for (ConstDeclNode* n = this; n; n = n-&gt;m_next)
</span><span class="lines">@@ -1999,7 +2049,7 @@
</span><span class="cx"> 
</span><span class="cx"> // ------------------------------ ConstStatementNode -----------------------------
</span><span class="cx"> 
</span><del>-void ConstStatementNode::emitBytecode(BytecodeGenerator&amp; generator, RegisterID*)
</del><ins>+void ConstStatementNode::emitBytecode(BytecodeGenerator&amp; generator, RegisterID*, TailCallMode)
</ins><span class="cx"> {
</span><span class="cx">     generator.emitDebugHook(WillExecuteStatement, firstLine(), startOffset(), lineStartOffset());
</span><span class="cx">     generator.emitNode(m_next);
</span><span class="lines">@@ -2013,10 +2063,10 @@
</span><span class="cx">     return m_tail;
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-inline void SourceElements::emitBytecode(BytecodeGenerator&amp; generator, RegisterID* dst)
</del><ins>+inline void SourceElements::emitBytecode(BytecodeGenerator&amp; generator, RegisterID* dst, TailCallMode tailCallMode)
</ins><span class="cx"> {
</span><span class="cx">     for (StatementNode* statement = m_head; statement; statement = statement-&gt;next())
</span><del>-        generator.emitNode(dst, statement);
</del><ins>+        generator.emitNode(dst, statement, tailCallMode);
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> // ------------------------------ BlockNode ------------------------------------
</span><span class="lines">@@ -2031,30 +2081,30 @@
</span><span class="cx">     return m_statements ? m_statements-&gt;singleStatement() : 0;
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-void BlockNode::emitBytecode(BytecodeGenerator&amp; generator, RegisterID* dst)
</del><ins>+void BlockNode::emitBytecode(BytecodeGenerator&amp; generator, RegisterID* dst, TailCallMode tailCallMode)
</ins><span class="cx"> {
</span><span class="cx">     if (!m_statements)
</span><span class="cx">         return;
</span><del>-    m_statements-&gt;emitBytecode(generator, dst);
</del><ins>+    m_statements-&gt;emitBytecode(generator, dst, tailCallMode);
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> // ------------------------------ EmptyStatementNode ---------------------------
</span><span class="cx"> 
</span><del>-void EmptyStatementNode::emitBytecode(BytecodeGenerator&amp; generator, RegisterID*)
</del><ins>+void EmptyStatementNode::emitBytecode(BytecodeGenerator&amp; generator, RegisterID*, TailCallMode)
</ins><span class="cx"> {
</span><span class="cx">     generator.emitDebugHook(WillExecuteStatement, firstLine(), startOffset(), lineStartOffset());
</span><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> // ------------------------------ DebuggerStatementNode ---------------------------
</span><span class="cx"> 
</span><del>-void DebuggerStatementNode::emitBytecode(BytecodeGenerator&amp; generator, RegisterID*)
</del><ins>+void DebuggerStatementNode::emitBytecode(BytecodeGenerator&amp; generator, RegisterID*, TailCallMode)
</ins><span class="cx"> {
</span><span class="cx">     generator.emitDebugHook(DidReachBreakpoint, lastLine(), startOffset(), lineStartOffset());
</span><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> // ------------------------------ ExprStatementNode ----------------------------
</span><span class="cx"> 
</span><del>-void ExprStatementNode::emitBytecode(BytecodeGenerator&amp; generator, RegisterID* dst)
</del><ins>+void ExprStatementNode::emitBytecode(BytecodeGenerator&amp; generator, RegisterID* dst, TailCallMode)
</ins><span class="cx"> {
</span><span class="cx">     ASSERT(m_expr);
</span><span class="cx">     generator.emitDebugHook(WillExecuteStatement, firstLine(), startOffset(), lineStartOffset());
</span><span class="lines">@@ -2063,7 +2113,7 @@
</span><span class="cx"> 
</span><span class="cx"> // ------------------------------ VarStatementNode ----------------------------
</span><span class="cx"> 
</span><del>-void VarStatementNode::emitBytecode(BytecodeGenerator&amp; generator, RegisterID*)
</del><ins>+void VarStatementNode::emitBytecode(BytecodeGenerator&amp; generator, RegisterID*, TailCallMode)
</ins><span class="cx"> {
</span><span class="cx">     ASSERT(m_expr);
</span><span class="cx">     generator.emitDebugHook(WillExecuteStatement, firstLine(), startOffset(), lineStartOffset());
</span><span class="lines">@@ -2072,7 +2122,7 @@
</span><span class="cx"> 
</span><span class="cx"> // ------------------------------ EmptyVarExpression ----------------------------
</span><span class="cx"> 
</span><del>-RegisterID* EmptyVarExpression::emitBytecode(BytecodeGenerator&amp; generator, RegisterID*)
</del><ins>+RegisterID* EmptyVarExpression::emitBytecode(BytecodeGenerator&amp; generator, RegisterID*, TailCallMode)
</ins><span class="cx"> {
</span><span class="cx">     if (!generator.vm()-&gt;typeProfiler())
</span><span class="cx">         return nullptr;
</span><span class="lines">@@ -2131,7 +2181,7 @@
</span><span class="cx">     return false;
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-void IfElseNode::emitBytecode(BytecodeGenerator&amp; generator, RegisterID* dst)
</del><ins>+void IfElseNode::emitBytecode(BytecodeGenerator&amp; generator, RegisterID* dst, TailCallMode tailCallMode)
</ins><span class="cx"> {
</span><span class="cx">     generator.emitDebugHook(WillExecuteStatement, firstLine(), startOffset(), lineStartOffset());
</span><span class="cx">     
</span><span class="lines">@@ -2149,7 +2199,7 @@
</span><span class="cx">     generator.emitProfileControlFlow(m_ifBlock-&gt;startOffset());
</span><span class="cx"> 
</span><span class="cx">     if (!didFoldIfBlock) {
</span><del>-        generator.emitNode(dst, m_ifBlock);
</del><ins>+        generator.emitNode(dst, m_ifBlock, tailCallMode);
</ins><span class="cx">         if (m_elseBlock)
</span><span class="cx">             generator.emitJump(afterElse.get());
</span><span class="cx">     }
</span><span class="lines">@@ -2158,7 +2208,7 @@
</span><span class="cx"> 
</span><span class="cx">     if (m_elseBlock) {
</span><span class="cx">         generator.emitProfileControlFlow(m_ifBlock-&gt;endOffset() + (m_ifBlock-&gt;isBlock() ? 1 : 0));
</span><del>-        generator.emitNode(dst, m_elseBlock);
</del><ins>+        generator.emitNode(dst, m_elseBlock, tailCallMode);
</ins><span class="cx">     }
</span><span class="cx"> 
</span><span class="cx">     generator.emitLabel(afterElse.get());
</span><span class="lines">@@ -2168,7 +2218,7 @@
</span><span class="cx"> 
</span><span class="cx"> // ------------------------------ DoWhileNode ----------------------------------
</span><span class="cx"> 
</span><del>-void DoWhileNode::emitBytecode(BytecodeGenerator&amp; generator, RegisterID* dst)
</del><ins>+void DoWhileNode::emitBytecode(BytecodeGenerator&amp; generator, RegisterID* dst, TailCallMode tailCallMode)
</ins><span class="cx"> {
</span><span class="cx">     LabelScopePtr scope = generator.newLabelScope(LabelScope::Loop);
</span><span class="cx"> 
</span><span class="lines">@@ -2177,7 +2227,7 @@
</span><span class="cx">     generator.emitLoopHint();
</span><span class="cx">     generator.emitDebugHook(WillExecuteStatement, lastLine(), startOffset(), lineStartOffset());
</span><span class="cx"> 
</span><del>-    generator.emitNode(dst, m_statement);
</del><ins>+    generator.emitNode(dst, m_statement, tailCallMode);
</ins><span class="cx"> 
</span><span class="cx">     generator.emitLabel(scope-&gt;continueTarget());
</span><span class="cx">     generator.emitDebugHook(WillExecuteStatement, lastLine(), startOffset(), lineStartOffset());
</span><span class="lines">@@ -2188,7 +2238,7 @@
</span><span class="cx"> 
</span><span class="cx"> // ------------------------------ WhileNode ------------------------------------
</span><span class="cx"> 
</span><del>-void WhileNode::emitBytecode(BytecodeGenerator&amp; generator, RegisterID* dst)
</del><ins>+void WhileNode::emitBytecode(BytecodeGenerator&amp; generator, RegisterID* dst, TailCallMode tailCallMode)
</ins><span class="cx"> {
</span><span class="cx">     LabelScopePtr scope = generator.newLabelScope(LabelScope::Loop);
</span><span class="cx">     RefPtr&lt;Label&gt; topOfLoop = generator.newLabel();
</span><span class="lines">@@ -2200,7 +2250,7 @@
</span><span class="cx">     generator.emitLoopHint();
</span><span class="cx">     
</span><span class="cx">     generator.emitProfileControlFlow(m_statement-&gt;startOffset());
</span><del>-    generator.emitNode(dst, m_statement);
</del><ins>+    generator.emitNode(dst, m_statement, tailCallMode);
</ins><span class="cx"> 
</span><span class="cx">     generator.emitLabel(scope-&gt;continueTarget());
</span><span class="cx">     generator.emitDebugHook(WillExecuteStatement, firstLine(), startOffset(), lineStartOffset());
</span><span class="lines">@@ -2214,7 +2264,7 @@
</span><span class="cx"> 
</span><span class="cx"> // ------------------------------ ForNode --------------------------------------
</span><span class="cx"> 
</span><del>-void ForNode::emitBytecode(BytecodeGenerator&amp; generator, RegisterID* dst)
</del><ins>+void ForNode::emitBytecode(BytecodeGenerator&amp; generator, RegisterID* dst, TailCallMode tailCallMode)
</ins><span class="cx"> {
</span><span class="cx">     LabelScopePtr scope = generator.newLabelScope(LabelScope::Loop);
</span><span class="cx"> 
</span><span class="lines">@@ -2231,7 +2281,7 @@
</span><span class="cx">     generator.emitLoopHint();
</span><span class="cx">     generator.emitProfileControlFlow(m_statement-&gt;startOffset());
</span><span class="cx"> 
</span><del>-    generator.emitNode(dst, m_statement);
</del><ins>+    generator.emitNode(dst, m_statement, tailCallMode);
</ins><span class="cx"> 
</span><span class="cx">     generator.emitLabel(scope-&gt;continueTarget());
</span><span class="cx">     generator.emitDebugHook(WillExecuteStatement, firstLine(), startOffset(), lineStartOffset());
</span><span class="lines">@@ -2481,13 +2531,13 @@
</span><span class="cx">     generator.emitProfileControlFlow(profilerEndOffset);
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-void ForInNode::emitBytecode(BytecodeGenerator&amp; generator, RegisterID* dst)
</del><ins>+void ForInNode::emitBytecode(BytecodeGenerator&amp; generator, RegisterID* dst, TailCallMode)
</ins><span class="cx"> {
</span><span class="cx">     this-&gt;emitMultiLoopBytecode(generator, dst);
</span><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> // ------------------------------ ForOfNode ------------------------------------
</span><del>-void ForOfNode::emitBytecode(BytecodeGenerator&amp; generator, RegisterID* dst)
</del><ins>+void ForOfNode::emitBytecode(BytecodeGenerator&amp; generator, RegisterID* dst, TailCallMode)
</ins><span class="cx"> {
</span><span class="cx">     if (!m_lexpr-&gt;isAssignmentLocation()) {
</span><span class="cx">         emitThrowReferenceError(generator, ASCIILiteral(&quot;Left side of for-of statement is not a reference.&quot;));
</span><span class="lines">@@ -2563,7 +2613,7 @@
</span><span class="cx">     return scope-&gt;continueTarget();
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-void ContinueNode::emitBytecode(BytecodeGenerator&amp; generator, RegisterID*)
</del><ins>+void ContinueNode::emitBytecode(BytecodeGenerator&amp; generator, RegisterID*, TailCallMode)
</ins><span class="cx"> {
</span><span class="cx">     generator.emitDebugHook(WillExecuteStatement, firstLine(), startOffset(), lineStartOffset());
</span><span class="cx">     
</span><span class="lines">@@ -2592,7 +2642,7 @@
</span><span class="cx">     return scope-&gt;breakTarget();
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-void BreakNode::emitBytecode(BytecodeGenerator&amp; generator, RegisterID*)
</del><ins>+void BreakNode::emitBytecode(BytecodeGenerator&amp; generator, RegisterID*, TailCallMode)
</ins><span class="cx"> {
</span><span class="cx">     generator.emitDebugHook(WillExecuteStatement, firstLine(), startOffset(), lineStartOffset());
</span><span class="cx">     
</span><span class="lines">@@ -2607,7 +2657,7 @@
</span><span class="cx"> 
</span><span class="cx"> // ------------------------------ ReturnNode -----------------------------------
</span><span class="cx"> 
</span><del>-void ReturnNode::emitBytecode(BytecodeGenerator&amp; generator, RegisterID* dst)
</del><ins>+void ReturnNode::emitBytecode(BytecodeGenerator&amp; generator, RegisterID* dst, TailCallMode tailCallMode)
</ins><span class="cx"> {
</span><span class="cx">     generator.emitDebugHook(WillExecuteStatement, firstLine(), startOffset(), lineStartOffset());
</span><span class="cx">     ASSERT(generator.codeType() == FunctionCode);
</span><span class="lines">@@ -2615,7 +2665,7 @@
</span><span class="cx">     if (dst == generator.ignoredResult())
</span><span class="cx">         dst = 0;
</span><span class="cx"> 
</span><del>-    RefPtr&lt;RegisterID&gt; returnRegister = m_value ? generator.emitNode(dst, m_value) : generator.emitLoad(dst, jsUndefined());
</del><ins>+    RefPtr&lt;RegisterID&gt; returnRegister = m_value ? generator.emitNode(dst, m_value, tailCallMode) : generator.emitLoad(dst, jsUndefined());
</ins><span class="cx">     if (generator.vm()-&gt;typeProfiler()) {
</span><span class="cx">         generator.emitProfileType(returnRegister.get(), ProfileTypeBytecodeFunctionReturnStatement, nullptr);
</span><span class="cx">         generator.emitTypeProfilerExpressionInfo(divotStart(), divotEnd());
</span><span class="lines">@@ -2636,25 +2686,25 @@
</span><span class="cx"> 
</span><span class="cx"> // ------------------------------ WithNode -------------------------------------
</span><span class="cx"> 
</span><del>-void WithNode::emitBytecode(BytecodeGenerator&amp; generator, RegisterID* dst)
</del><ins>+void WithNode::emitBytecode(BytecodeGenerator&amp; generator, RegisterID* dst, TailCallMode tailCallMode)
</ins><span class="cx"> {
</span><span class="cx">     generator.emitDebugHook(WillExecuteStatement, firstLine(), startOffset(), lineStartOffset());
</span><span class="cx"> 
</span><span class="cx">     RefPtr&lt;RegisterID&gt; scope = generator.emitNode(m_expr);
</span><span class="cx">     generator.emitExpressionInfo(m_divot, m_divot - m_expressionLength, m_divot);
</span><span class="cx">     generator.emitPushWithScope(generator.scopeRegister(), scope.get());
</span><del>-    generator.emitNode(dst, m_statement);
</del><ins>+    generator.emitNode(dst, m_statement, tailCallMode);
</ins><span class="cx">     generator.emitPopScope(generator.scopeRegister());
</span><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> // ------------------------------ CaseClauseNode --------------------------------
</span><span class="cx"> 
</span><del>-inline void CaseClauseNode::emitBytecode(BytecodeGenerator&amp; generator, RegisterID* dst)
</del><ins>+inline void CaseClauseNode::emitBytecode(BytecodeGenerator&amp; generator, RegisterID* dst, TailCallMode tailCallMode)
</ins><span class="cx"> {
</span><span class="cx">     generator.emitProfileControlFlow(m_startOffset);
</span><span class="cx">     if (!m_statements)
</span><span class="cx">         return;
</span><del>-    m_statements-&gt;emitBytecode(generator, dst);
</del><ins>+    m_statements-&gt;emitBytecode(generator, dst, tailCallMode);
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> // ------------------------------ CaseBlockNode --------------------------------
</span><span class="lines">@@ -2748,7 +2798,7 @@
</span><span class="cx">     return SwitchInfo::SwitchString;
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-void CaseBlockNode::emitBytecodeForBlock(BytecodeGenerator&amp; generator, RegisterID* switchExpression, RegisterID* dst)
</del><ins>+void CaseBlockNode::emitBytecodeForBlock(BytecodeGenerator&amp; generator, RegisterID* switchExpression, RegisterID* dst, TailCallMode tailCallMode)
</ins><span class="cx"> {
</span><span class="cx">     RefPtr&lt;Label&gt; defaultLabel;
</span><span class="cx">     Vector&lt;RefPtr&lt;Label&gt;, 8&gt; labelVector;
</span><span class="lines">@@ -2787,17 +2837,17 @@
</span><span class="cx">     size_t i = 0;
</span><span class="cx">     for (ClauseListNode* list = m_list1; list; list = list-&gt;getNext()) {
</span><span class="cx">         generator.emitLabel(labelVector[i++].get());
</span><del>-        list-&gt;getClause()-&gt;emitBytecode(generator, dst);
</del><ins>+        list-&gt;getClause()-&gt;emitBytecode(generator, dst, tailCallMode);
</ins><span class="cx">     }
</span><span class="cx"> 
</span><span class="cx">     if (m_defaultClause) {
</span><span class="cx">         generator.emitLabel(defaultLabel.get());
</span><del>-        m_defaultClause-&gt;emitBytecode(generator, dst);
</del><ins>+        m_defaultClause-&gt;emitBytecode(generator, dst, tailCallMode);
</ins><span class="cx">     }
</span><span class="cx"> 
</span><span class="cx">     for (ClauseListNode* list = m_list2; list; list = list-&gt;getNext()) {
</span><span class="cx">         generator.emitLabel(labelVector[i++].get());
</span><del>-        list-&gt;getClause()-&gt;emitBytecode(generator, dst);
</del><ins>+        list-&gt;getClause()-&gt;emitBytecode(generator, dst, tailCallMode);
</ins><span class="cx">     }
</span><span class="cx">     if (!m_defaultClause)
</span><span class="cx">         generator.emitLabel(defaultLabel.get());
</span><span class="lines">@@ -2811,14 +2861,14 @@
</span><span class="cx"> 
</span><span class="cx"> // ------------------------------ SwitchNode -----------------------------------
</span><span class="cx"> 
</span><del>-void SwitchNode::emitBytecode(BytecodeGenerator&amp; generator, RegisterID* dst)
</del><ins>+void SwitchNode::emitBytecode(BytecodeGenerator&amp; generator, RegisterID* dst, TailCallMode tailCallMode)
</ins><span class="cx"> {
</span><span class="cx">     generator.emitDebugHook(WillExecuteStatement, firstLine(), startOffset(), lineStartOffset());
</span><span class="cx">     
</span><span class="cx">     LabelScopePtr scope = generator.newLabelScope(LabelScope::Switch);
</span><span class="cx"> 
</span><span class="cx">     RefPtr&lt;RegisterID&gt; r0 = generator.emitNode(m_expr);
</span><del>-    m_block-&gt;emitBytecodeForBlock(generator, r0.get(), dst);
</del><ins>+    m_block-&gt;emitBytecodeForBlock(generator, r0.get(), dst, tailCallMode);
</ins><span class="cx"> 
</span><span class="cx">     generator.emitLabel(scope-&gt;breakTarget());
</span><span class="cx">     generator.emitProfileControlFlow(endOffset());
</span><span class="lines">@@ -2826,7 +2876,7 @@
</span><span class="cx"> 
</span><span class="cx"> // ------------------------------ LabelNode ------------------------------------
</span><span class="cx"> 
</span><del>-void LabelNode::emitBytecode(BytecodeGenerator&amp; generator, RegisterID* dst)
</del><ins>+void LabelNode::emitBytecode(BytecodeGenerator&amp; generator, RegisterID* dst, TailCallMode)
</ins><span class="cx"> {
</span><span class="cx">     generator.emitDebugHook(WillExecuteStatement, firstLine(), startOffset(), lineStartOffset());
</span><span class="cx"> 
</span><span class="lines">@@ -2840,7 +2890,7 @@
</span><span class="cx"> 
</span><span class="cx"> // ------------------------------ ThrowNode ------------------------------------
</span><span class="cx"> 
</span><del>-void ThrowNode::emitBytecode(BytecodeGenerator&amp; generator, RegisterID* dst)
</del><ins>+void ThrowNode::emitBytecode(BytecodeGenerator&amp; generator, RegisterID* dst, TailCallMode)
</ins><span class="cx"> {
</span><span class="cx">     generator.emitDebugHook(WillExecuteStatement, firstLine(), startOffset(), lineStartOffset());
</span><span class="cx"> 
</span><span class="lines">@@ -2855,7 +2905,7 @@
</span><span class="cx"> 
</span><span class="cx"> // ------------------------------ TryNode --------------------------------------
</span><span class="cx"> 
</span><del>-void TryNode::emitBytecode(BytecodeGenerator&amp; generator, RegisterID* dst)
</del><ins>+void TryNode::emitBytecode(BytecodeGenerator&amp; generator, RegisterID* dst, TailCallMode tailCallMode)
</ins><span class="cx"> {
</span><span class="cx">     // NOTE: The catch and finally blocks must be labeled explicitly, so the
</span><span class="cx">     // optimizer knows they may be jumped to from anywhere.
</span><span class="lines">@@ -2893,7 +2943,7 @@
</span><span class="cx"> 
</span><span class="cx">         generator.emitPushCatchScope(generator.scopeRegister(), m_thrownValueIdent, thrownValueRegister.get(), DontDelete);
</span><span class="cx">         generator.emitProfileControlFlow(m_tryBlock-&gt;endOffset() + 1);
</span><del>-        generator.emitNode(dst, m_catchBlock);
</del><ins>+        generator.emitNode(dst, m_catchBlock, m_finallyBlock ? NoTailCalls : tailCallMode);
</ins><span class="cx">         generator.emitPopScope(generator.scopeRegister());
</span><span class="cx">         generator.emitLabel(catchEndLabel.get());
</span><span class="cx">     }
</span><span class="lines">@@ -2909,7 +2959,7 @@
</span><span class="cx"> 
</span><span class="cx">         // Normal path: run the finally code, and jump to the end.
</span><span class="cx">         generator.emitProfileControlFlow(finallyStartOffset);
</span><del>-        generator.emitNode(dst, m_finallyBlock);
</del><ins>+        generator.emitNode(dst, m_finallyBlock, tailCallMode);
</ins><span class="cx">         generator.emitProfileControlFlow(m_finallyBlock-&gt;endOffset() + 1);
</span><span class="cx">         generator.emitJump(finallyEndLabel.get());
</span><span class="cx"> 
</span><span class="lines">@@ -2918,7 +2968,7 @@
</span><span class="cx">         RefPtr&lt;RegisterID&gt; thrownValueRegister = generator.newTemporary();
</span><span class="cx">         generator.popTryAndEmitCatch(tryData, exceptionRegister.get(), thrownValueRegister.get(), preFinallyLabel.get(), HandlerType::Finally);
</span><span class="cx">         generator.emitProfileControlFlow(finallyStartOffset);
</span><del>-        generator.emitNode(dst, m_finallyBlock);
</del><ins>+        generator.emitNode(dst, m_finallyBlock, tailCallMode);
</ins><span class="cx">         generator.emitThrow(exceptionRegister.get());
</span><span class="cx"> 
</span><span class="cx">         generator.emitLabel(finallyEndLabel.get());
</span><span class="lines">@@ -2934,12 +2984,12 @@
</span><span class="cx"> {
</span><span class="cx">     if (!m_statements)
</span><span class="cx">         return;
</span><del>-    m_statements-&gt;emitBytecode(generator, dst);
</del><ins>+    m_statements-&gt;emitBytecode(generator, dst, isStrictMode() ? CanHaveTailCalls : NoTailCalls);
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> // ------------------------------ ProgramNode -----------------------------
</span><span class="cx"> 
</span><del>-void ProgramNode::emitBytecode(BytecodeGenerator&amp; generator, RegisterID*)
</del><ins>+void ProgramNode::emitBytecode(BytecodeGenerator&amp; generator, RegisterID*, TailCallMode)
</ins><span class="cx"> {
</span><span class="cx">     generator.emitDebugHook(WillExecuteProgram, startLine(), startStartOffset(), startLineStartOffset());
</span><span class="cx"> 
</span><span class="lines">@@ -2954,7 +3004,7 @@
</span><span class="cx"> 
</span><span class="cx"> // ------------------------------ EvalNode -----------------------------
</span><span class="cx"> 
</span><del>-void EvalNode::emitBytecode(BytecodeGenerator&amp; generator, RegisterID*)
</del><ins>+void EvalNode::emitBytecode(BytecodeGenerator&amp; generator, RegisterID*, TailCallMode)
</ins><span class="cx"> {
</span><span class="cx">     generator.emitDebugHook(WillExecuteProgram, startLine(), startStartOffset(), startLineStartOffset());
</span><span class="cx"> 
</span><span class="lines">@@ -2968,11 +3018,11 @@
</span><span class="cx"> 
</span><span class="cx"> // ------------------------------ FunctionBodyNode -----------------------------
</span><span class="cx"> 
</span><del>-void FunctionBodyNode::emitBytecode(BytecodeGenerator&amp;, RegisterID*)
</del><ins>+void FunctionBodyNode::emitBytecode(BytecodeGenerator&amp;, RegisterID*, TailCallMode)
</ins><span class="cx"> {
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-void FunctionNode::emitBytecode(BytecodeGenerator&amp; generator, RegisterID*)
</del><ins>+void FunctionNode::emitBytecode(BytecodeGenerator&amp; generator, RegisterID*, TailCallMode)
</ins><span class="cx"> {
</span><span class="cx">     if (generator.vm()-&gt;typeProfiler()) {
</span><span class="cx">         for (size_t i = 0; i &lt; m_parameters-&gt;size(); i++) {
</span><span class="lines">@@ -3014,13 +3064,13 @@
</span><span class="cx"> 
</span><span class="cx"> // ------------------------------ FuncDeclNode ---------------------------------
</span><span class="cx"> 
</span><del>-void FuncDeclNode::emitBytecode(BytecodeGenerator&amp;, RegisterID*)
</del><ins>+void FuncDeclNode::emitBytecode(BytecodeGenerator&amp;, RegisterID*, TailCallMode)
</ins><span class="cx"> {
</span><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> // ------------------------------ FuncExprNode ---------------------------------
</span><span class="cx"> 
</span><del>-RegisterID* FuncExprNode::emitBytecode(BytecodeGenerator&amp; generator, RegisterID* dst)
</del><ins>+RegisterID* FuncExprNode::emitBytecode(BytecodeGenerator&amp; generator, RegisterID* dst, TailCallMode)
</ins><span class="cx"> {
</span><span class="cx">     return generator.emitNewFunctionExpression(generator.finalDestination(dst), this);
</span><span class="cx"> }
</span><span class="lines">@@ -3028,14 +3078,14 @@
</span><span class="cx"> #if ENABLE(ES6_CLASS_SYNTAX)
</span><span class="cx"> // ------------------------------ ClassDeclNode ---------------------------------
</span><span class="cx"> 
</span><del>-void ClassDeclNode::emitBytecode(BytecodeGenerator&amp; generator, RegisterID* dst)
</del><ins>+void ClassDeclNode::emitBytecode(BytecodeGenerator&amp; generator, RegisterID* dst, TailCallMode)
</ins><span class="cx"> {
</span><span class="cx">     generator.emitNode(dst, m_classDeclaration);
</span><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> // ------------------------------ ClassExprNode ---------------------------------
</span><span class="cx"> 
</span><del>-RegisterID* ClassExprNode::emitBytecode(BytecodeGenerator&amp; generator, RegisterID* dst)
</del><ins>+RegisterID* ClassExprNode::emitBytecode(BytecodeGenerator&amp; generator, RegisterID* dst, TailCallMode)
</ins><span class="cx"> {
</span><span class="cx">     RefPtr&lt;RegisterID&gt; superclass;
</span><span class="cx">     if (m_classHeritage) {
</span><span class="lines">@@ -3106,7 +3156,7 @@
</span><span class="cx"> #endif
</span><span class="cx">     
</span><span class="cx"> // ------------------------------ DestructuringAssignmentNode -----------------
</span><del>-RegisterID* DestructuringAssignmentNode::emitBytecode(BytecodeGenerator&amp; generator, RegisterID* dst)
</del><ins>+RegisterID* DestructuringAssignmentNode::emitBytecode(BytecodeGenerator&amp; generator, RegisterID* dst, TailCallMode)
</ins><span class="cx"> {
</span><span class="cx">     if (RegisterID* result = m_bindings-&gt;emitDirectBinding(generator, dst, m_initializer))
</span><span class="cx">         return result;
</span><span class="lines">@@ -3351,7 +3401,7 @@
</span><span class="cx">     identifiers.append(m_boundProperty);
</span><span class="cx"> }
</span><span class="cx">     
</span><del>-RegisterID* SpreadExpressionNode::emitBytecode(BytecodeGenerator&amp;, RegisterID*)
</del><ins>+RegisterID* SpreadExpressionNode::emitBytecode(BytecodeGenerator&amp;, RegisterID*, TailCallMode)
</ins><span class="cx"> {
</span><span class="cx">     RELEASE_ASSERT_NOT_REACHED();
</span><span class="cx">     return 0;
</span></span></pre></div>
<a id="branchesjsctailcallSourceJavaScriptCoreparserNodesh"></a>
<div class="modfile"><h4>Modified: branches/jsc-tailcall/Source/JavaScriptCore/parser/Nodes.h (186821 => 186822)</h4>
<pre class="diff"><span>
<span class="info">--- branches/jsc-tailcall/Source/JavaScriptCore/parser/Nodes.h        2015-07-14 22:24:54 UTC (rev 186821)
+++ branches/jsc-tailcall/Source/JavaScriptCore/parser/Nodes.h        2015-07-14 22:33:32 UTC (rev 186822)
</span><span class="lines">@@ -76,6 +76,11 @@
</span><span class="cx">     };
</span><span class="cx">     inline FallThroughMode invert(FallThroughMode fallThroughMode) { return static_cast&lt;FallThroughMode&gt;(!fallThroughMode); }
</span><span class="cx"> 
</span><ins>+    enum TailCallMode {
+        CanHaveTailCalls,
+        NoTailCalls,
+    };
+
</ins><span class="cx">     typedef HashSet&lt;RefPtr&lt;UniquedStringImpl&gt;, IdentifierRepHash&gt; IdentifierSet;
</span><span class="cx"> 
</span><span class="cx">     namespace DeclarationStacks {
</span><span class="lines">@@ -144,7 +149,7 @@
</span><span class="cx">         ExpressionNode(const JSTokenLocation&amp;, ResultType = ResultType::unknownType());
</span><span class="cx"> 
</span><span class="cx">     public:
</span><del>-        virtual RegisterID* emitBytecode(BytecodeGenerator&amp;, RegisterID* destination = 0) = 0;
</del><ins>+        virtual RegisterID* emitBytecode(BytecodeGenerator&amp;, RegisterID* destination = 0, TailCallMode = NoTailCalls) = 0;
</ins><span class="cx"> 
</span><span class="cx">         virtual bool isNumber() const { return false; }
</span><span class="cx">         virtual bool isString() const { return false; }
</span><span class="lines">@@ -181,7 +186,7 @@
</span><span class="cx">         StatementNode(const JSTokenLocation&amp;);
</span><span class="cx"> 
</span><span class="cx">     public:
</span><del>-        virtual void emitBytecode(BytecodeGenerator&amp;, RegisterID* destination = 0) = 0;
</del><ins>+        virtual void emitBytecode(BytecodeGenerator&amp;, RegisterID* destination = 0, TailCallMode = NoTailCalls) = 0;
</ins><span class="cx"> 
</span><span class="cx">         void setLoc(unsigned firstLine, unsigned lastLine, int startOffset, int lineStartOffset);
</span><span class="cx">         unsigned lastLine() const { return m_lastLine; }
</span><span class="lines">@@ -209,7 +214,7 @@
</span><span class="cx">         virtual bool isConstant() const  override { return true; }
</span><span class="cx">         virtual JSValue jsValue(BytecodeGenerator&amp;) const = 0;
</span><span class="cx">     private:
</span><del>-        virtual RegisterID* emitBytecode(BytecodeGenerator&amp;, RegisterID* = 0) override;
</del><ins>+        virtual RegisterID* emitBytecode(BytecodeGenerator&amp;, RegisterID* = 0, TailCallMode = NoTailCalls) override;
</ins><span class="cx">         virtual void emitBytecodeInConditionContext(BytecodeGenerator&amp;, Label* trueTarget, Label* falseTarget, FallThroughMode) override;
</span><span class="cx">     };
</span><span class="cx"> 
</span><span class="lines">@@ -239,7 +244,7 @@
</span><span class="cx">         NumberNode(const JSTokenLocation&amp;, double value);
</span><span class="cx">         double value() const { return m_value; }
</span><span class="cx">         virtual bool isIntegerNode() const = 0;
</span><del>-        virtual RegisterID* emitBytecode(BytecodeGenerator&amp;, RegisterID* = 0) override final;
</del><ins>+        virtual RegisterID* emitBytecode(BytecodeGenerator&amp;, RegisterID* = 0, TailCallMode = NoTailCalls) override final;
</ins><span class="cx"> 
</span><span class="cx">     private:
</span><span class="cx">         virtual bool isNumber() const override final { return true; }
</span><span class="lines">@@ -449,7 +454,7 @@
</span><span class="cx">         const Identifier&amp; raw() { return m_raw; }
</span><span class="cx"> 
</span><span class="cx">     private:
</span><del>-        virtual RegisterID* emitBytecode(BytecodeGenerator&amp;, RegisterID* = 0) override;
</del><ins>+        virtual RegisterID* emitBytecode(BytecodeGenerator&amp;, RegisterID* = 0, TailCallMode = NoTailCalls) override;
</ins><span class="cx"> 
</span><span class="cx">         const Identifier&amp; m_cooked;
</span><span class="cx">         const Identifier&amp; m_raw;
</span><span class="lines">@@ -477,7 +482,7 @@
</span><span class="cx">         TemplateExpressionListNode* templateExpressions() const { return m_templateExpressions; }
</span><span class="cx"> 
</span><span class="cx">     private:
</span><del>-        virtual RegisterID* emitBytecode(BytecodeGenerator&amp;, RegisterID* = 0) override;
</del><ins>+        virtual RegisterID* emitBytecode(BytecodeGenerator&amp;, RegisterID* = 0, TailCallMode = NoTailCalls) override;
</ins><span class="cx"> 
</span><span class="cx">         TemplateStringListNode* m_templateStrings;
</span><span class="cx">         TemplateExpressionListNode* m_templateExpressions;
</span><span class="lines">@@ -490,7 +495,7 @@
</span><span class="cx">         TemplateLiteralNode* templateLiteral() const { return m_templateLiteral; }
</span><span class="cx"> 
</span><span class="cx">     private:
</span><del>-        virtual RegisterID* emitBytecode(BytecodeGenerator&amp;, RegisterID* = 0) override;
</del><ins>+        virtual RegisterID* emitBytecode(BytecodeGenerator&amp;, RegisterID* = 0, TailCallMode = NoTailCalls) override;
</ins><span class="cx"> 
</span><span class="cx">         ExpressionNode* m_tag;
</span><span class="cx">         TemplateLiteralNode* m_templateLiteral;
</span><span class="lines">@@ -502,7 +507,7 @@
</span><span class="cx">         RegExpNode(const JSTokenLocation&amp;, const Identifier&amp; pattern, const Identifier&amp; flags);
</span><span class="cx"> 
</span><span class="cx">     private:
</span><del>-        virtual RegisterID* emitBytecode(BytecodeGenerator&amp;, RegisterID* = 0) override;
</del><ins>+        virtual RegisterID* emitBytecode(BytecodeGenerator&amp;, RegisterID* = 0, TailCallMode = NoTailCalls) override;
</ins><span class="cx"> 
</span><span class="cx">         const Identifier&amp; m_pattern;
</span><span class="cx">         const Identifier&amp; m_flags;
</span><span class="lines">@@ -513,7 +518,7 @@
</span><span class="cx">         ThisNode(const JSTokenLocation&amp;, ThisTDZMode);
</span><span class="cx"> 
</span><span class="cx">     private:
</span><del>-        virtual RegisterID* emitBytecode(BytecodeGenerator&amp;, RegisterID* = 0) override;
</del><ins>+        virtual RegisterID* emitBytecode(BytecodeGenerator&amp;, RegisterID* = 0, TailCallMode = NoTailCalls) override;
</ins><span class="cx"> 
</span><span class="cx">         bool m_shouldAlwaysEmitTDZCheck;
</span><span class="cx">     };
</span><span class="lines">@@ -524,7 +529,7 @@
</span><span class="cx"> 
</span><span class="cx">     private:
</span><span class="cx">         virtual bool isSuperNode() const override { return true; }
</span><del>-        virtual RegisterID* emitBytecode(BytecodeGenerator&amp;, RegisterID* = 0) override;
</del><ins>+        virtual RegisterID* emitBytecode(BytecodeGenerator&amp;, RegisterID* = 0, TailCallMode = NoTailCalls) override;
</ins><span class="cx">     };
</span><span class="cx"> 
</span><span class="cx">     class ResolveNode : public ExpressionNode {
</span><span class="lines">@@ -534,7 +539,7 @@
</span><span class="cx">         const Identifier&amp; identifier() const { return m_ident; }
</span><span class="cx"> 
</span><span class="cx">     private:
</span><del>-        virtual RegisterID* emitBytecode(BytecodeGenerator&amp;, RegisterID* = 0) override;
</del><ins>+        virtual RegisterID* emitBytecode(BytecodeGenerator&amp;, RegisterID* = 0, TailCallMode = NoTailCalls) override;
</ins><span class="cx"> 
</span><span class="cx">         virtual bool isPure(BytecodeGenerator&amp;) const override;
</span><span class="cx">         virtual bool isLocation() const override { return true; }
</span><span class="lines">@@ -569,7 +574,7 @@
</span><span class="cx"> 
</span><span class="cx">         ElementNode* elements() const { ASSERT(isSimpleArray()); return m_element; }
</span><span class="cx">     private:
</span><del>-        virtual RegisterID* emitBytecode(BytecodeGenerator&amp;, RegisterID* = 0) override;
</del><ins>+        virtual RegisterID* emitBytecode(BytecodeGenerator&amp;, RegisterID* = 0, TailCallMode = NoTailCalls) override;
</ins><span class="cx"> 
</span><span class="cx">         virtual bool isSimpleArray() const override;
</span><span class="cx"> 
</span><span class="lines">@@ -609,7 +614,7 @@
</span><span class="cx">         PropertyListNode(const JSTokenLocation&amp;, PropertyNode*, PropertyListNode*);
</span><span class="cx"> 
</span><span class="cx">     private:
</span><del>-        virtual RegisterID* emitBytecode(BytecodeGenerator&amp;, RegisterID* = 0) override;
</del><ins>+        virtual RegisterID* emitBytecode(BytecodeGenerator&amp;, RegisterID* = 0, TailCallMode = NoTailCalls) override;
</ins><span class="cx">         void emitPutConstantProperty(BytecodeGenerator&amp;, RegisterID*, PropertyNode&amp;);
</span><span class="cx"> 
</span><span class="cx">         PropertyNode* m_node;
</span><span class="lines">@@ -622,7 +627,7 @@
</span><span class="cx">         ObjectLiteralNode(const JSTokenLocation&amp;, PropertyListNode*);
</span><span class="cx"> 
</span><span class="cx">     private:
</span><del>-        virtual RegisterID* emitBytecode(BytecodeGenerator&amp;, RegisterID* = 0) override;
</del><ins>+        virtual RegisterID* emitBytecode(BytecodeGenerator&amp;, RegisterID* = 0, TailCallMode = NoTailCalls) override;
</ins><span class="cx"> 
</span><span class="cx">         PropertyListNode* m_list;
</span><span class="cx">     };
</span><span class="lines">@@ -637,7 +642,7 @@
</span><span class="cx">         bool subscriptHasAssignments() const { return m_subscriptHasAssignments; }
</span><span class="cx"> 
</span><span class="cx">     private:
</span><del>-        virtual RegisterID* emitBytecode(BytecodeGenerator&amp;, RegisterID* = 0) override;
</del><ins>+        virtual RegisterID* emitBytecode(BytecodeGenerator&amp;, RegisterID* = 0, TailCallMode = NoTailCalls) override;
</ins><span class="cx"> 
</span><span class="cx">         virtual bool isLocation() const override { return true; }
</span><span class="cx">         virtual bool isBracketAccessorNode() const override { return true; }
</span><span class="lines">@@ -655,7 +660,7 @@
</span><span class="cx">         const Identifier&amp; identifier() const { return m_ident; }
</span><span class="cx"> 
</span><span class="cx">     private:
</span><del>-        virtual RegisterID* emitBytecode(BytecodeGenerator&amp;, RegisterID* = 0) override;
</del><ins>+        virtual RegisterID* emitBytecode(BytecodeGenerator&amp;, RegisterID* = 0, TailCallMode = NoTailCalls) override;
</ins><span class="cx"> 
</span><span class="cx">         virtual bool isLocation() const override { return true; }
</span><span class="cx">         virtual bool isDotAccessorNode() const override { return true; }
</span><span class="lines">@@ -671,7 +676,7 @@
</span><span class="cx">         ExpressionNode* expression() const { return m_expression; }
</span><span class="cx">         
</span><span class="cx">     private:
</span><del>-        virtual RegisterID* emitBytecode(BytecodeGenerator&amp;, RegisterID* = 0) override;
</del><ins>+        virtual RegisterID* emitBytecode(BytecodeGenerator&amp;, RegisterID* = 0, TailCallMode = NoTailCalls) override;
</ins><span class="cx">         
</span><span class="cx">         virtual bool isSpreadExpression() const override { return true; }
</span><span class="cx">         ExpressionNode* m_expression;
</span><span class="lines">@@ -686,7 +691,7 @@
</span><span class="cx">         ExpressionNode* m_expr;
</span><span class="cx"> 
</span><span class="cx">     private:
</span><del>-        virtual RegisterID* emitBytecode(BytecodeGenerator&amp;, RegisterID* = 0) override;
</del><ins>+        virtual RegisterID* emitBytecode(BytecodeGenerator&amp;, RegisterID* = 0, TailCallMode = NoTailCalls) override;
</ins><span class="cx">     };
</span><span class="cx"> 
</span><span class="cx">     class ArgumentsNode : public ParserArenaFreeable {
</span><span class="lines">@@ -703,7 +708,7 @@
</span><span class="cx">         NewExprNode(const JSTokenLocation&amp;, ExpressionNode*, ArgumentsNode*);
</span><span class="cx"> 
</span><span class="cx">     private:
</span><del>-        virtual RegisterID* emitBytecode(BytecodeGenerator&amp;, RegisterID* = 0) override;
</del><ins>+        virtual RegisterID* emitBytecode(BytecodeGenerator&amp;, RegisterID* = 0, TailCallMode = NoTailCalls) override;
</ins><span class="cx"> 
</span><span class="cx">         ExpressionNode* m_expr;
</span><span class="cx">         ArgumentsNode* m_args;
</span><span class="lines">@@ -714,7 +719,7 @@
</span><span class="cx">         EvalFunctionCallNode(const JSTokenLocation&amp;, ArgumentsNode*, const JSTextPosition&amp; divot, const JSTextPosition&amp; divotStart, const JSTextPosition&amp; divotEnd);
</span><span class="cx"> 
</span><span class="cx">     private:
</span><del>-        virtual RegisterID* emitBytecode(BytecodeGenerator&amp;, RegisterID* = 0) override;
</del><ins>+        virtual RegisterID* emitBytecode(BytecodeGenerator&amp;, RegisterID* = 0, TailCallMode = NoTailCalls) override;
</ins><span class="cx"> 
</span><span class="cx">         ArgumentsNode* m_args;
</span><span class="cx">     };
</span><span class="lines">@@ -724,7 +729,7 @@
</span><span class="cx">         FunctionCallValueNode(const JSTokenLocation&amp;, ExpressionNode*, ArgumentsNode*, const JSTextPosition&amp; divot, const JSTextPosition&amp; divotStart, const JSTextPosition&amp; divotEnd);
</span><span class="cx"> 
</span><span class="cx">     private:
</span><del>-        virtual RegisterID* emitBytecode(BytecodeGenerator&amp;, RegisterID* = 0) override;
</del><ins>+        virtual RegisterID* emitBytecode(BytecodeGenerator&amp;, RegisterID* = 0, TailCallMode = NoTailCalls) override;
</ins><span class="cx"> 
</span><span class="cx">         ExpressionNode* m_expr;
</span><span class="cx">         ArgumentsNode* m_args;
</span><span class="lines">@@ -735,7 +740,7 @@
</span><span class="cx">         FunctionCallResolveNode(const JSTokenLocation&amp;, const Identifier&amp;, ArgumentsNode*, const JSTextPosition&amp; divot, const JSTextPosition&amp; divotStart, const JSTextPosition&amp; divotEnd);
</span><span class="cx"> 
</span><span class="cx">     private:
</span><del>-        virtual RegisterID* emitBytecode(BytecodeGenerator&amp;, RegisterID* = 0) override;
</del><ins>+        virtual RegisterID* emitBytecode(BytecodeGenerator&amp;, RegisterID* = 0, TailCallMode = NoTailCalls) override;
</ins><span class="cx"> 
</span><span class="cx">         const Identifier&amp; m_ident;
</span><span class="cx">         ArgumentsNode* m_args;
</span><span class="lines">@@ -746,7 +751,7 @@
</span><span class="cx">         FunctionCallBracketNode(const JSTokenLocation&amp;, ExpressionNode* base, ExpressionNode* subscript, bool subscriptHasAssignments, ArgumentsNode*, const JSTextPosition&amp; divot, const JSTextPosition&amp; divotStart, const JSTextPosition&amp; divotEnd);
</span><span class="cx"> 
</span><span class="cx">     private:
</span><del>-        virtual RegisterID* emitBytecode(BytecodeGenerator&amp;, RegisterID* = 0) override;
</del><ins>+        virtual RegisterID* emitBytecode(BytecodeGenerator&amp;, RegisterID* = 0, TailCallMode = NoTailCalls) override;
</ins><span class="cx"> 
</span><span class="cx">         ExpressionNode* m_base;
</span><span class="cx">         ExpressionNode* m_subscript;
</span><span class="lines">@@ -759,7 +764,7 @@
</span><span class="cx">         FunctionCallDotNode(const JSTokenLocation&amp;, ExpressionNode* base, const Identifier&amp;, ArgumentsNode*, const JSTextPosition&amp; divot, const JSTextPosition&amp; divotStart, const JSTextPosition&amp; divotEnd);
</span><span class="cx"> 
</span><span class="cx">     private:
</span><del>-        virtual RegisterID* emitBytecode(BytecodeGenerator&amp;, RegisterID* = 0) override;
</del><ins>+        virtual RegisterID* emitBytecode(BytecodeGenerator&amp;, RegisterID* = 0, TailCallMode = NoTailCalls) override;
</ins><span class="cx"> 
</span><span class="cx">     protected:
</span><span class="cx">         ExpressionNode* m_base;
</span><span class="lines">@@ -780,7 +785,7 @@
</span><span class="cx"> #undef JSC_DECLARE_BYTECODE_INTRINSIC_FUNCTIONS
</span><span class="cx"> 
</span><span class="cx">     private:
</span><del>-        virtual RegisterID* emitBytecode(BytecodeGenerator&amp;, RegisterID* = 0) override;
</del><ins>+        virtual RegisterID* emitBytecode(BytecodeGenerator&amp;, RegisterID* = 0, TailCallMode = NoTailCalls) override;
</ins><span class="cx"> 
</span><span class="cx">         EmitterType m_emitter;
</span><span class="cx">         const Identifier&amp; m_ident;
</span><span class="lines">@@ -792,7 +797,7 @@
</span><span class="cx">         CallFunctionCallDotNode(const JSTokenLocation&amp;, ExpressionNode* base, const Identifier&amp;, ArgumentsNode*, const JSTextPosition&amp; divot, const JSTextPosition&amp; divotStart, const JSTextPosition&amp; divotEnd);
</span><span class="cx"> 
</span><span class="cx">     private:
</span><del>-        virtual RegisterID* emitBytecode(BytecodeGenerator&amp;, RegisterID* = 0) override;
</del><ins>+        virtual RegisterID* emitBytecode(BytecodeGenerator&amp;, RegisterID* = 0, TailCallMode = NoTailCalls) override;
</ins><span class="cx">     };
</span><span class="cx">     
</span><span class="cx">     class ApplyFunctionCallDotNode : public FunctionCallDotNode {
</span><span class="lines">@@ -800,7 +805,7 @@
</span><span class="cx">         ApplyFunctionCallDotNode(const JSTokenLocation&amp;, ExpressionNode* base, const Identifier&amp;, ArgumentsNode*, const JSTextPosition&amp; divot, const JSTextPosition&amp; divotStart, const JSTextPosition&amp; divotEnd);
</span><span class="cx"> 
</span><span class="cx">     private:
</span><del>-        virtual RegisterID* emitBytecode(BytecodeGenerator&amp;, RegisterID* = 0) override;
</del><ins>+        virtual RegisterID* emitBytecode(BytecodeGenerator&amp;, RegisterID* = 0, TailCallMode = NoTailCalls) override;
</ins><span class="cx">     };
</span><span class="cx"> 
</span><span class="cx">     class DeleteResolveNode : public ExpressionNode, public ThrowableExpressionData {
</span><span class="lines">@@ -808,7 +813,7 @@
</span><span class="cx">         DeleteResolveNode(const JSTokenLocation&amp;, const Identifier&amp;, const JSTextPosition&amp; divot, const JSTextPosition&amp; divotStart, const JSTextPosition&amp; divotEnd);
</span><span class="cx"> 
</span><span class="cx">     private:
</span><del>-        virtual RegisterID* emitBytecode(BytecodeGenerator&amp;, RegisterID* = 0) override;
</del><ins>+        virtual RegisterID* emitBytecode(BytecodeGenerator&amp;, RegisterID* = 0, TailCallMode = NoTailCalls) override;
</ins><span class="cx"> 
</span><span class="cx">         const Identifier&amp; m_ident;
</span><span class="cx">     };
</span><span class="lines">@@ -818,7 +823,7 @@
</span><span class="cx">         DeleteBracketNode(const JSTokenLocation&amp;, ExpressionNode* base, ExpressionNode* subscript, const JSTextPosition&amp; divot, const JSTextPosition&amp; divotStart, const JSTextPosition&amp; divotEnd);
</span><span class="cx"> 
</span><span class="cx">     private:
</span><del>-        virtual RegisterID* emitBytecode(BytecodeGenerator&amp;, RegisterID* = 0) override;
</del><ins>+        virtual RegisterID* emitBytecode(BytecodeGenerator&amp;, RegisterID* = 0, TailCallMode = NoTailCalls) override;
</ins><span class="cx"> 
</span><span class="cx">         ExpressionNode* m_base;
</span><span class="cx">         ExpressionNode* m_subscript;
</span><span class="lines">@@ -829,7 +834,7 @@
</span><span class="cx">         DeleteDotNode(const JSTokenLocation&amp;, ExpressionNode* base, const Identifier&amp;, const JSTextPosition&amp; divot, const JSTextPosition&amp; divotStart, const JSTextPosition&amp; divotEnd);
</span><span class="cx"> 
</span><span class="cx">     private:
</span><del>-        virtual RegisterID* emitBytecode(BytecodeGenerator&amp;, RegisterID* = 0) override;
</del><ins>+        virtual RegisterID* emitBytecode(BytecodeGenerator&amp;, RegisterID* = 0, TailCallMode = NoTailCalls) override;
</ins><span class="cx"> 
</span><span class="cx">         ExpressionNode* m_base;
</span><span class="cx">         const Identifier&amp; m_ident;
</span><span class="lines">@@ -840,7 +845,7 @@
</span><span class="cx">         DeleteValueNode(const JSTokenLocation&amp;, ExpressionNode*);
</span><span class="cx"> 
</span><span class="cx">     private:
</span><del>-        virtual RegisterID* emitBytecode(BytecodeGenerator&amp;, RegisterID* = 0) override;
</del><ins>+        virtual RegisterID* emitBytecode(BytecodeGenerator&amp;, RegisterID* = 0, TailCallMode = NoTailCalls) override;
</ins><span class="cx"> 
</span><span class="cx">         ExpressionNode* m_expr;
</span><span class="cx">     };
</span><span class="lines">@@ -850,7 +855,7 @@
</span><span class="cx">         VoidNode(const JSTokenLocation&amp;, ExpressionNode*);
</span><span class="cx"> 
</span><span class="cx">     private:
</span><del>-        virtual RegisterID* emitBytecode(BytecodeGenerator&amp;, RegisterID* = 0) override;
</del><ins>+        virtual RegisterID* emitBytecode(BytecodeGenerator&amp;, RegisterID* = 0, TailCallMode = NoTailCalls) override;
</ins><span class="cx"> 
</span><span class="cx">         ExpressionNode* m_expr;
</span><span class="cx">     };
</span><span class="lines">@@ -862,7 +867,7 @@
</span><span class="cx">         const Identifier&amp; identifier() const { return m_ident; }
</span><span class="cx"> 
</span><span class="cx">     private:
</span><del>-        virtual RegisterID* emitBytecode(BytecodeGenerator&amp;, RegisterID* = 0) override;
</del><ins>+        virtual RegisterID* emitBytecode(BytecodeGenerator&amp;, RegisterID* = 0, TailCallMode = NoTailCalls) override;
</ins><span class="cx"> 
</span><span class="cx">         const Identifier&amp; m_ident;
</span><span class="cx">     };
</span><span class="lines">@@ -872,7 +877,7 @@
</span><span class="cx">         TypeOfValueNode(const JSTokenLocation&amp;, ExpressionNode*);
</span><span class="cx"> 
</span><span class="cx">     private:
</span><del>-        virtual RegisterID* emitBytecode(BytecodeGenerator&amp;, RegisterID* = 0) override;
</del><ins>+        virtual RegisterID* emitBytecode(BytecodeGenerator&amp;, RegisterID* = 0, TailCallMode = NoTailCalls) override;
</ins><span class="cx"> 
</span><span class="cx">         ExpressionNode* m_expr;
</span><span class="cx">     };
</span><span class="lines">@@ -882,7 +887,7 @@
</span><span class="cx">         PrefixNode(const JSTokenLocation&amp;, ExpressionNode*, Operator, const JSTextPosition&amp; divot, const JSTextPosition&amp; divotStart, const JSTextPosition&amp; divotEnd);
</span><span class="cx"> 
</span><span class="cx">     protected:
</span><del>-        virtual RegisterID* emitBytecode(BytecodeGenerator&amp;, RegisterID* = 0) override;
</del><ins>+        virtual RegisterID* emitBytecode(BytecodeGenerator&amp;, RegisterID* = 0, TailCallMode = NoTailCalls) override;
</ins><span class="cx">         virtual RegisterID* emitResolve(BytecodeGenerator&amp;, RegisterID* = 0);
</span><span class="cx">         virtual RegisterID* emitBracket(BytecodeGenerator&amp;, RegisterID* = 0);
</span><span class="cx">         virtual RegisterID* emitDot(BytecodeGenerator&amp;, RegisterID* = 0);
</span><span class="lines">@@ -896,7 +901,7 @@
</span><span class="cx">         PostfixNode(const JSTokenLocation&amp;, ExpressionNode*, Operator, const JSTextPosition&amp; divot, const JSTextPosition&amp; divotStart, const JSTextPosition&amp; divotEnd);
</span><span class="cx"> 
</span><span class="cx">     private:
</span><del>-        virtual RegisterID* emitBytecode(BytecodeGenerator&amp;, RegisterID* = 0) override;
</del><ins>+        virtual RegisterID* emitBytecode(BytecodeGenerator&amp;, RegisterID* = 0, TailCallMode = NoTailCalls) override;
</ins><span class="cx">         virtual RegisterID* emitResolve(BytecodeGenerator&amp;, RegisterID* = 0) override;
</span><span class="cx">         virtual RegisterID* emitBracket(BytecodeGenerator&amp;, RegisterID* = 0) override;
</span><span class="cx">         virtual RegisterID* emitDot(BytecodeGenerator&amp;, RegisterID* = 0) override;
</span><span class="lines">@@ -911,7 +916,7 @@
</span><span class="cx">         const ExpressionNode* expr() const { return m_expr; }
</span><span class="cx"> 
</span><span class="cx">     private:
</span><del>-        virtual RegisterID* emitBytecode(BytecodeGenerator&amp;, RegisterID* = 0) override;
</del><ins>+        virtual RegisterID* emitBytecode(BytecodeGenerator&amp;, RegisterID* = 0, TailCallMode = NoTailCalls) override;
</ins><span class="cx"> 
</span><span class="cx">         OpcodeID opcodeID() const { return m_opcodeID; }
</span><span class="cx"> 
</span><span class="lines">@@ -941,7 +946,7 @@
</span><span class="cx">         const ExpressionNode* expr() const { return m_expr; }
</span><span class="cx"> 
</span><span class="cx">     private:
</span><del>-        virtual RegisterID* emitBytecode(BytecodeGenerator&amp;, RegisterID* = 0) override;
</del><ins>+        virtual RegisterID* emitBytecode(BytecodeGenerator&amp;, RegisterID* = 0, TailCallMode = NoTailCalls) override;
</ins><span class="cx"> 
</span><span class="cx">         ExpressionNode* m_expr;
</span><span class="cx">     };
</span><span class="lines">@@ -966,7 +971,7 @@
</span><span class="cx"> 
</span><span class="cx">     private:
</span><span class="cx">         void tryFoldToBranch(BytecodeGenerator&amp;, TriState&amp; branchCondition, ExpressionNode*&amp; branchExpression);
</span><del>-        virtual RegisterID* emitBytecode(BytecodeGenerator&amp;, RegisterID* = 0) override;
</del><ins>+        virtual RegisterID* emitBytecode(BytecodeGenerator&amp;, RegisterID* = 0, TailCallMode = NoTailCalls) override;
</ins><span class="cx"> 
</span><span class="cx">     protected:
</span><span class="cx">         OpcodeID opcodeID() const { return m_opcodeID; }
</span><span class="lines">@@ -1050,7 +1055,7 @@
</span><span class="cx">         ThrowableBinaryOpNode(const JSTokenLocation&amp;, ExpressionNode* expr1, ExpressionNode* expr2, OpcodeID, bool rightHasAssignments);
</span><span class="cx"> 
</span><span class="cx">     private:
</span><del>-        virtual RegisterID* emitBytecode(BytecodeGenerator&amp;, RegisterID* = 0) override;
</del><ins>+        virtual RegisterID* emitBytecode(BytecodeGenerator&amp;, RegisterID* = 0, TailCallMode = NoTailCalls) override;
</ins><span class="cx">     };
</span><span class="cx">     
</span><span class="cx">     class InstanceOfNode : public ThrowableBinaryOpNode {
</span><span class="lines">@@ -1058,7 +1063,7 @@
</span><span class="cx">         InstanceOfNode(const JSTokenLocation&amp;, ExpressionNode* expr1, ExpressionNode* expr2, bool rightHasAssignments);
</span><span class="cx"> 
</span><span class="cx">     private:
</span><del>-        virtual RegisterID* emitBytecode(BytecodeGenerator&amp;, RegisterID* = 0) override;
</del><ins>+        virtual RegisterID* emitBytecode(BytecodeGenerator&amp;, RegisterID* = 0, TailCallMode = NoTailCalls) override;
</ins><span class="cx">     };
</span><span class="cx"> 
</span><span class="cx">     class InNode : public ThrowableBinaryOpNode {
</span><span class="lines">@@ -1071,7 +1076,7 @@
</span><span class="cx">         EqualNode(const JSTokenLocation&amp;, ExpressionNode* expr1, ExpressionNode* expr2, bool rightHasAssignments);
</span><span class="cx"> 
</span><span class="cx">     private:
</span><del>-        virtual RegisterID* emitBytecode(BytecodeGenerator&amp;, RegisterID* = 0) override;
</del><ins>+        virtual RegisterID* emitBytecode(BytecodeGenerator&amp;, RegisterID* = 0, TailCallMode = NoTailCalls) override;
</ins><span class="cx">     };
</span><span class="cx"> 
</span><span class="cx">     class NotEqualNode : public BinaryOpNode {
</span><span class="lines">@@ -1084,7 +1089,7 @@
</span><span class="cx">         StrictEqualNode(const JSTokenLocation&amp;, ExpressionNode* expr1, ExpressionNode* expr2, bool rightHasAssignments);
</span><span class="cx"> 
</span><span class="cx">     private:
</span><del>-        virtual RegisterID* emitBytecode(BytecodeGenerator&amp;, RegisterID* = 0) override;
</del><ins>+        virtual RegisterID* emitBytecode(BytecodeGenerator&amp;, RegisterID* = 0, TailCallMode = NoTailCalls) override;
</ins><span class="cx">     };
</span><span class="cx"> 
</span><span class="cx">     class NotStrictEqualNode : public BinaryOpNode {
</span><span class="lines">@@ -1113,7 +1118,7 @@
</span><span class="cx">         LogicalOpNode(const JSTokenLocation&amp;, ExpressionNode* expr1, ExpressionNode* expr2, LogicalOperator);
</span><span class="cx"> 
</span><span class="cx">     private:
</span><del>-        virtual RegisterID* emitBytecode(BytecodeGenerator&amp;, RegisterID* = 0) override;
</del><ins>+        virtual RegisterID* emitBytecode(BytecodeGenerator&amp;, RegisterID* = 0, TailCallMode = NoTailCalls) override;
</ins><span class="cx">         virtual void emitBytecodeInConditionContext(BytecodeGenerator&amp;, Label* trueTarget, Label* falseTarget, FallThroughMode) override;
</span><span class="cx"> 
</span><span class="cx">         ExpressionNode* m_expr1;
</span><span class="lines">@@ -1127,7 +1132,7 @@
</span><span class="cx">         ConditionalNode(const JSTokenLocation&amp;, ExpressionNode* logical, ExpressionNode* expr1, ExpressionNode* expr2);
</span><span class="cx"> 
</span><span class="cx">     private:
</span><del>-        virtual RegisterID* emitBytecode(BytecodeGenerator&amp;, RegisterID* = 0) override;
</del><ins>+        virtual RegisterID* emitBytecode(BytecodeGenerator&amp;, RegisterID* = 0, TailCallMode = NoTailCalls) override;
</ins><span class="cx"> 
</span><span class="cx">         ExpressionNode* m_logical;
</span><span class="cx">         ExpressionNode* m_expr1;
</span><span class="lines">@@ -1139,7 +1144,7 @@
</span><span class="cx">         ReadModifyResolveNode(const JSTokenLocation&amp;, const Identifier&amp;, Operator, ExpressionNode*  right, bool rightHasAssignments, const JSTextPosition&amp; divot, const JSTextPosition&amp; divotStart, const JSTextPosition&amp; divotEnd);
</span><span class="cx"> 
</span><span class="cx">     private:
</span><del>-        virtual RegisterID* emitBytecode(BytecodeGenerator&amp;, RegisterID* = 0) override;
</del><ins>+        virtual RegisterID* emitBytecode(BytecodeGenerator&amp;, RegisterID* = 0, TailCallMode = NoTailCalls) override;
</ins><span class="cx"> 
</span><span class="cx">         const Identifier&amp; m_ident;
</span><span class="cx">         ExpressionNode* m_right;
</span><span class="lines">@@ -1152,7 +1157,7 @@
</span><span class="cx">         AssignResolveNode(const JSTokenLocation&amp;, const Identifier&amp;, ExpressionNode* right);
</span><span class="cx"> 
</span><span class="cx">     private:
</span><del>-        virtual RegisterID* emitBytecode(BytecodeGenerator&amp;, RegisterID* = 0) override;
</del><ins>+        virtual RegisterID* emitBytecode(BytecodeGenerator&amp;, RegisterID* = 0, TailCallMode = NoTailCalls) override;
</ins><span class="cx"> 
</span><span class="cx">         const Identifier&amp; m_ident;
</span><span class="cx">         ExpressionNode* m_right;
</span><span class="lines">@@ -1163,7 +1168,7 @@
</span><span class="cx">         ReadModifyBracketNode(const JSTokenLocation&amp;, ExpressionNode* base, ExpressionNode* subscript, Operator, ExpressionNode* right, bool subscriptHasAssignments, bool rightHasAssignments, const JSTextPosition&amp; divot, const JSTextPosition&amp; divotStart, const JSTextPosition&amp; divotEnd);
</span><span class="cx"> 
</span><span class="cx">     private:
</span><del>-        virtual RegisterID* emitBytecode(BytecodeGenerator&amp;, RegisterID* = 0) override;
</del><ins>+        virtual RegisterID* emitBytecode(BytecodeGenerator&amp;, RegisterID* = 0, TailCallMode = NoTailCalls) override;
</ins><span class="cx"> 
</span><span class="cx">         ExpressionNode* m_base;
</span><span class="cx">         ExpressionNode* m_subscript;
</span><span class="lines">@@ -1178,7 +1183,7 @@
</span><span class="cx">         AssignBracketNode(const JSTokenLocation&amp;, ExpressionNode* base, ExpressionNode* subscript, ExpressionNode* right, bool subscriptHasAssignments, bool rightHasAssignments, const JSTextPosition&amp; divot, const JSTextPosition&amp; divotStart, const JSTextPosition&amp; divotEnd);
</span><span class="cx"> 
</span><span class="cx">     private:
</span><del>-        virtual RegisterID* emitBytecode(BytecodeGenerator&amp;, RegisterID* = 0) override;
</del><ins>+        virtual RegisterID* emitBytecode(BytecodeGenerator&amp;, RegisterID* = 0, TailCallMode = NoTailCalls) override;
</ins><span class="cx"> 
</span><span class="cx">         ExpressionNode* m_base;
</span><span class="cx">         ExpressionNode* m_subscript;
</span><span class="lines">@@ -1192,7 +1197,7 @@
</span><span class="cx">         AssignDotNode(const JSTokenLocation&amp;, ExpressionNode* base, const Identifier&amp;, ExpressionNode* right, bool rightHasAssignments, const JSTextPosition&amp; divot, const JSTextPosition&amp; divotStart, const JSTextPosition&amp; divotEnd);
</span><span class="cx"> 
</span><span class="cx">     private:
</span><del>-        virtual RegisterID* emitBytecode(BytecodeGenerator&amp;, RegisterID* = 0) override;
</del><ins>+        virtual RegisterID* emitBytecode(BytecodeGenerator&amp;, RegisterID* = 0, TailCallMode = NoTailCalls) override;
</ins><span class="cx"> 
</span><span class="cx">         ExpressionNode* m_base;
</span><span class="cx">         const Identifier&amp; m_ident;
</span><span class="lines">@@ -1205,7 +1210,7 @@
</span><span class="cx">         ReadModifyDotNode(const JSTokenLocation&amp;, ExpressionNode* base, const Identifier&amp;, Operator, ExpressionNode* right, bool rightHasAssignments, const JSTextPosition&amp; divot, const JSTextPosition&amp; divotStart, const JSTextPosition&amp; divotEnd);
</span><span class="cx"> 
</span><span class="cx">     private:
</span><del>-        virtual RegisterID* emitBytecode(BytecodeGenerator&amp;, RegisterID* = 0) override;
</del><ins>+        virtual RegisterID* emitBytecode(BytecodeGenerator&amp;, RegisterID* = 0, TailCallMode = NoTailCalls) override;
</ins><span class="cx"> 
</span><span class="cx">         ExpressionNode* m_base;
</span><span class="cx">         const Identifier&amp; m_ident;
</span><span class="lines">@@ -1219,7 +1224,7 @@
</span><span class="cx">         AssignErrorNode(const JSTokenLocation&amp;, const JSTextPosition&amp; divot, const JSTextPosition&amp; divotStart, const JSTextPosition&amp; divotEnd);
</span><span class="cx"> 
</span><span class="cx">     private:
</span><del>-        virtual RegisterID* emitBytecode(BytecodeGenerator&amp;, RegisterID* = 0) override;
</del><ins>+        virtual RegisterID* emitBytecode(BytecodeGenerator&amp;, RegisterID* = 0, TailCallMode = NoTailCalls) override;
</ins><span class="cx">     };
</span><span class="cx">     
</span><span class="cx">     class CommaNode final : public ExpressionNode {
</span><span class="lines">@@ -1231,7 +1236,7 @@
</span><span class="cx"> 
</span><span class="cx">     private:
</span><span class="cx">         virtual bool isCommaNode() const override { return true; }
</span><del>-        virtual RegisterID* emitBytecode(BytecodeGenerator&amp;, RegisterID* = 0) override;
</del><ins>+        virtual RegisterID* emitBytecode(BytecodeGenerator&amp;, RegisterID* = 0, TailCallMode = NoTailCalls) override;
</ins><span class="cx"> 
</span><span class="cx">         ExpressionNode* m_expr;
</span><span class="cx">         CommaNode* m_next;
</span><span class="lines">@@ -1245,7 +1250,7 @@
</span><span class="cx">         const Identifier&amp; ident() { return m_ident; }
</span><span class="cx"> 
</span><span class="cx">     private:
</span><del>-        virtual RegisterID* emitBytecode(BytecodeGenerator&amp;, RegisterID* = 0) override;
</del><ins>+        virtual RegisterID* emitBytecode(BytecodeGenerator&amp;, RegisterID* = 0, TailCallMode = NoTailCalls) override;
</ins><span class="cx">         virtual RegisterID* emitCodeSingle(BytecodeGenerator&amp;);
</span><span class="cx"> 
</span><span class="cx">         const Identifier&amp; m_ident;
</span><span class="lines">@@ -1262,7 +1267,7 @@
</span><span class="cx">         ConstStatementNode(const JSTokenLocation&amp;, ConstDeclNode* next);
</span><span class="cx"> 
</span><span class="cx">     private:
</span><del>-        virtual void emitBytecode(BytecodeGenerator&amp;, RegisterID* = 0) override;
</del><ins>+        virtual void emitBytecode(BytecodeGenerator&amp;, RegisterID* = 0, TailCallMode = NoTailCalls) override;
</ins><span class="cx"> 
</span><span class="cx">         ConstDeclNode* m_next;
</span><span class="cx">     };
</span><span class="lines">@@ -1276,7 +1281,7 @@
</span><span class="cx">         StatementNode* singleStatement() const;
</span><span class="cx">         StatementNode* lastStatement() const;
</span><span class="cx"> 
</span><del>-        void emitBytecode(BytecodeGenerator&amp;, RegisterID* destination);
</del><ins>+        void emitBytecode(BytecodeGenerator&amp;, RegisterID* destination, TailCallMode);
</ins><span class="cx"> 
</span><span class="cx">     private:
</span><span class="cx">         StatementNode* m_head;
</span><span class="lines">@@ -1291,7 +1296,7 @@
</span><span class="cx">         StatementNode* lastStatement() const;
</span><span class="cx"> 
</span><span class="cx">     private:
</span><del>-        virtual void emitBytecode(BytecodeGenerator&amp;, RegisterID* = 0) override;
</del><ins>+        virtual void emitBytecode(BytecodeGenerator&amp;, RegisterID* = 0, TailCallMode = NoTailCalls) override;
</ins><span class="cx"> 
</span><span class="cx">         virtual bool isBlock() const override { return true; }
</span><span class="cx"> 
</span><span class="lines">@@ -1303,7 +1308,7 @@
</span><span class="cx">         EmptyStatementNode(const JSTokenLocation&amp;);
</span><span class="cx"> 
</span><span class="cx">     private:
</span><del>-        virtual void emitBytecode(BytecodeGenerator&amp;, RegisterID* = 0) override;
</del><ins>+        virtual void emitBytecode(BytecodeGenerator&amp;, RegisterID* = 0, TailCallMode = NoTailCalls) override;
</ins><span class="cx"> 
</span><span class="cx">         virtual bool isEmptyStatement() const override { return true; }
</span><span class="cx">     };
</span><span class="lines">@@ -1313,7 +1318,7 @@
</span><span class="cx">         DebuggerStatementNode(const JSTokenLocation&amp;);
</span><span class="cx">         
</span><span class="cx">     private:
</span><del>-        virtual void emitBytecode(BytecodeGenerator&amp;, RegisterID* = 0) override;
</del><ins>+        virtual void emitBytecode(BytecodeGenerator&amp;, RegisterID* = 0, TailCallMode = NoTailCalls) override;
</ins><span class="cx">     };
</span><span class="cx"> 
</span><span class="cx">     class ExprStatementNode : public StatementNode {
</span><span class="lines">@@ -1325,7 +1330,7 @@
</span><span class="cx">     private:
</span><span class="cx">         virtual bool isExprStatement() const override { return true; }
</span><span class="cx"> 
</span><del>-        virtual void emitBytecode(BytecodeGenerator&amp;, RegisterID* = 0) override;
</del><ins>+        virtual void emitBytecode(BytecodeGenerator&amp;, RegisterID* = 0, TailCallMode = NoTailCalls) override;
</ins><span class="cx"> 
</span><span class="cx">         ExpressionNode* m_expr;
</span><span class="cx">     };
</span><span class="lines">@@ -1334,7 +1339,7 @@
</span><span class="cx">     public:
</span><span class="cx">         VarStatementNode(const JSTokenLocation&amp;, ExpressionNode*);
</span><span class="cx">     private:
</span><del>-        virtual void emitBytecode(BytecodeGenerator&amp;, RegisterID* = 0) override;
</del><ins>+        virtual void emitBytecode(BytecodeGenerator&amp;, RegisterID* = 0, TailCallMode = NoTailCalls) override;
</ins><span class="cx"> 
</span><span class="cx">         ExpressionNode* m_expr;
</span><span class="cx">     };
</span><span class="lines">@@ -1344,7 +1349,7 @@
</span><span class="cx">         EmptyVarExpression(const JSTokenLocation&amp;, const Identifier&amp;);
</span><span class="cx"> 
</span><span class="cx">     private:
</span><del>-        virtual RegisterID* emitBytecode(BytecodeGenerator&amp;, RegisterID* = 0) override;
</del><ins>+        virtual RegisterID* emitBytecode(BytecodeGenerator&amp;, RegisterID* = 0, TailCallMode = NoTailCalls) override;
</ins><span class="cx"> 
</span><span class="cx">         const Identifier&amp; m_ident;
</span><span class="cx">     };
</span><span class="lines">@@ -1355,7 +1360,7 @@
</span><span class="cx">         IfElseNode(const JSTokenLocation&amp;, ExpressionNode* condition, StatementNode* ifBlock, StatementNode* elseBlock);
</span><span class="cx"> 
</span><span class="cx">     private:
</span><del>-        virtual void emitBytecode(BytecodeGenerator&amp;, RegisterID* = 0) override;
</del><ins>+        virtual void emitBytecode(BytecodeGenerator&amp;, RegisterID* = 0, TailCallMode = NoTailCalls) override;
</ins><span class="cx">         bool tryFoldBreakAndContinue(BytecodeGenerator&amp;, StatementNode* ifBlock,
</span><span class="cx">             Label*&amp; trueTarget, FallThroughMode&amp;);
</span><span class="cx"> 
</span><span class="lines">@@ -1369,7 +1374,7 @@
</span><span class="cx">         DoWhileNode(const JSTokenLocation&amp;, StatementNode*, ExpressionNode*);
</span><span class="cx"> 
</span><span class="cx">     private:
</span><del>-        virtual void emitBytecode(BytecodeGenerator&amp;, RegisterID* = 0) override;
</del><ins>+        virtual void emitBytecode(BytecodeGenerator&amp;, RegisterID* = 0, TailCallMode = NoTailCalls) override;
</ins><span class="cx"> 
</span><span class="cx">         StatementNode* m_statement;
</span><span class="cx">         ExpressionNode* m_expr;
</span><span class="lines">@@ -1380,7 +1385,7 @@
</span><span class="cx">         WhileNode(const JSTokenLocation&amp;, ExpressionNode*, StatementNode*);
</span><span class="cx"> 
</span><span class="cx">     private:
</span><del>-        virtual void emitBytecode(BytecodeGenerator&amp;, RegisterID* = 0) override;
</del><ins>+        virtual void emitBytecode(BytecodeGenerator&amp;, RegisterID* = 0, TailCallMode = NoTailCalls) override;
</ins><span class="cx"> 
</span><span class="cx">         ExpressionNode* m_expr;
</span><span class="cx">         StatementNode* m_statement;
</span><span class="lines">@@ -1391,7 +1396,7 @@
</span><span class="cx">         ForNode(const JSTokenLocation&amp;, ExpressionNode* expr1, ExpressionNode* expr2, ExpressionNode* expr3, StatementNode*);
</span><span class="cx"> 
</span><span class="cx">     private:
</span><del>-        virtual void emitBytecode(BytecodeGenerator&amp;, RegisterID* = 0) override;
</del><ins>+        virtual void emitBytecode(BytecodeGenerator&amp;, RegisterID* = 0, TailCallMode = NoTailCalls) override;
</ins><span class="cx"> 
</span><span class="cx">         ExpressionNode* m_expr1;
</span><span class="cx">         ExpressionNode* m_expr2;
</span><span class="lines">@@ -1420,7 +1425,7 @@
</span><span class="cx">         void emitLoopHeader(BytecodeGenerator&amp;, RegisterID* propertyName);
</span><span class="cx">         void emitMultiLoopBytecode(BytecodeGenerator&amp;, RegisterID* dst);
</span><span class="cx"> 
</span><del>-        virtual void emitBytecode(BytecodeGenerator&amp;, RegisterID* = 0) override;
</del><ins>+        virtual void emitBytecode(BytecodeGenerator&amp;, RegisterID* = 0, TailCallMode = NoTailCalls) override;
</ins><span class="cx">     };
</span><span class="cx">     
</span><span class="cx">     class ForOfNode : public EnumerationNode {
</span><span class="lines">@@ -1428,7 +1433,7 @@
</span><span class="cx">         ForOfNode(const JSTokenLocation&amp;, ExpressionNode*, ExpressionNode*, StatementNode*);
</span><span class="cx">         
</span><span class="cx">     private:
</span><del>-        virtual void emitBytecode(BytecodeGenerator&amp;, RegisterID* = 0) override;
</del><ins>+        virtual void emitBytecode(BytecodeGenerator&amp;, RegisterID* = 0, TailCallMode = NoTailCalls) override;
</ins><span class="cx">     };
</span><span class="cx"> 
</span><span class="cx">     class ContinueNode : public StatementNode, public ThrowableExpressionData {
</span><span class="lines">@@ -1438,7 +1443,7 @@
</span><span class="cx">         
</span><span class="cx">     private:
</span><span class="cx">         virtual bool isContinue() const override { return true; }
</span><del>-        virtual void emitBytecode(BytecodeGenerator&amp;, RegisterID* = 0) override;
</del><ins>+        virtual void emitBytecode(BytecodeGenerator&amp;, RegisterID* = 0, TailCallMode = NoTailCalls) override;
</ins><span class="cx"> 
</span><span class="cx">         const Identifier&amp; m_ident;
</span><span class="cx">     };
</span><span class="lines">@@ -1450,7 +1455,7 @@
</span><span class="cx">         
</span><span class="cx">     private:
</span><span class="cx">         virtual bool isBreak() const override { return true; }
</span><del>-        virtual void emitBytecode(BytecodeGenerator&amp;, RegisterID* = 0) override;
</del><ins>+        virtual void emitBytecode(BytecodeGenerator&amp;, RegisterID* = 0, TailCallMode = NoTailCalls) override;
</ins><span class="cx"> 
</span><span class="cx">         const Identifier&amp; m_ident;
</span><span class="cx">     };
</span><span class="lines">@@ -1462,7 +1467,7 @@
</span><span class="cx">         ExpressionNode* value() { return m_value; }
</span><span class="cx"> 
</span><span class="cx">     private:
</span><del>-        virtual void emitBytecode(BytecodeGenerator&amp;, RegisterID* = 0) override;
</del><ins>+        virtual void emitBytecode(BytecodeGenerator&amp;, RegisterID* = 0, TailCallMode = NoTailCalls) override;
</ins><span class="cx"> 
</span><span class="cx">         virtual bool isReturnNode() const override { return true; }
</span><span class="cx"> 
</span><span class="lines">@@ -1474,7 +1479,7 @@
</span><span class="cx">         WithNode(const JSTokenLocation&amp;, ExpressionNode*, StatementNode*, const JSTextPosition&amp; divot, uint32_t expressionLength);
</span><span class="cx"> 
</span><span class="cx">     private:
</span><del>-        virtual void emitBytecode(BytecodeGenerator&amp;, RegisterID* = 0) override;
</del><ins>+        virtual void emitBytecode(BytecodeGenerator&amp;, RegisterID* = 0, TailCallMode = NoTailCalls) override;
</ins><span class="cx"> 
</span><span class="cx">         ExpressionNode* m_expr;
</span><span class="cx">         StatementNode* m_statement;
</span><span class="lines">@@ -1487,7 +1492,7 @@
</span><span class="cx">         LabelNode(const JSTokenLocation&amp;, const Identifier&amp; name, StatementNode*);
</span><span class="cx"> 
</span><span class="cx">     private:
</span><del>-        virtual void emitBytecode(BytecodeGenerator&amp;, RegisterID* = 0) override;
</del><ins>+        virtual void emitBytecode(BytecodeGenerator&amp;, RegisterID* = 0, TailCallMode = NoTailCalls) override;
</ins><span class="cx"> 
</span><span class="cx">         const Identifier&amp; m_name;
</span><span class="cx">         StatementNode* m_statement;
</span><span class="lines">@@ -1498,7 +1503,7 @@
</span><span class="cx">         ThrowNode(const JSTokenLocation&amp;, ExpressionNode*);
</span><span class="cx"> 
</span><span class="cx">     private:
</span><del>-        virtual void emitBytecode(BytecodeGenerator&amp;, RegisterID* = 0) override;
</del><ins>+        virtual void emitBytecode(BytecodeGenerator&amp;, RegisterID* = 0, TailCallMode = NoTailCalls) override;
</ins><span class="cx"> 
</span><span class="cx">         ExpressionNode* m_expr;
</span><span class="cx">     };
</span><span class="lines">@@ -1508,7 +1513,7 @@
</span><span class="cx">         TryNode(const JSTokenLocation&amp;, StatementNode* tryBlock, const Identifier&amp; exceptionIdent, StatementNode* catchBlock, StatementNode* finallyBlock);
</span><span class="cx"> 
</span><span class="cx">     private:
</span><del>-        virtual void emitBytecode(BytecodeGenerator&amp;, RegisterID* = 0) override;
</del><ins>+        virtual void emitBytecode(BytecodeGenerator&amp;, RegisterID* = 0, TailCallMode = NoTailCalls) override;
</ins><span class="cx"> 
</span><span class="cx">         StatementNode* m_tryBlock;
</span><span class="cx">         const Identifier&amp; m_thrownValueIdent;
</span><span class="lines">@@ -1609,7 +1614,7 @@
</span><span class="cx">         const Vector&lt;RefPtr&lt;UniquedStringImpl&gt;&gt;&amp; closedVariables() const { return m_closedVariables; }
</span><span class="cx"> 
</span><span class="cx">     private:
</span><del>-        virtual void emitBytecode(BytecodeGenerator&amp;, RegisterID* = 0) override;
</del><ins>+        virtual void emitBytecode(BytecodeGenerator&amp;, RegisterID* = 0, TailCallMode = NoTailCalls) override;
</ins><span class="cx">         Vector&lt;RefPtr&lt;UniquedStringImpl&gt;&gt; m_closedVariables;
</span><span class="cx">         unsigned m_startColumn;
</span><span class="cx">         unsigned m_endColumn;
</span><span class="lines">@@ -1625,7 +1630,7 @@
</span><span class="cx">         static const bool scopeIsFunction = false;
</span><span class="cx"> 
</span><span class="cx">     private:
</span><del>-        virtual void emitBytecode(BytecodeGenerator&amp;, RegisterID* = 0) override;
</del><ins>+        virtual void emitBytecode(BytecodeGenerator&amp;, RegisterID* = 0, TailCallMode = NoTailCalls) override;
</ins><span class="cx"> 
</span><span class="cx">         unsigned m_endColumn;
</span><span class="cx">     };
</span><span class="lines">@@ -1661,7 +1666,7 @@
</span><span class="cx"> 
</span><span class="cx">         FunctionParameters* parameters() const { return m_parameters.get(); }
</span><span class="cx"> 
</span><del>-        virtual void emitBytecode(BytecodeGenerator&amp;, RegisterID* = 0) override;
</del><ins>+        virtual void emitBytecode(BytecodeGenerator&amp;, RegisterID* = 0, TailCallMode = NoTailCalls) override;
</ins><span class="cx"> 
</span><span class="cx">         void finishParsing(const SourceCode&amp;, ParameterNode*, const Identifier&amp;, FunctionMode);
</span><span class="cx">         
</span><span class="lines">@@ -1708,7 +1713,7 @@
</span><span class="cx"> 
</span><span class="cx">         FunctionParameters* parameters() const { return m_parameters.get(); }
</span><span class="cx"> 
</span><del>-        virtual void emitBytecode(BytecodeGenerator&amp;, RegisterID* = 0) override;
</del><ins>+        virtual void emitBytecode(BytecodeGenerator&amp;, RegisterID* = 0, TailCallMode = NoTailCalls) override;
</ins><span class="cx"> 
</span><span class="cx">         void finishParsing(PassRefPtr&lt;FunctionParameters&gt;, const Identifier&amp;, FunctionMode);
</span><span class="cx">         
</span><span class="lines">@@ -1736,7 +1741,7 @@
</span><span class="cx">         FunctionBodyNode* body() { return m_body; }
</span><span class="cx"> 
</span><span class="cx">     private:
</span><del>-        virtual RegisterID* emitBytecode(BytecodeGenerator&amp;, RegisterID* = 0) override;
</del><ins>+        virtual RegisterID* emitBytecode(BytecodeGenerator&amp;, RegisterID* = 0, TailCallMode = NoTailCalls) override;
</ins><span class="cx"> 
</span><span class="cx">         virtual bool isFuncExprNode() const override { return true; }
</span><span class="cx"> 
</span><span class="lines">@@ -1752,7 +1757,7 @@
</span><span class="cx">         const Identifier&amp; name() { return m_name; }
</span><span class="cx"> 
</span><span class="cx">     private:
</span><del>-        virtual RegisterID* emitBytecode(BytecodeGenerator&amp;, RegisterID* = 0) override;
</del><ins>+        virtual RegisterID* emitBytecode(BytecodeGenerator&amp;, RegisterID* = 0, TailCallMode = NoTailCalls) override;
</ins><span class="cx"> 
</span><span class="cx">         const Identifier&amp; m_name;
</span><span class="cx">         ExpressionNode* m_constructorExpression;
</span><span class="lines">@@ -1863,7 +1868,7 @@
</span><span class="cx">     private:
</span><span class="cx">         virtual bool isAssignmentLocation() const override { return true; }
</span><span class="cx">         virtual bool isDestructuringNode() const override { return true; }
</span><del>-        virtual RegisterID* emitBytecode(BytecodeGenerator&amp;, RegisterID* = 0) override;
</del><ins>+        virtual RegisterID* emitBytecode(BytecodeGenerator&amp;, RegisterID* = 0, TailCallMode = NoTailCalls) override;
</ins><span class="cx"> 
</span><span class="cx">         RefPtr&lt;DestructuringPatternNode&gt; m_bindings;
</span><span class="cx">         ExpressionNode* m_initializer;
</span><span class="lines">@@ -1877,7 +1882,7 @@
</span><span class="cx">         FunctionBodyNode* body() { return m_body; }
</span><span class="cx"> 
</span><span class="cx">     private:
</span><del>-        virtual void emitBytecode(BytecodeGenerator&amp;, RegisterID* = 0) override;
</del><ins>+        virtual void emitBytecode(BytecodeGenerator&amp;, RegisterID* = 0, TailCallMode = NoTailCalls) override;
</ins><span class="cx"> 
</span><span class="cx">         FunctionBodyNode* m_body;
</span><span class="cx">     };
</span><span class="lines">@@ -1888,7 +1893,7 @@
</span><span class="cx">         ClassDeclNode(const JSTokenLocation&amp;, ExpressionNode* classExpression);
</span><span class="cx"> 
</span><span class="cx">     private:
</span><del>-        virtual void emitBytecode(BytecodeGenerator&amp;, RegisterID* = 0) override;
</del><ins>+        virtual void emitBytecode(BytecodeGenerator&amp;, RegisterID* = 0, TailCallMode = NoTailCalls) override;
</ins><span class="cx"> 
</span><span class="cx">         ExpressionNode* m_classDeclaration;
</span><span class="cx">     };
</span><span class="lines">@@ -1900,7 +1905,7 @@
</span><span class="cx"> 
</span><span class="cx">         ExpressionNode* expr() const { return m_expr; }
</span><span class="cx"> 
</span><del>-        void emitBytecode(BytecodeGenerator&amp;, RegisterID* destination);
</del><ins>+        void emitBytecode(BytecodeGenerator&amp;, RegisterID* destination, TailCallMode);
</ins><span class="cx">         void setStartOffset(int offset) { m_startOffset = offset; }
</span><span class="cx"> 
</span><span class="cx">     private:
</span><span class="lines">@@ -1926,7 +1931,7 @@
</span><span class="cx">     public:
</span><span class="cx">         CaseBlockNode(ClauseListNode* list1, CaseClauseNode* defaultClause, ClauseListNode* list2);
</span><span class="cx"> 
</span><del>-        void emitBytecodeForBlock(BytecodeGenerator&amp;, RegisterID* input, RegisterID* destination);
</del><ins>+        void emitBytecodeForBlock(BytecodeGenerator&amp;, RegisterID* input, RegisterID* destination, TailCallMode);
</ins><span class="cx"> 
</span><span class="cx">     private:
</span><span class="cx">         SwitchInfo::SwitchType tryTableSwitch(Vector&lt;ExpressionNode*, 8&gt;&amp; literalVector, int32_t&amp; min_num, int32_t&amp; max_num);
</span><span class="lines">@@ -1941,7 +1946,7 @@
</span><span class="cx">         SwitchNode(const JSTokenLocation&amp;, ExpressionNode*, CaseBlockNode*);
</span><span class="cx"> 
</span><span class="cx">     private:
</span><del>-        virtual void emitBytecode(BytecodeGenerator&amp;, RegisterID* = 0) override;
</del><ins>+        virtual void emitBytecode(BytecodeGenerator&amp;, RegisterID* = 0, TailCallMode = NoTailCalls) override;
</ins><span class="cx"> 
</span><span class="cx">         ExpressionNode* m_expr;
</span><span class="cx">         CaseBlockNode* m_block;
</span></span></pre>
</div>
</div>

</body>
</html>