<!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>[200038] trunk/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/200038">200038</a></dd>
<dt>Author</dt> <dd>sbarati@apple.com</dd>
<dt>Date</dt> <dd>2016-04-25 12:08:53 -0700 (Mon, 25 Apr 2016)</dd>
</dl>

<h3>Log Message</h3>
<pre>We don't have to parse a function's parameters every time if the function is in the source provider cache
https://bugs.webkit.org/show_bug.cgi?id=156943

Reviewed by Filip Pizlo.

This patch makes a few changes to make parsing inner functions
faster.

First, we were always parsing an inner function's parameter
list using the templatized TreeBuiler. This means if our parent scope
was building an AST, we ended up building AST nodes for the inner
function's parameter list even though these nodes would go unused.
This patch fixes that to *always* build an inner function's parameter
list using the SyntaxChecker. (Note that this is consistent now with
always building an inner function's body with a SyntaxChecker.)

Second, we were always parsing an inner function's parameter list
even if we had that function saved in the source provider cache.
I've fixed that bug and made it so that we skip over the parsing
of a function's parameter list when it's in the source provider
cache. We could probably enhance this in the future to skip
over the entirety of a function starting at the &quot;function&quot;
keyword or any other start of the function (depending on
the function type: arrow function, method, etc).

This patch also renames a few fields. First, I fixed a typo
from &quot;tocken&quot; =&gt; &quot;token&quot; for a few field names. Secondly,
I renamed a field that was called 'bodyStartColumn' to
'parametersStartColumn' because the field really held the
parameter list's start column.

I'm benchmarking this as a 1.5-2% octane/jquery speedup
on a 15&quot; MBP.

* parser/ASTBuilder.h:
(JSC::ASTBuilder::createFunctionExpr):
(JSC::ASTBuilder::createMethodDefinition):
(JSC::ASTBuilder::createArrowFunctionExpr):
(JSC::ASTBuilder::createGetterOrSetterProperty):
(JSC::ASTBuilder::createFuncDeclStatement):
* parser/Lexer.cpp:
(JSC::Lexer&lt;T&gt;::lex):
* parser/Lexer.h:
(JSC::Lexer::currentPosition):
(JSC::Lexer::positionBeforeLastNewline):
(JSC::Lexer::lastTokenLocation):
(JSC::Lexer::setLastLineNumber):
(JSC::Lexer::lastLineNumber):
(JSC::Lexer::prevTerminator):
* parser/Parser.cpp:
(JSC::Parser&lt;LexerType&gt;::parseInner):
(JSC::Parser&lt;LexerType&gt;::parseGeneratorFunctionSourceElements):
(JSC::Parser&lt;LexerType&gt;::parseFunctionBody):
(JSC::stringForFunctionMode):
(JSC::Parser&lt;LexerType&gt;::parseFunctionParameters):
(JSC::Parser&lt;LexerType&gt;::parseFunctionInfo):
* parser/Parser.h:
(JSC::Scope::usedVariablesContains):
(JSC::Scope::forEachUsedVariable):
(JSC::Scope::useVariable):
(JSC::Scope::copyCapturedVariablesToVector):
(JSC::Scope::fillParametersForSourceProviderCache):
(JSC::Scope::restoreFromSourceProviderCache):
* parser/ParserFunctionInfo.h:
* parser/SourceProviderCacheItem.h:
(JSC::SourceProviderCacheItem::endFunctionToken):
(JSC::SourceProviderCacheItem::usedVariables):
(JSC::SourceProviderCacheItem::SourceProviderCacheItem):</pre>

<h3>Modified Paths</h3>
<ul>
<li><a href="#trunkSourceJavaScriptCoreChangeLog">trunk/Source/JavaScriptCore/ChangeLog</a></li>
<li><a href="#trunkSourceJavaScriptCoreparserASTBuilderh">trunk/Source/JavaScriptCore/parser/ASTBuilder.h</a></li>
<li><a href="#trunkSourceJavaScriptCoreparserLexercpp">trunk/Source/JavaScriptCore/parser/Lexer.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoreparserLexerh">trunk/Source/JavaScriptCore/parser/Lexer.h</a></li>
<li><a href="#trunkSourceJavaScriptCoreparserParsercpp">trunk/Source/JavaScriptCore/parser/Parser.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoreparserParserh">trunk/Source/JavaScriptCore/parser/Parser.h</a></li>
<li><a href="#trunkSourceJavaScriptCoreparserParserFunctionInfoh">trunk/Source/JavaScriptCore/parser/ParserFunctionInfo.h</a></li>
<li><a href="#trunkSourceJavaScriptCoreparserSourceProviderCacheItemh">trunk/Source/JavaScriptCore/parser/SourceProviderCacheItem.h</a></li>
</ul>

</div>
<div id="patch">
<h3>Diff</h3>
<a id="trunkSourceJavaScriptCoreChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/ChangeLog (200037 => 200038)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/ChangeLog        2016-04-25 18:38:56 UTC (rev 200037)
+++ trunk/Source/JavaScriptCore/ChangeLog        2016-04-25 19:08:53 UTC (rev 200038)
</span><span class="lines">@@ -1,3 +1,74 @@
</span><ins>+2016-04-25  Saam barati  &lt;sbarati@apple.com&gt;
+
+        We don't have to parse a function's parameters every time if the function is in the source provider cache
+        https://bugs.webkit.org/show_bug.cgi?id=156943
+
+        Reviewed by Filip Pizlo.
+
+        This patch makes a few changes to make parsing inner functions
+        faster.
+
+        First, we were always parsing an inner function's parameter
+        list using the templatized TreeBuiler. This means if our parent scope
+        was building an AST, we ended up building AST nodes for the inner
+        function's parameter list even though these nodes would go unused.
+        This patch fixes that to *always* build an inner function's parameter
+        list using the SyntaxChecker. (Note that this is consistent now with
+        always building an inner function's body with a SyntaxChecker.)
+
+        Second, we were always parsing an inner function's parameter list
+        even if we had that function saved in the source provider cache.
+        I've fixed that bug and made it so that we skip over the parsing 
+        of a function's parameter list when it's in the source provider
+        cache. We could probably enhance this in the future to skip
+        over the entirety of a function starting at the &quot;function&quot;
+        keyword or any other start of the function (depending on
+        the function type: arrow function, method, etc).
+
+        This patch also renames a few fields. First, I fixed a typo
+        from &quot;tocken&quot; =&gt; &quot;token&quot; for a few field names. Secondly,
+        I renamed a field that was called 'bodyStartColumn' to 
+        'parametersStartColumn' because the field really held the
+        parameter list's start column.
+
+        I'm benchmarking this as a 1.5-2% octane/jquery speedup
+        on a 15&quot; MBP.
+
+        * parser/ASTBuilder.h:
+        (JSC::ASTBuilder::createFunctionExpr):
+        (JSC::ASTBuilder::createMethodDefinition):
+        (JSC::ASTBuilder::createArrowFunctionExpr):
+        (JSC::ASTBuilder::createGetterOrSetterProperty):
+        (JSC::ASTBuilder::createFuncDeclStatement):
+        * parser/Lexer.cpp:
+        (JSC::Lexer&lt;T&gt;::lex):
+        * parser/Lexer.h:
+        (JSC::Lexer::currentPosition):
+        (JSC::Lexer::positionBeforeLastNewline):
+        (JSC::Lexer::lastTokenLocation):
+        (JSC::Lexer::setLastLineNumber):
+        (JSC::Lexer::lastLineNumber):
+        (JSC::Lexer::prevTerminator):
+        * parser/Parser.cpp:
+        (JSC::Parser&lt;LexerType&gt;::parseInner):
+        (JSC::Parser&lt;LexerType&gt;::parseGeneratorFunctionSourceElements):
+        (JSC::Parser&lt;LexerType&gt;::parseFunctionBody):
+        (JSC::stringForFunctionMode):
+        (JSC::Parser&lt;LexerType&gt;::parseFunctionParameters):
+        (JSC::Parser&lt;LexerType&gt;::parseFunctionInfo):
+        * parser/Parser.h:
+        (JSC::Scope::usedVariablesContains):
+        (JSC::Scope::forEachUsedVariable):
+        (JSC::Scope::useVariable):
+        (JSC::Scope::copyCapturedVariablesToVector):
+        (JSC::Scope::fillParametersForSourceProviderCache):
+        (JSC::Scope::restoreFromSourceProviderCache):
+        * parser/ParserFunctionInfo.h:
+        * parser/SourceProviderCacheItem.h:
+        (JSC::SourceProviderCacheItem::endFunctionToken):
+        (JSC::SourceProviderCacheItem::usedVariables):
+        (JSC::SourceProviderCacheItem::SourceProviderCacheItem):
+
</ins><span class="cx"> 2016-04-25  Mark Lam  &lt;mark.lam@apple.com&gt;
</span><span class="cx"> 
</span><span class="cx">         Renaming SpecInt32, SpecInt52, MachineInt to SpecInt32Only, SpecInt52Only, AnyInt.
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreparserASTBuilderh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/parser/ASTBuilder.h (200037 => 200038)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/parser/ASTBuilder.h        2016-04-25 18:38:56 UTC (rev 200037)
+++ trunk/Source/JavaScriptCore/parser/ASTBuilder.h        2016-04-25 19:08:53 UTC (rev 200038)
</span><span class="lines">@@ -375,7 +375,7 @@
</span><span class="cx">     ExpressionNode* createFunctionExpr(const JSTokenLocation&amp; location, const ParserFunctionInfo&lt;ASTBuilder&gt;&amp; functionInfo)
</span><span class="cx">     {
</span><span class="cx">         FuncExprNode* result = new (m_parserArena) FuncExprNode(location, *functionInfo.name, functionInfo.body,
</span><del>-            m_sourceCode-&gt;subExpression(functionInfo.startOffset, functionInfo.endOffset, functionInfo.startLine, functionInfo.bodyStartColumn));
</del><ins>+            m_sourceCode-&gt;subExpression(functionInfo.startOffset, functionInfo.endOffset, functionInfo.startLine, functionInfo.parametersStartColumn));
</ins><span class="cx">         functionInfo.body-&gt;setLoc(functionInfo.startLine, functionInfo.endLine, location.startOffset, location.lineStartOffset);
</span><span class="cx">         return result;
</span><span class="cx">     }
</span><span class="lines">@@ -383,7 +383,7 @@
</span><span class="cx">     ExpressionNode* createMethodDefinition(const JSTokenLocation&amp; location, const ParserFunctionInfo&lt;ASTBuilder&gt;&amp; functionInfo)
</span><span class="cx">     {
</span><span class="cx">         MethodDefinitionNode* result = new (m_parserArena) MethodDefinitionNode(location, *functionInfo.name, functionInfo.body,
</span><del>-            m_sourceCode-&gt;subExpression(functionInfo.startOffset, functionInfo.endOffset, functionInfo.startLine, functionInfo.bodyStartColumn));
</del><ins>+            m_sourceCode-&gt;subExpression(functionInfo.startOffset, functionInfo.endOffset, functionInfo.startLine, functionInfo.parametersStartColumn));
</ins><span class="cx">         functionInfo.body-&gt;setLoc(functionInfo.startLine, functionInfo.endLine, location.startOffset, location.lineStartOffset);
</span><span class="cx">         return result;
</span><span class="cx">     }
</span><span class="lines">@@ -403,7 +403,7 @@
</span><span class="cx">     ExpressionNode* createArrowFunctionExpr(const JSTokenLocation&amp; location, const ParserFunctionInfo&lt;ASTBuilder&gt;&amp; functionInfo)
</span><span class="cx">     {
</span><span class="cx">         usesArrowFunction();
</span><del>-        SourceCode source = m_sourceCode-&gt;subExpression(functionInfo.startOffset, functionInfo.body-&gt;isArrowFunctionBodyExpression() ? functionInfo.endOffset - 1 : functionInfo.endOffset, functionInfo.startLine, functionInfo.bodyStartColumn);
</del><ins>+        SourceCode source = m_sourceCode-&gt;subExpression(functionInfo.startOffset, functionInfo.body-&gt;isArrowFunctionBodyExpression() ? functionInfo.endOffset - 1 : functionInfo.endOffset, functionInfo.startLine, functionInfo.parametersStartColumn);
</ins><span class="cx">         ArrowFuncExprNode* result = new (m_parserArena) ArrowFuncExprNode(location, *functionInfo.name, functionInfo.body, source);
</span><span class="cx">         functionInfo.body-&gt;setLoc(functionInfo.startLine, functionInfo.endLine, location.startOffset, location.lineStartOffset);
</span><span class="cx">         return result;
</span><span class="lines">@@ -416,7 +416,7 @@
</span><span class="cx">         functionInfo.body-&gt;setLoc(functionInfo.startLine, functionInfo.endLine, location.startOffset, location.lineStartOffset);
</span><span class="cx">         functionInfo.body-&gt;setEcmaName(*name);
</span><span class="cx">         functionInfo.body-&gt;setInferredName(*name);
</span><del>-        SourceCode source = m_sourceCode-&gt;subExpression(functionInfo.startOffset, functionInfo.endOffset, functionInfo.startLine, functionInfo.bodyStartColumn);
</del><ins>+        SourceCode source = m_sourceCode-&gt;subExpression(functionInfo.startOffset, functionInfo.endOffset, functionInfo.startLine, functionInfo.parametersStartColumn);
</ins><span class="cx">         MethodDefinitionNode* methodDef = new (m_parserArena) MethodDefinitionNode(location, m_vm-&gt;propertyNames-&gt;nullIdentifier, functionInfo.body, source);
</span><span class="cx">         return new (m_parserArena) PropertyNode(*name, methodDef, type, PropertyNode::Unknown, SuperBinding::Needed, isClassProperty);
</span><span class="cx">     }
</span><span class="lines">@@ -426,7 +426,7 @@
</span><span class="cx">     {
</span><span class="cx">         ASSERT(name);
</span><span class="cx">         functionInfo.body-&gt;setLoc(functionInfo.startLine, functionInfo.endLine, location.startOffset, location.lineStartOffset);
</span><del>-        SourceCode source = m_sourceCode-&gt;subExpression(functionInfo.startOffset, functionInfo.endOffset, functionInfo.startLine, functionInfo.bodyStartColumn);
</del><ins>+        SourceCode source = m_sourceCode-&gt;subExpression(functionInfo.startOffset, functionInfo.endOffset, functionInfo.startLine, functionInfo.parametersStartColumn);
</ins><span class="cx">         MethodDefinitionNode* methodDef = new (m_parserArena) MethodDefinitionNode(location, m_vm-&gt;propertyNames-&gt;nullIdentifier, functionInfo.body, source);
</span><span class="cx">         return new (m_parserArena) PropertyNode(name, methodDef, type, PropertyNode::Unknown, SuperBinding::Needed, isClassProperty);
</span><span class="cx">     }
</span><span class="lines">@@ -436,7 +436,7 @@
</span><span class="cx">     {
</span><span class="cx">         functionInfo.body-&gt;setLoc(functionInfo.startLine, functionInfo.endLine, location.startOffset, location.lineStartOffset);
</span><span class="cx">         const Identifier&amp; ident = parserArena.identifierArena().makeNumericIdentifier(vm, name);
</span><del>-        SourceCode source = m_sourceCode-&gt;subExpression(functionInfo.startOffset, functionInfo.endOffset, functionInfo.startLine, functionInfo.bodyStartColumn);
</del><ins>+        SourceCode source = m_sourceCode-&gt;subExpression(functionInfo.startOffset, functionInfo.endOffset, functionInfo.startLine, functionInfo.parametersStartColumn);
</ins><span class="cx">         MethodDefinitionNode* methodDef = new (m_parserArena) MethodDefinitionNode(location, vm-&gt;propertyNames-&gt;nullIdentifier, functionInfo.body, source);
</span><span class="cx">         return new (m_parserArena) PropertyNode(ident, methodDef, type, PropertyNode::Unknown, SuperBinding::Needed, isClassProperty);
</span><span class="cx">     }
</span><span class="lines">@@ -491,7 +491,7 @@
</span><span class="cx">     StatementNode* createFuncDeclStatement(const JSTokenLocation&amp; location, const ParserFunctionInfo&lt;ASTBuilder&gt;&amp; functionInfo)
</span><span class="cx">     {
</span><span class="cx">         FuncDeclNode* decl = new (m_parserArena) FuncDeclNode(location, *functionInfo.name, functionInfo.body,
</span><del>-            m_sourceCode-&gt;subExpression(functionInfo.startOffset, functionInfo.endOffset, functionInfo.startLine, functionInfo.bodyStartColumn));
</del><ins>+            m_sourceCode-&gt;subExpression(functionInfo.startOffset, functionInfo.endOffset, functionInfo.startLine, functionInfo.parametersStartColumn));
</ins><span class="cx">         if (*functionInfo.name == m_vm-&gt;propertyNames-&gt;arguments)
</span><span class="cx">             usesArguments();
</span><span class="cx">         functionInfo.body-&gt;setLoc(functionInfo.startLine, functionInfo.endLine, location.startOffset, location.lineStartOffset);
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreparserLexercpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/parser/Lexer.cpp (200037 => 200038)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/parser/Lexer.cpp        2016-04-25 18:38:56 UTC (rev 200037)
+++ trunk/Source/JavaScriptCore/parser/Lexer.cpp        2016-04-25 19:08:53 UTC (rev 200038)
</span><span class="lines">@@ -1770,7 +1770,7 @@
</span><span class="cx"> {
</span><span class="cx">     JSTokenData* tokenData = &amp;tokenRecord-&gt;m_data;
</span><span class="cx">     JSTokenLocation* tokenLocation = &amp;tokenRecord-&gt;m_location;
</span><del>-    m_lastTockenLocation = JSTokenLocation(tokenRecord-&gt;m_location);
</del><ins>+    m_lastTokenLocation = JSTokenLocation(tokenRecord-&gt;m_location);
</ins><span class="cx">     
</span><span class="cx">     ASSERT(!m_error);
</span><span class="cx">     ASSERT(m_buffer8.isEmpty());
</span><span class="lines">@@ -2002,6 +2002,9 @@
</span><span class="cx">         break;
</span><span class="cx">     case CharacterOpenParen:
</span><span class="cx">         token = OPENPAREN;
</span><ins>+        tokenData-&gt;line = lineNumber();
+        tokenData-&gt;offset = currentOffset();
+        tokenData-&gt;lineStartOffset = currentLineStartOffset();
</ins><span class="cx">         shift();
</span><span class="cx">         break;
</span><span class="cx">     case CharacterCloseParen:
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreparserLexerh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/parser/Lexer.h (200037 => 200038)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/parser/Lexer.h        2016-04-25 18:38:56 UTC (rev 200037)
+++ trunk/Source/JavaScriptCore/parser/Lexer.h        2016-04-25 19:08:53 UTC (rev 200038)
</span><span class="lines">@@ -73,7 +73,7 @@
</span><span class="cx">         return JSTextPosition(m_lineNumber, currentOffset(), currentLineStartOffset());
</span><span class="cx">     }
</span><span class="cx">     JSTextPosition positionBeforeLastNewline() const { return m_positionBeforeLastNewline; }
</span><del>-    JSTokenLocation lastTokenLocation() const { return m_lastTockenLocation; }
</del><ins>+    JSTokenLocation lastTokenLocation() const { return m_lastTokenLocation; }
</ins><span class="cx">     void setLastLineNumber(int lastLineNumber) { m_lastLineNumber = lastLineNumber; }
</span><span class="cx">     int lastLineNumber() const { return m_lastLineNumber; }
</span><span class="cx">     bool prevTerminator() const { return m_terminator; }
</span><span class="lines">@@ -202,7 +202,7 @@
</span><span class="cx">     const T* m_codeStartPlusOffset;
</span><span class="cx">     const T* m_lineStart;
</span><span class="cx">     JSTextPosition m_positionBeforeLastNewline;
</span><del>-    JSTokenLocation m_lastTockenLocation;
</del><ins>+    JSTokenLocation m_lastTokenLocation;
</ins><span class="cx">     bool m_isReparsingFunction;
</span><span class="cx">     bool m_atLineStart;
</span><span class="cx">     bool m_error;
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreparserParsercpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/parser/Parser.cpp (200037 => 200038)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/parser/Parser.cpp        2016-04-25 18:38:56 UTC (rev 200037)
+++ trunk/Source/JavaScriptCore/parser/Parser.cpp        2016-04-25 19:08:53 UTC (rev 200038)
</span><span class="lines">@@ -253,10 +253,9 @@
</span><span class="cx">     if (m_lexer-&gt;isReparsingFunction()) {
</span><span class="cx">         ParserFunctionInfo&lt;ASTBuilder&gt; functionInfo;
</span><span class="cx">         if (parseMode == SourceParseMode::GeneratorBodyMode)
</span><del>-            functionInfo.parameters = createGeneratorParameters(context);
</del><ins>+            m_parameters = createGeneratorParameters(context);
</ins><span class="cx">         else
</span><del>-            parseFunctionParameters(context, parseMode, functionInfo);
-        m_parameters = functionInfo.parameters;
</del><ins>+            m_parameters = parseFunctionParameters(context, parseMode, functionInfo);
</ins><span class="cx"> 
</span><span class="cx">         if (parseMode == SourceParseMode::ArrowFunctionMode &amp;&amp; !hasError()) {
</span><span class="cx">             // The only way we could have an error wile reparsing is if we run out of stack space.
</span><span class="lines">@@ -497,7 +496,7 @@
</span><span class="cx"> 
</span><span class="cx">     ParserFunctionInfo&lt;TreeBuilder&gt; info;
</span><span class="cx">     info.name = &amp;m_vm-&gt;propertyNames-&gt;nullIdentifier;
</span><del>-    info.parameters = createGeneratorParameters(context);
</del><ins>+    createGeneratorParameters(context);
</ins><span class="cx">     info.startOffset = parametersStart;
</span><span class="cx">     info.startLine = tokenLine();
</span><span class="cx">     info.parameterCount = 4; // generator, state, value, resume mode
</span><span class="lines">@@ -513,7 +512,7 @@
</span><span class="cx"> 
</span><span class="cx">     info.endLine = tokenLine();
</span><span class="cx">     info.endOffset = m_token.m_data.offset;
</span><del>-    info.bodyStartColumn = startColumn;
</del><ins>+    info.parametersStartColumn = startColumn;
</ins><span class="cx"> 
</span><span class="cx">     auto functionExpr = context.createFunctionExpr(startLocation, info);
</span><span class="cx">     auto statement = context.createExprStatement(startLocation, functionExpr, start, m_lastTokenEndPosition.line);
</span><span class="lines">@@ -1767,7 +1766,7 @@
</span><span class="cx"> 
</span><span class="cx"> template &lt;typename LexerType&gt;
</span><span class="cx"> template &lt;class TreeBuilder&gt; TreeFunctionBody Parser&lt;LexerType&gt;::parseFunctionBody(
</span><del>-    TreeBuilder&amp; context, const JSTokenLocation&amp; startLocation, int startColumn, int functionKeywordStart, int functionNameStart, int parametersStart, 
</del><ins>+    TreeBuilder&amp; context, SyntaxChecker&amp; syntaxChecker, const JSTokenLocation&amp; startLocation, int startColumn, int functionKeywordStart, int functionNameStart, int parametersStart, 
</ins><span class="cx">     ConstructorKind constructorKind, SuperBinding superBinding, FunctionBodyType bodyType, unsigned parameterCount, SourceParseMode parseMode)
</span><span class="cx"> {
</span><span class="cx">     bool isArrowFunctionBodyExpression = bodyType == ArrowFunctionBodyExpression;
</span><span class="lines">@@ -1781,7 +1780,6 @@
</span><span class="cx"> 
</span><span class="cx">     DepthManager statementDepth(&amp;m_statementDepth);
</span><span class="cx">     m_statementDepth = 0;
</span><del>-    SyntaxChecker syntaxChecker(const_cast&lt;VM*&gt;(m_vm), m_lexer.get());
</del><span class="cx">     if (bodyType == ArrowFunctionBodyExpression)
</span><span class="cx">         failIfFalse(parseArrowFunctionSingleExpressionBodySourceElements(syntaxChecker), &quot;Cannot parse body of this arrow function&quot;);
</span><span class="cx">     else
</span><span class="lines">@@ -1817,13 +1815,10 @@
</span><span class="cx">     return nullptr;
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-template &lt;typename LexerType&gt; template &lt;class TreeBuilder&gt; int Parser&lt;LexerType&gt;::parseFunctionParameters(TreeBuilder&amp; context, SourceParseMode mode, ParserFunctionInfo&lt;TreeBuilder&gt;&amp; functionInfo)
</del><ins>+template &lt;typename LexerType&gt; template &lt;class TreeBuilder, class FunctionInfoType&gt; typename TreeBuilder::FormalParameterList Parser&lt;LexerType&gt;::parseFunctionParameters(TreeBuilder&amp; context, SourceParseMode mode, FunctionInfoType&amp; functionInfo)
</ins><span class="cx"> {
</span><span class="cx">     RELEASE_ASSERT(mode != SourceParseMode::ProgramMode &amp;&amp; mode != SourceParseMode::ModuleAnalyzeMode &amp;&amp; mode != SourceParseMode::ModuleEvaluateMode);
</span><del>-    int parametersStart = m_token.m_location.startOffset;
</del><span class="cx">     TreeFormalParameterList parameterList = context.createFormalParameterList();
</span><del>-    functionInfo.parameters = parameterList;
-    functionInfo.startOffset = parametersStart;
</del><span class="cx">     SetForScope&lt;FunctionParsePhase&gt; functionParsePhasePoisoner(m_parserState.functionParsePhase, FunctionParsePhase::Parameters);
</span><span class="cx">     
</span><span class="cx">     if (mode == SourceParseMode::ArrowFunctionMode) {
</span><span class="lines">@@ -1848,7 +1843,7 @@
</span><span class="cx">             }
</span><span class="cx">         }
</span><span class="cx"> 
</span><del>-        return parametersStart;
</del><ins>+        return parameterList;
</ins><span class="cx">     }
</span><span class="cx"> 
</span><span class="cx">     if (!consume(OPENPAREN)) {
</span><span class="lines">@@ -1879,7 +1874,7 @@
</span><span class="cx">         consumeOrFail(CLOSEPAREN, &quot;Expected a ')' or a ',' after a parameter declaration&quot;);
</span><span class="cx">     }
</span><span class="cx"> 
</span><del>-    return parametersStart;
</del><ins>+    return parameterList;
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> template &lt;typename LexerType&gt;
</span><span class="lines">@@ -1925,17 +1920,93 @@
</span><span class="cx">     int functionNameStart = m_token.m_location.startOffset;
</span><span class="cx">     const Identifier* lastFunctionName = m_parserState.lastFunctionName;
</span><span class="cx">     m_parserState.lastFunctionName = nullptr;
</span><del>-    int parametersStart;
</del><ins>+    int parametersStart = -1;
</ins><span class="cx">     JSTokenLocation startLocation;
</span><del>-    int startColumn;
</del><ins>+    int startColumn = -1;
</ins><span class="cx">     FunctionBodyType functionBodyType;
</span><span class="cx"> 
</span><ins>+    auto loadCachedFunction = [&amp;] () -&gt; bool {
+        ASSERT(parametersStart != -1);
+        ASSERT(startColumn != -1);
+
+        // If we know about this function already, we can use the cached info and skip the parser to the end of the function.
+        if (const SourceProviderCacheItem* cachedInfo = TreeBuilder::CanUseFunctionCache ? findCachedFunctionInfo(parametersStart) : 0) {
+            // If we're in a strict context, the cached function info must say it was strict too.
+            ASSERT(!strictMode() || cachedInfo-&gt;strictMode);
+            JSTokenLocation endLocation;
+
+            ConstructorKind constructorKind = static_cast&lt;ConstructorKind&gt;(cachedInfo-&gt;constructorKind);
+            SuperBinding expectedSuperBinding = static_cast&lt;SuperBinding&gt;(cachedInfo-&gt;expectedSuperBinding);
+            functionScope-&gt;setConstructorKind(constructorKind);
+            functionScope-&gt;setExpectedSuperBinding(expectedSuperBinding);
+
+            endLocation.line = cachedInfo-&gt;lastTokenLine;
+            endLocation.startOffset = cachedInfo-&gt;lastTokenStartOffset;
+            endLocation.lineStartOffset = cachedInfo-&gt;lastTokenLineStartOffset;
+            ASSERT(endLocation.startOffset &gt;= endLocation.lineStartOffset);
+
+            bool endColumnIsOnStartLine = endLocation.line == functionInfo.startLine;
+            unsigned currentLineStartOffset = m_lexer-&gt;currentLineStartOffset();
+            unsigned bodyEndColumn = endColumnIsOnStartLine ? endLocation.startOffset - currentLineStartOffset : endLocation.startOffset - endLocation.lineStartOffset;
+
+            ASSERT(endLocation.startOffset &gt;= endLocation.lineStartOffset);
+            
+            FunctionBodyType functionBodyType;
+            if (mode == SourceParseMode::ArrowFunctionMode)
+                functionBodyType = cachedInfo-&gt;isBodyArrowExpression ?  ArrowFunctionBodyExpression : ArrowFunctionBodyBlock;
+            else
+                functionBodyType = StandardFunctionBodyBlock;
+            
+            functionInfo.body = context.createFunctionMetadata(
+                startLocation, endLocation, startColumn, bodyEndColumn, 
+                functionKeywordStart, functionNameStart, parametersStart, 
+                cachedInfo-&gt;strictMode, constructorKind, expectedSuperBinding, cachedInfo-&gt;parameterCount, mode, functionBodyType == ArrowFunctionBodyExpression);
+            functionInfo.endOffset = cachedInfo-&gt;endFunctionOffset;
+            functionInfo.parameterCount = cachedInfo-&gt;parameterCount;
+
+            functionScope-&gt;restoreFromSourceProviderCache(cachedInfo);
+            popScope(functionScope, TreeBuilder::NeedsFreeVariableInfo);
+            
+            m_token = cachedInfo-&gt;endFunctionToken();
+
+            if (endColumnIsOnStartLine)
+                m_token.m_location.lineStartOffset = currentLineStartOffset;
+
+            m_lexer-&gt;setOffset(m_token.m_location.endOffset, m_token.m_location.lineStartOffset);
+            m_lexer-&gt;setLineNumber(m_token.m_location.line);
+
+            switch (functionBodyType) {
+            case ArrowFunctionBodyExpression:
+                next();
+                context.setEndOffset(functionInfo.body, m_lexer-&gt;currentOffset());
+                break;
+            case ArrowFunctionBodyBlock:
+            case StandardFunctionBodyBlock:
+                context.setEndOffset(functionInfo.body, m_lexer-&gt;currentOffset());
+                next();
+                break;
+            }
+            functionInfo.endLine = m_lastTokenEndPosition.line;
+            return true;
+        }
+
+        return false;
+    };
+
+    SyntaxChecker syntaxChecker(const_cast&lt;VM*&gt;(m_vm), m_lexer.get());
+
</ins><span class="cx">     if (mode == SourceParseMode::ArrowFunctionMode) {
</span><span class="cx">         startLocation = tokenLocation();
</span><span class="cx">         functionInfo.startLine = tokenLine();
</span><span class="cx">         startColumn = tokenColumn();
</span><span class="cx"> 
</span><del>-        parametersStart = parseFunctionParameters(context, mode, functionInfo);
</del><ins>+        parametersStart = m_token.m_location.startOffset;
+        functionInfo.startOffset = parametersStart;
+        functionInfo.parametersStartColumn = startColumn;
+
+        if (loadCachedFunction())
+            return true;
+        parseFunctionParameters(syntaxChecker, mode, functionInfo);
</ins><span class="cx">         propagateError();
</span><span class="cx"> 
</span><span class="cx">         matchOrFail(ARROWFUNCTION, &quot;Expected a '=&gt;' after arrow function parameter declaration&quot;);
</span><span class="lines">@@ -1986,8 +2057,14 @@
</span><span class="cx">         startLocation = tokenLocation();
</span><span class="cx">         functionInfo.startLine = tokenLine();
</span><span class="cx">         startColumn = tokenColumn();
</span><ins>+        functionInfo.parametersStartColumn = startColumn;
</ins><span class="cx"> 
</span><del>-        parametersStart = parseFunctionParameters(context, mode, functionInfo);
</del><ins>+        parametersStart = m_token.m_location.startOffset;
+        functionInfo.startOffset = parametersStart;
+
+        if (loadCachedFunction())
+            return true;
+        parseFunctionParameters(syntaxChecker, mode, functionInfo);
</ins><span class="cx">         propagateError();
</span><span class="cx">         
</span><span class="cx">         matchOrFail(OPENBRACE, &quot;Expected an opening '{' at the start of a &quot;, stringForFunctionMode(mode), &quot; body&quot;);
</span><span class="lines">@@ -2006,67 +2083,30 @@
</span><span class="cx">     functionScope-&gt;setConstructorKind(constructorKind);
</span><span class="cx">     functionScope-&gt;setExpectedSuperBinding(expectedSuperBinding);
</span><span class="cx"> 
</span><del>-    functionInfo.bodyStartColumn = startColumn;
-    
-    // If we know about this function already, we can use the cached info and skip the parser to the end of the function.
-    if (const SourceProviderCacheItem* cachedInfo = TreeBuilder::CanUseFunctionCache ? findCachedFunctionInfo(functionInfo.startOffset) : 0) {
-        // If we're in a strict context, the cached function info must say it was strict too.
-        ASSERT(!strictMode() || cachedInfo-&gt;strictMode);
-        JSTokenLocation endLocation;
-
-        endLocation.line = cachedInfo-&gt;lastTockenLine;
-        endLocation.startOffset = cachedInfo-&gt;lastTockenStartOffset;
-        endLocation.lineStartOffset = cachedInfo-&gt;lastTockenLineStartOffset;
-
-        bool endColumnIsOnStartLine = (endLocation.line == functionInfo.startLine);
-        ASSERT(endLocation.startOffset &gt;= endLocation.lineStartOffset);
-        unsigned bodyEndColumn = endColumnIsOnStartLine ?
-            endLocation.startOffset - m_token.m_data.lineStartOffset :
-            endLocation.startOffset - endLocation.lineStartOffset;
-        unsigned currentLineStartOffset = m_token.m_location.lineStartOffset;
-        
-        functionInfo.body = context.createFunctionMetadata(
-            startLocation, endLocation, functionInfo.bodyStartColumn, bodyEndColumn, 
-            functionKeywordStart, functionNameStart, parametersStart, 
-            cachedInfo-&gt;strictMode, constructorKind, expectedSuperBinding, cachedInfo-&gt;parameterCount, mode, functionBodyType == ArrowFunctionBodyExpression);
-        
-        functionScope-&gt;restoreFromSourceProviderCache(cachedInfo);
-        popScope(functionScope, TreeBuilder::NeedsFreeVariableInfo);
-        
-        m_token = cachedInfo-&gt;endFunctionToken();
-        
-        if (endColumnIsOnStartLine)
-            m_token.m_location.lineStartOffset = currentLineStartOffset;
-
-        m_lexer-&gt;setOffset(m_token.m_location.endOffset, m_token.m_location.lineStartOffset);
-        m_lexer-&gt;setLineNumber(m_token.m_location.line);
-        functionInfo.endOffset = cachedInfo-&gt;endFunctionOffset;
-
-        if (mode == SourceParseMode::ArrowFunctionMode)
-            functionBodyType = cachedInfo-&gt;isBodyArrowExpression ?  ArrowFunctionBodyExpression : ArrowFunctionBodyBlock;
-        else
-            functionBodyType = StandardFunctionBodyBlock;
-        
-        switch (functionBodyType) {
-        case ArrowFunctionBodyExpression:
-            next();
-            context.setEndOffset(functionInfo.body, m_lexer-&gt;currentOffset());
-            break;
-        case ArrowFunctionBodyBlock:
-        case StandardFunctionBodyBlock:
-            context.setEndOffset(functionInfo.body, m_lexer-&gt;currentOffset());
-            next();
-            break;
-        }
-        functionInfo.endLine = m_lastTokenEndPosition.line;
-        return true;
-    }
-    
</del><span class="cx">     m_parserState.lastFunctionName = lastFunctionName;
</span><span class="cx">     ParserState oldState = internalSaveParserState();
</span><span class="cx"> 
</span><ins>+    // FIXME: https://bugs.webkit.org/show_bug.cgi?id=156962
+    // This loop collects the set of capture candidates that aren't
+    // part of the set of this function's declared parameters. We will
+    // figure out which parameters are captured for this function when
+    // we actually generate code for it. For now, we just propagate to
+    // our parent scopes which variables we might have closed over that
+    // belong to them. This is necessary for correctness when using
+    // the source provider cache because we can't close over a variable
+    // that we don't claim to close over. The source provider cache must
+    // know this information to properly cache this function.
+    // This might work itself out nicer if we declared a different
+    // Scope struct for the parameters (because they are indeed implemented
+    // as their own scope).
+    UniquedStringImplPtrSet nonLocalCapturesFromParameterExpressions;
+    functionScope-&gt;forEachUsedVariable([&amp;] (UniquedStringImpl* impl) {
+        if (!functionScope-&gt;hasDeclaredParameter(impl))
+            nonLocalCapturesFromParameterExpressions.add(impl);
+    });
+
</ins><span class="cx">     auto performParsingFunctionBody = [&amp;] {
</span><del>-        return parseFunctionBody(context, startLocation, startColumn, functionKeywordStart, functionNameStart, parametersStart, constructorKind, expectedSuperBinding, functionBodyType, functionInfo.parameterCount, mode);
</del><ins>+        return parseFunctionBody(context, syntaxChecker, startLocation, startColumn, functionKeywordStart, functionNameStart, parametersStart, constructorKind, expectedSuperBinding, functionBodyType, functionInfo.parameterCount, mode);
</ins><span class="cx">     };
</span><span class="cx"> 
</span><span class="cx">     if (mode == SourceParseMode::GeneratorWrapperFunctionMode) {
</span><span class="lines">@@ -2134,16 +2174,18 @@
</span><span class="cx">         SourceProviderCacheItemCreationParameters parameters;
</span><span class="cx">         parameters.endFunctionOffset = functionInfo.endOffset;
</span><span class="cx">         parameters.functionNameStart = functionNameStart;
</span><del>-        parameters.lastTockenLine = location.line;
-        parameters.lastTockenStartOffset = location.startOffset;
-        parameters.lastTockenEndOffset = location.endOffset;
-        parameters.lastTockenLineStartOffset = location.lineStartOffset;
</del><ins>+        parameters.lastTokenLine = location.line;
+        parameters.lastTokenStartOffset = location.startOffset;
+        parameters.lastTokenEndOffset = location.endOffset;
+        parameters.lastTokenLineStartOffset = location.lineStartOffset;
</ins><span class="cx">         parameters.parameterCount = functionInfo.parameterCount;
</span><ins>+        parameters.constructorKind = constructorKind;
+        parameters.expectedSuperBinding = expectedSuperBinding;
</ins><span class="cx">         if (functionBodyType == ArrowFunctionBodyExpression) {
</span><span class="cx">             parameters.isBodyArrowExpression = true;
</span><span class="cx">             parameters.tokenType = m_token.m_type;
</span><span class="cx">         }
</span><del>-        functionScope-&gt;fillParametersForSourceProviderCache(parameters);
</del><ins>+        functionScope-&gt;fillParametersForSourceProviderCache(parameters, nonLocalCapturesFromParameterExpressions);
</ins><span class="cx">         newInfo = SourceProviderCacheItem::create(parameters);
</span><span class="cx">     }
</span><span class="cx">     
</span><span class="lines">@@ -2153,7 +2195,7 @@
</span><span class="cx">         matchOrFail(CLOSEBRACE, &quot;Expected a closing '}' after a &quot;, stringForFunctionMode(mode), &quot; body&quot;);
</span><span class="cx">         next();
</span><span class="cx">     }
</span><del>-    
</del><ins>+
</ins><span class="cx">     if (newInfo)
</span><span class="cx">         m_functionCache-&gt;add(functionInfo.startOffset, WTFMove(newInfo));
</span><span class="cx">     
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreparserParserh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/parser/Parser.h (200037 => 200038)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/parser/Parser.h        2016-04-25 18:38:56 UTC (rev 200037)
+++ trunk/Source/JavaScriptCore/parser/Parser.h        2016-04-25 19:08:53 UTC (rev 200038)
</span><span class="lines">@@ -50,6 +50,7 @@
</span><span class="cx"> class VM;
</span><span class="cx"> class ProgramNode;
</span><span class="cx"> class SourceCode;
</span><ins>+class SyntaxChecker;
</ins><span class="cx"> 
</span><span class="cx"> // Macros to make the more common TreeBuilder types a little less verbose
</span><span class="cx"> #define TreeStatement typename TreeBuilder::Statement
</span><span class="lines">@@ -501,6 +502,14 @@
</span><span class="cx">         }
</span><span class="cx">         return false;
</span><span class="cx">     }
</span><ins>+    template &lt;typename Func&gt;
+    void forEachUsedVariable(const Func&amp; func)
+    {
+        for (const UniquedStringImplPtrSet&amp; set : m_usedVariables) {
+            for (UniquedStringImpl* impl : set)
+                func(impl);
+        }
+    }
</ins><span class="cx">     void useVariable(const Identifier* ident, bool isEval)
</span><span class="cx">     {
</span><span class="cx">         useVariable(ident-&gt;impl(), isEval);
</span><span class="lines">@@ -644,7 +653,7 @@
</span><span class="cx">         }
</span><span class="cx">     }
</span><span class="cx"> 
</span><del>-    void fillParametersForSourceProviderCache(SourceProviderCacheItemCreationParameters&amp; parameters)
</del><ins>+    void fillParametersForSourceProviderCache(SourceProviderCacheItemCreationParameters&amp; parameters, const UniquedStringImplPtrSet&amp; capturesFromParameterExpressions)
</ins><span class="cx">     {
</span><span class="cx">         ASSERT(m_isFunction);
</span><span class="cx">         parameters.usesEval = m_usesEval;
</span><span class="lines">@@ -653,6 +662,18 @@
</span><span class="cx">         parameters.innerArrowFunctionFeatures = m_innerArrowFunctionFeatures;
</span><span class="cx">         for (const UniquedStringImplPtrSet&amp; set : m_usedVariables)
</span><span class="cx">             copyCapturedVariablesToVector(set, parameters.usedVariables);
</span><ins>+
+        // FIXME: https://bugs.webkit.org/show_bug.cgi?id=156962
+        // We add these unconditionally because we currently don't keep a separate
+        // declaration scope for a function's parameters and its var/let/const declarations.
+        // This is somewhat unfortunate and we should refactor to do this at some point
+        // because parameters logically form a parent scope to var/let/const variables.
+        // But because we don't do this, we must grab capture candidates from a parameter
+        // list before we parse the body of a function because the body's declarations
+        // might make us believe something isn't actually a capture candidate when it really
+        // is.
+        for (UniquedStringImpl* impl : capturesFromParameterExpressions)
+            parameters.usedVariables.append(impl);
</ins><span class="cx">     }
</span><span class="cx"> 
</span><span class="cx">     void restoreFromSourceProviderCache(const SourceProviderCacheItem* info)
</span><span class="lines">@@ -1389,7 +1410,7 @@
</span><span class="cx">     template &lt;class TreeBuilder&gt; TreeProperty parseProperty(TreeBuilder&amp;, bool strict);
</span><span class="cx">     template &lt;class TreeBuilder&gt; TreeExpression parsePropertyMethod(TreeBuilder&amp; context, const Identifier* methodName, bool isGenerator);
</span><span class="cx">     template &lt;class TreeBuilder&gt; TreeProperty parseGetterSetter(TreeBuilder&amp;, bool strict, PropertyNode::Type, unsigned getterOrSetterStartOffset, ConstructorKind, bool isClassProperty);
</span><del>-    template &lt;class TreeBuilder&gt; ALWAYS_INLINE TreeFunctionBody parseFunctionBody(TreeBuilder&amp;, const JSTokenLocation&amp;, int, int functionKeywordStart, int functionNameStart, int parametersStart, ConstructorKind, SuperBinding, FunctionBodyType, unsigned, SourceParseMode);
</del><ins>+    template &lt;class TreeBuilder&gt; ALWAYS_INLINE TreeFunctionBody parseFunctionBody(TreeBuilder&amp;, SyntaxChecker&amp;, const JSTokenLocation&amp;, int, int functionKeywordStart, int functionNameStart, int parametersStart, ConstructorKind, SuperBinding, FunctionBodyType, unsigned, SourceParseMode);
</ins><span class="cx">     template &lt;class TreeBuilder&gt; ALWAYS_INLINE bool parseFormalParameters(TreeBuilder&amp;, TreeFormalParameterList, unsigned&amp;);
</span><span class="cx">     enum VarDeclarationListContext { ForLoopContext, VarDeclarationContext };
</span><span class="cx">     template &lt;class TreeBuilder&gt; TreeExpression parseVariableDeclarationList(TreeBuilder&amp;, int&amp; declarations, TreeDestructuringPattern&amp; lastPattern, TreeExpression&amp; lastInitializer, JSTextPosition&amp; identStart, JSTextPosition&amp; initStart, JSTextPosition&amp; initEnd, VarDeclarationListContext, DeclarationType, ExportType, bool&amp; forLoopConstDoesNotHaveInitializer);
</span><span class="lines">@@ -1415,7 +1436,7 @@
</span><span class="cx">     
</span><span class="cx">     ALWAYS_INLINE bool isArrowFunctionParameters();
</span><span class="cx">     
</span><del>-    template &lt;class TreeBuilder&gt; NEVER_INLINE int parseFunctionParameters(TreeBuilder&amp;, SourceParseMode, ParserFunctionInfo&lt;TreeBuilder&gt;&amp;);
</del><ins>+    template &lt;class TreeBuilder, class FunctionInfoType&gt; NEVER_INLINE typename TreeBuilder::FormalParameterList parseFunctionParameters(TreeBuilder&amp;, SourceParseMode, FunctionInfoType&amp;);
</ins><span class="cx">     template &lt;class TreeBuilder&gt; NEVER_INLINE typename TreeBuilder::FormalParameterList createGeneratorParameters(TreeBuilder&amp;);
</span><span class="cx"> 
</span><span class="cx">     template &lt;class TreeBuilder&gt; NEVER_INLINE TreeClassExpression parseClass(TreeBuilder&amp;, FunctionRequirements, ParserClassInfo&lt;TreeBuilder&gt;&amp;);
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreparserParserFunctionInfoh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/parser/ParserFunctionInfo.h (200037 => 200038)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/parser/ParserFunctionInfo.h        2016-04-25 18:38:56 UTC (rev 200037)
+++ trunk/Source/JavaScriptCore/parser/ParserFunctionInfo.h        2016-04-25 19:08:53 UTC (rev 200038)
</span><span class="lines">@@ -31,14 +31,13 @@
</span><span class="cx"> template &lt;class TreeBuilder&gt;
</span><span class="cx"> struct ParserFunctionInfo {
</span><span class="cx">     const Identifier* name = 0;
</span><del>-    typename TreeBuilder::FormalParameterList parameters = 0;
</del><span class="cx">     typename TreeBuilder::FunctionBody body = 0;
</span><span class="cx">     unsigned parameterCount = 0;
</span><span class="cx">     unsigned startOffset = 0;
</span><span class="cx">     unsigned endOffset = 0;
</span><span class="cx">     int startLine = 0;
</span><span class="cx">     int endLine = 0;
</span><del>-    unsigned bodyStartColumn = 0;
</del><ins>+    unsigned parametersStartColumn = 0;
</ins><span class="cx"> };
</span><span class="cx"> 
</span><span class="cx"> template &lt;class TreeBuilder&gt;
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreparserSourceProviderCacheItemh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/parser/SourceProviderCacheItem.h (200037 => 200038)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/parser/SourceProviderCacheItem.h        2016-04-25 18:38:56 UTC (rev 200037)
+++ trunk/Source/JavaScriptCore/parser/SourceProviderCacheItem.h        2016-04-25 19:08:53 UTC (rev 200038)
</span><span class="lines">@@ -35,10 +35,10 @@
</span><span class="cx"> 
</span><span class="cx"> struct SourceProviderCacheItemCreationParameters {
</span><span class="cx">     unsigned functionNameStart;
</span><del>-    unsigned lastTockenLine;
-    unsigned lastTockenStartOffset;
-    unsigned lastTockenEndOffset;
-    unsigned lastTockenLineStartOffset;
</del><ins>+    unsigned lastTokenLine;
+    unsigned lastTokenStartOffset;
+    unsigned lastTokenEndOffset;
+    unsigned lastTokenLineStartOffset;
</ins><span class="cx">     unsigned endFunctionOffset;
</span><span class="cx">     unsigned parameterCount;
</span><span class="cx">     bool needsFullActivation;
</span><span class="lines">@@ -48,6 +48,8 @@
</span><span class="cx">     Vector&lt;UniquedStringImpl*, 8&gt; usedVariables;
</span><span class="cx">     bool isBodyArrowExpression { false };
</span><span class="cx">     JSTokenType tokenType { CLOSEBRACE };
</span><ins>+    ConstructorKind constructorKind;
+    SuperBinding expectedSuperBinding;
</ins><span class="cx"> };
</span><span class="cx"> 
</span><span class="cx"> #if COMPILER(MSVC)
</span><span class="lines">@@ -65,11 +67,11 @@
</span><span class="cx">     {
</span><span class="cx">         JSToken token;
</span><span class="cx">         token.m_type = isBodyArrowExpression ? tokenType : CLOSEBRACE;
</span><del>-        token.m_data.offset = lastTockenStartOffset;
-        token.m_location.startOffset = lastTockenStartOffset;
-        token.m_location.endOffset = lastTockenEndOffset;
-        token.m_location.line = lastTockenLine;
-        token.m_location.lineStartOffset = lastTockenLineStartOffset;
</del><ins>+        token.m_data.offset = lastTokenStartOffset;
+        token.m_location.startOffset = lastTokenStartOffset;
+        token.m_location.endOffset = lastTokenEndOffset;
+        token.m_location.line = lastTokenLine;
+        token.m_location.lineStartOffset = lastTokenLineStartOffset;
</ins><span class="cx">         // token.m_location.sourceOffset is initialized once by the client. So,
</span><span class="cx">         // we do not need to set it here.
</span><span class="cx">         return token;
</span><span class="lines">@@ -77,26 +79,23 @@
</span><span class="cx"> 
</span><span class="cx">     unsigned functionNameStart : 31;
</span><span class="cx">     bool needsFullActivation : 1;
</span><del>-
</del><span class="cx">     unsigned endFunctionOffset : 31;
</span><del>-    unsigned lastTockenLine : 31;
-    unsigned lastTockenStartOffset : 31;
-    unsigned lastTockenEndOffset: 31;
-    unsigned parameterCount;
-    
</del><span class="cx">     bool usesEval : 1;
</span><del>-
</del><ins>+    unsigned lastTokenLine : 31;
</ins><span class="cx">     bool strictMode : 1;
</span><del>-    
</del><ins>+    unsigned lastTokenStartOffset : 31;
+    unsigned lastTokenEndOffset: 31;
+    unsigned constructorKind : 2; // ConstructorKind
+    unsigned parameterCount : 31;
+    unsigned expectedSuperBinding : 1; // SuperBinding
+    unsigned lastTokenLineStartOffset;
+    unsigned usedVariablesCount;
</ins><span class="cx">     InnerArrowFunctionCodeFeatures innerArrowFunctionFeatures;
</span><del>-
-    unsigned lastTockenLineStartOffset;
-    unsigned usedVariablesCount;
-
-    UniquedStringImpl** usedVariables() const { return const_cast&lt;UniquedStringImpl**&gt;(m_variables); }
</del><span class="cx">     bool isBodyArrowExpression;
</span><span class="cx">     JSTokenType tokenType;
</span><span class="cx"> 
</span><ins>+    UniquedStringImpl** usedVariables() const { return const_cast&lt;UniquedStringImpl**&gt;(m_variables); }
+
</ins><span class="cx"> private:
</span><span class="cx">     SourceProviderCacheItem(const SourceProviderCacheItemCreationParameters&amp;);
</span><span class="cx"> 
</span><span class="lines">@@ -121,15 +120,17 @@
</span><span class="cx">     : functionNameStart(parameters.functionNameStart)
</span><span class="cx">     , needsFullActivation(parameters.needsFullActivation)
</span><span class="cx">     , endFunctionOffset(parameters.endFunctionOffset)
</span><del>-    , lastTockenLine(parameters.lastTockenLine)
-    , lastTockenStartOffset(parameters.lastTockenStartOffset)
-    , lastTockenEndOffset(parameters.lastTockenEndOffset)
-    , parameterCount(parameters.parameterCount)
</del><span class="cx">     , usesEval(parameters.usesEval)
</span><ins>+    , lastTokenLine(parameters.lastTokenLine)
</ins><span class="cx">     , strictMode(parameters.strictMode)
</span><ins>+    , lastTokenStartOffset(parameters.lastTokenStartOffset)
+    , lastTokenEndOffset(parameters.lastTokenEndOffset)
+    , constructorKind(static_cast&lt;unsigned&gt;(parameters.constructorKind))
+    , parameterCount(parameters.parameterCount)
+    , expectedSuperBinding(static_cast&lt;unsigned&gt;(parameters.expectedSuperBinding))
+    , lastTokenLineStartOffset(parameters.lastTokenLineStartOffset)
+    , usedVariablesCount(parameters.usedVariables.size())
</ins><span class="cx">     , innerArrowFunctionFeatures(parameters.innerArrowFunctionFeatures)
</span><del>-    , lastTockenLineStartOffset(parameters.lastTockenLineStartOffset)
-    , usedVariablesCount(parameters.usedVariables.size())
</del><span class="cx">     , isBodyArrowExpression(parameters.isBodyArrowExpression)
</span><span class="cx">     , tokenType(parameters.tokenType)
</span><span class="cx"> {
</span></span></pre>
</div>
</div>

</body>
</html>