<!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>[197033] trunk</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/197033">197033</a></dd>
<dt>Author</dt> <dd>commit-queue@webkit.org</dd>
<dt>Date</dt> <dd>2016-02-24 09:36:12 -0800 (Wed, 24 Feb 2016)</dd>
</dl>

<h3>Log Message</h3>
<pre>[ES6] Arrow function syntax. Emit loading&amp;putting this/super only if they are used in arrow function
https://bugs.webkit.org/show_bug.cgi?id=153981

Patch by Skachkov Oleksandr &lt;gskachkov@gmail.com&gt; on 2016-02-24
Reviewed by Saam Barati.
Source/JavaScriptCore:

In first iteration of implemenation arrow function, we emit load and store variables 'this', 'arguments',
'super', 'new.target' in case if arrow function is exist even variables are not used in arrow function.
Current patch added logic that prevent from emiting those varibles if they are not used in arrow function.
During syntax analyze parser store information about using variables in arrow function inside of
the ordinary function scope and then put to BytecodeGenerator through UnlinkedCodeBlock

* bytecode/ExecutableInfo.h:
(JSC::ExecutableInfo::ExecutableInfo):
(JSC::ExecutableInfo::arrowFunctionCodeFeatures):
* bytecode/UnlinkedCodeBlock.cpp:
(JSC::UnlinkedCodeBlock::UnlinkedCodeBlock):
* bytecode/UnlinkedCodeBlock.h:
(JSC::UnlinkedCodeBlock::arrowFunctionCodeFeatures):
(JSC::UnlinkedCodeBlock::doAnyInnerArrowFunctionsUseArguments):
(JSC::UnlinkedCodeBlock::doAnyInnerArrowFunctionsUseSuperCall):
(JSC::UnlinkedCodeBlock::doAnyInnerArrowFunctionsUseSuperProperty):
(JSC::UnlinkedCodeBlock::doAnyInnerArrowFunctionsUseEval):
(JSC::UnlinkedCodeBlock::doAnyInnerArrowFunctionsUseThis):
(JSC::UnlinkedCodeBlock::doAnyInnerArrowFunctionsUseNewTarget):
* bytecode/UnlinkedFunctionExecutable.cpp:
(JSC::generateUnlinkedFunctionCodeBlock):
(JSC::UnlinkedFunctionExecutable::UnlinkedFunctionExecutable):
* bytecode/UnlinkedFunctionExecutable.h:
* bytecompiler/BytecodeGenerator.cpp:
(JSC::BytecodeGenerator::BytecodeGenerator):
(JSC::BytecodeGenerator::initializeArrowFunctionContextScopeIfNeeded):
(JSC::BytecodeGenerator::emitLoadArrowFunctionLexicalEnvironment):
(JSC::BytecodeGenerator::emitLoadThisFromArrowFunctionLexicalEnvironment):
(JSC::BytecodeGenerator::emitLoadNewTargetFromArrowFunctionLexicalEnvironment):
(JSC::BytecodeGenerator::emitLoadDerivedConstructorFromArrowFunctionLexicalEnvironment):
(JSC::BytecodeGenerator::isThisUsedInInnerArrowFunction):
(JSC::BytecodeGenerator::isArgumentsUsedInInnerArrowFunction):
(JSC::BytecodeGenerator::isNewTargetUsedInInnerArrowFunction):
(JSC::BytecodeGenerator::isSuperUsedInInnerArrowFunction):
(JSC::BytecodeGenerator::emitPutNewTargetToArrowFunctionContextScope):
(JSC::BytecodeGenerator::emitPutDerivedConstructorToArrowFunctionContextScope):
(JSC::BytecodeGenerator::emitPutThisToArrowFunctionContextScope):
* bytecompiler/BytecodeGenerator.h:
* bytecompiler/NodesCodegen.cpp:
(JSC::ThisNode::emitBytecode):
(JSC::EvalFunctionCallNode::emitBytecode):
(JSC::FunctionCallValueNode::emitBytecode):
(JSC::FunctionNode::emitBytecode):
* parser/ASTBuilder.h:
(JSC::ASTBuilder::createFunctionMetadata):
* parser/Nodes.cpp:
(JSC::FunctionMetadataNode::FunctionMetadataNode):
* parser/Nodes.h:
* parser/Parser.cpp:
(JSC::Parser&lt;LexerType&gt;::parseGeneratorFunctionSourceElements):
(JSC::Parser&lt;LexerType&gt;::parseFunctionBody):
(JSC::Parser&lt;LexerType&gt;::parseFunctionInfo):
(JSC::Parser&lt;LexerType&gt;::parseProperty):
(JSC::Parser&lt;LexerType&gt;::parsePrimaryExpression):
(JSC::Parser&lt;LexerType&gt;::parseMemberExpression):
* parser/Parser.h:
(JSC::Scope::Scope):
(JSC::Scope::isArrowFunctionBoundary):
(JSC::Scope::innerArrowFunctionFeatures):
(JSC::Scope::setInnerArrowFunctionUseSuperCall):
(JSC::Scope::setInnerArrowFunctionUseSuperProperty):
(JSC::Scope::setInnerArrowFunctionUseEval):
(JSC::Scope::setInnerArrowFunctionUseThis):
(JSC::Scope::setInnerArrowFunctionUseNewTarget):
(JSC::Scope::setInnerArrowFunctionUseArguments):
(JSC::Scope::setInnerArrowFunctionUseEvalAndUseArgumentsIfNeeded):
(JSC::Scope::collectFreeVariables):
(JSC::Scope::mergeInnerArrowFunctionFeatures):
(JSC::Scope::fillParametersForSourceProviderCache):
(JSC::Scope::restoreFromSourceProviderCache):
(JSC::Scope::setIsFunction):
(JSC::Scope::setIsArrowFunction):
(JSC::Parser::closestParentNonArrowFunctionNonLexicalScope):
(JSC::Parser::pushScope):
(JSC::Parser::popScopeInternal):
* parser/ParserModes.h:
* parser/SourceProviderCacheItem.h:
(JSC::SourceProviderCacheItem::SourceProviderCacheItem):
* parser/SyntaxChecker.h:
(JSC::SyntaxChecker::createFunctionMetadata):
* tests/stress/arrowfunction-lexical-bind-arguments-non-strict-1.js:
* tests/stress/arrowfunction-lexical-bind-arguments-strict.js:
* tests/stress/arrowfunction-lexical-bind-newtarget.js:
* tests/stress/arrowfunction-lexical-bind-superproperty.js:
* tests/stress/arrowfunction-lexical-bind-this-8.js: Added.

LayoutTests:

Added new benchmark tests for invoking arrow function within function, class's constructor and method

* js/regress/arrowfunction-call-in-class-constructor-expected.txt: Added.
* js/regress/arrowfunction-call-in-class-constructor.html: Added.
* js/regress/arrowfunction-call-in-class-method-expected.txt: Added.
* js/regress/arrowfunction-call-in-class-method.html: Added.
* js/regress/arrowfunction-call-in-function-expected.txt: Added.
* js/regress/arrowfunction-call-in-function.html: Added.
* js/regress/script-tests/arrowfunction-call-in-class-constructor.js: Added.
* js/regress/script-tests/arrowfunction-call-in-class-method.js: Added.
* js/regress/script-tests/arrowfunction-call-in-function.js: Added.
* js/regress/script-tests/arrowfunction-call.js:</pre>

<h3>Modified Paths</h3>
<ul>
<li><a href="#trunkLayoutTestsChangeLog">trunk/LayoutTests/ChangeLog</a></li>
<li><a href="#trunkLayoutTestsjsregressscripttestsarrowfunctioncalljs">trunk/LayoutTests/js/regress/script-tests/arrowfunction-call.js</a></li>
<li><a href="#trunkSourceJavaScriptCoreChangeLog">trunk/Source/JavaScriptCore/ChangeLog</a></li>
<li><a href="#trunkSourceJavaScriptCorebytecodeExecutableInfoh">trunk/Source/JavaScriptCore/bytecode/ExecutableInfo.h</a></li>
<li><a href="#trunkSourceJavaScriptCorebytecodeUnlinkedCodeBlockcpp">trunk/Source/JavaScriptCore/bytecode/UnlinkedCodeBlock.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCorebytecodeUnlinkedCodeBlockh">trunk/Source/JavaScriptCore/bytecode/UnlinkedCodeBlock.h</a></li>
<li><a href="#trunkSourceJavaScriptCorebytecodeUnlinkedFunctionExecutablecpp">trunk/Source/JavaScriptCore/bytecode/UnlinkedFunctionExecutable.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCorebytecodeUnlinkedFunctionExecutableh">trunk/Source/JavaScriptCore/bytecode/UnlinkedFunctionExecutable.h</a></li>
<li><a href="#trunkSourceJavaScriptCorebytecompilerBytecodeGeneratorcpp">trunk/Source/JavaScriptCore/bytecompiler/BytecodeGenerator.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCorebytecompilerBytecodeGeneratorh">trunk/Source/JavaScriptCore/bytecompiler/BytecodeGenerator.h</a></li>
<li><a href="#trunkSourceJavaScriptCorebytecompilerNodesCodegencpp">trunk/Source/JavaScriptCore/bytecompiler/NodesCodegen.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoreparserASTBuilderh">trunk/Source/JavaScriptCore/parser/ASTBuilder.h</a></li>
<li><a href="#trunkSourceJavaScriptCoreparserNodescpp">trunk/Source/JavaScriptCore/parser/Nodes.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoreparserNodesh">trunk/Source/JavaScriptCore/parser/Nodes.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="#trunkSourceJavaScriptCoreparserParserModesh">trunk/Source/JavaScriptCore/parser/ParserModes.h</a></li>
<li><a href="#trunkSourceJavaScriptCoreparserSourceProviderCacheItemh">trunk/Source/JavaScriptCore/parser/SourceProviderCacheItem.h</a></li>
<li><a href="#trunkSourceJavaScriptCoreparserSyntaxCheckerh">trunk/Source/JavaScriptCore/parser/SyntaxChecker.h</a></li>
<li><a href="#trunkSourceJavaScriptCoretestsstressarrowfunctionlexicalbindargumentsnonstrict1js">trunk/Source/JavaScriptCore/tests/stress/arrowfunction-lexical-bind-arguments-non-strict-1.js</a></li>
<li><a href="#trunkSourceJavaScriptCoretestsstressarrowfunctionlexicalbindargumentsstrictjs">trunk/Source/JavaScriptCore/tests/stress/arrowfunction-lexical-bind-arguments-strict.js</a></li>
<li><a href="#trunkSourceJavaScriptCoretestsstressarrowfunctionlexicalbindnewtargetjs">trunk/Source/JavaScriptCore/tests/stress/arrowfunction-lexical-bind-newtarget.js</a></li>
<li><a href="#trunkSourceJavaScriptCoretestsstressarrowfunctionlexicalbindsuperpropertyjs">trunk/Source/JavaScriptCore/tests/stress/arrowfunction-lexical-bind-superproperty.js</a></li>
</ul>

<h3>Added Paths</h3>
<ul>
<li><a href="#trunkLayoutTestsjsregressarrowfunctioncallinclassconstructorexpectedtxt">trunk/LayoutTests/js/regress/arrowfunction-call-in-class-constructor-expected.txt</a></li>
<li><a href="#trunkLayoutTestsjsregressarrowfunctioncallinclassconstructorhtml">trunk/LayoutTests/js/regress/arrowfunction-call-in-class-constructor.html</a></li>
<li><a href="#trunkLayoutTestsjsregressarrowfunctioncallinclassmethodexpectedtxt">trunk/LayoutTests/js/regress/arrowfunction-call-in-class-method-expected.txt</a></li>
<li><a href="#trunkLayoutTestsjsregressarrowfunctioncallinclassmethodhtml">trunk/LayoutTests/js/regress/arrowfunction-call-in-class-method.html</a></li>
<li><a href="#trunkLayoutTestsjsregressarrowfunctioncallinfunctionexpectedtxt">trunk/LayoutTests/js/regress/arrowfunction-call-in-function-expected.txt</a></li>
<li><a href="#trunkLayoutTestsjsregressarrowfunctioncallinfunctionhtml">trunk/LayoutTests/js/regress/arrowfunction-call-in-function.html</a></li>
<li><a href="#trunkLayoutTestsjsregressscripttestsarrowfunctioncallinclassconstructorjs">trunk/LayoutTests/js/regress/script-tests/arrowfunction-call-in-class-constructor.js</a></li>
<li><a href="#trunkLayoutTestsjsregressscripttestsarrowfunctioncallinclassmethodjs">trunk/LayoutTests/js/regress/script-tests/arrowfunction-call-in-class-method.js</a></li>
<li><a href="#trunkLayoutTestsjsregressscripttestsarrowfunctioncallinfunctionjs">trunk/LayoutTests/js/regress/script-tests/arrowfunction-call-in-function.js</a></li>
<li><a href="#trunkSourceJavaScriptCoretestsstressarrowfunctionlexicalbindthis8js">trunk/Source/JavaScriptCore/tests/stress/arrowfunction-lexical-bind-this-8.js</a></li>
</ul>

</div>
<div id="patch">
<h3>Diff</h3>
<a id="trunkLayoutTestsChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/LayoutTests/ChangeLog (197032 => 197033)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/ChangeLog        2016-02-24 17:26:52 UTC (rev 197032)
+++ trunk/LayoutTests/ChangeLog        2016-02-24 17:36:12 UTC (rev 197033)
</span><span class="lines">@@ -1,3 +1,23 @@
</span><ins>+2016-02-24  Skachkov Oleksandr  &lt;gskachkov@gmail.com&gt;
+
+        [ES6] Arrow function syntax. Emit loading&amp;putting this/super only if they are used in arrow function
+        https://bugs.webkit.org/show_bug.cgi?id=153981
+
+        Reviewed by Saam Barati.
+
+        Added new benchmark tests for invoking arrow function within function, class's constructor and method
+
+        * js/regress/arrowfunction-call-in-class-constructor-expected.txt: Added.
+        * js/regress/arrowfunction-call-in-class-constructor.html: Added.
+        * js/regress/arrowfunction-call-in-class-method-expected.txt: Added.
+        * js/regress/arrowfunction-call-in-class-method.html: Added.
+        * js/regress/arrowfunction-call-in-function-expected.txt: Added.
+        * js/regress/arrowfunction-call-in-function.html: Added.
+        * js/regress/script-tests/arrowfunction-call-in-class-constructor.js: Added.
+        * js/regress/script-tests/arrowfunction-call-in-class-method.js: Added.
+        * js/regress/script-tests/arrowfunction-call-in-function.js: Added.
+        * js/regress/script-tests/arrowfunction-call.js:
+
</ins><span class="cx"> 2016-02-24  Zalan Bujtas  &lt;zalan@apple.com&gt;
</span><span class="cx"> 
</span><span class="cx">         Background of an absolutely positioned inline element inside text-indented parent is positioned statically.
</span></span></pre></div>
<a id="trunkLayoutTestsjsregressarrowfunctioncallinclassconstructorexpectedtxt"></a>
<div class="addfile"><h4>Added: trunk/LayoutTests/js/regress/arrowfunction-call-in-class-constructor-expected.txt (0 => 197033)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/js/regress/arrowfunction-call-in-class-constructor-expected.txt                                (rev 0)
+++ trunk/LayoutTests/js/regress/arrowfunction-call-in-class-constructor-expected.txt        2016-02-24 17:36:12 UTC (rev 197033)
</span><span class="lines">@@ -0,0 +1,10 @@
</span><ins>+JSRegress/arrowfunction-call-in-class-constructor
+
+On success, you will see a series of &quot;PASS&quot; messages, followed by &quot;TEST COMPLETE&quot;.
+
+
+PASS no exception thrown
+PASS successfullyParsed is true
+
+TEST COMPLETE
+
</ins></span></pre></div>
<a id="trunkLayoutTestsjsregressarrowfunctioncallinclassconstructorhtml"></a>
<div class="addfile"><h4>Added: trunk/LayoutTests/js/regress/arrowfunction-call-in-class-constructor.html (0 => 197033)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/js/regress/arrowfunction-call-in-class-constructor.html                                (rev 0)
+++ trunk/LayoutTests/js/regress/arrowfunction-call-in-class-constructor.html        2016-02-24 17:36:12 UTC (rev 197033)
</span><span class="lines">@@ -0,0 +1,12 @@
</span><ins>+&lt;!DOCTYPE HTML PUBLIC &quot;-//IETF//DTD HTML//EN&quot;&gt;
+&lt;html&gt;
+&lt;head&gt;
+&lt;script src=&quot;../../resources/js-test-pre.js&quot;&gt;&lt;/script&gt;
+&lt;/head&gt;
+&lt;body&gt;
+&lt;script src=&quot;../../resources/regress-pre.js&quot;&gt;&lt;/script&gt;
+&lt;script src=&quot;script-tests/arrowfunction-call-in-class-constructor.js&quot;&gt;&lt;/script&gt;
+&lt;script src=&quot;../../resources/regress-post.js&quot;&gt;&lt;/script&gt;
+&lt;script src=&quot;../../resources/js-test-post.js&quot;&gt;&lt;/script&gt;
+&lt;/body&gt;
+&lt;/html&gt;
</ins></span></pre></div>
<a id="trunkLayoutTestsjsregressarrowfunctioncallinclassmethodexpectedtxt"></a>
<div class="addfile"><h4>Added: trunk/LayoutTests/js/regress/arrowfunction-call-in-class-method-expected.txt (0 => 197033)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/js/regress/arrowfunction-call-in-class-method-expected.txt                                (rev 0)
+++ trunk/LayoutTests/js/regress/arrowfunction-call-in-class-method-expected.txt        2016-02-24 17:36:12 UTC (rev 197033)
</span><span class="lines">@@ -0,0 +1,10 @@
</span><ins>+JSRegress/arrowfunction-call-in-class-method
+
+On success, you will see a series of &quot;PASS&quot; messages, followed by &quot;TEST COMPLETE&quot;.
+
+
+PASS no exception thrown
+PASS successfullyParsed is true
+
+TEST COMPLETE
+
</ins></span></pre></div>
<a id="trunkLayoutTestsjsregressarrowfunctioncallinclassmethodhtml"></a>
<div class="addfile"><h4>Added: trunk/LayoutTests/js/regress/arrowfunction-call-in-class-method.html (0 => 197033)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/js/regress/arrowfunction-call-in-class-method.html                                (rev 0)
+++ trunk/LayoutTests/js/regress/arrowfunction-call-in-class-method.html        2016-02-24 17:36:12 UTC (rev 197033)
</span><span class="lines">@@ -0,0 +1,12 @@
</span><ins>+&lt;!DOCTYPE HTML PUBLIC &quot;-//IETF//DTD HTML//EN&quot;&gt;
+&lt;html&gt;
+&lt;head&gt;
+&lt;script src=&quot;../../resources/js-test-pre.js&quot;&gt;&lt;/script&gt;
+&lt;/head&gt;
+&lt;body&gt;
+&lt;script src=&quot;../../resources/regress-pre.js&quot;&gt;&lt;/script&gt;
+&lt;script src=&quot;script-tests/arrowfunction-call-in-class-method.js&quot;&gt;&lt;/script&gt;
+&lt;script src=&quot;../../resources/regress-post.js&quot;&gt;&lt;/script&gt;
+&lt;script src=&quot;../../resources/js-test-post.js&quot;&gt;&lt;/script&gt;
+&lt;/body&gt;
+&lt;/html&gt;
</ins></span></pre></div>
<a id="trunkLayoutTestsjsregressarrowfunctioncallinfunctionexpectedtxt"></a>
<div class="addfile"><h4>Added: trunk/LayoutTests/js/regress/arrowfunction-call-in-function-expected.txt (0 => 197033)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/js/regress/arrowfunction-call-in-function-expected.txt                                (rev 0)
+++ trunk/LayoutTests/js/regress/arrowfunction-call-in-function-expected.txt        2016-02-24 17:36:12 UTC (rev 197033)
</span><span class="lines">@@ -0,0 +1,10 @@
</span><ins>+JSRegress/arrowfunction-call-in-function
+
+On success, you will see a series of &quot;PASS&quot; messages, followed by &quot;TEST COMPLETE&quot;.
+
+
+PASS no exception thrown
+PASS successfullyParsed is true
+
+TEST COMPLETE
+
</ins></span></pre></div>
<a id="trunkLayoutTestsjsregressarrowfunctioncallinfunctionhtml"></a>
<div class="addfile"><h4>Added: trunk/LayoutTests/js/regress/arrowfunction-call-in-function.html (0 => 197033)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/js/regress/arrowfunction-call-in-function.html                                (rev 0)
+++ trunk/LayoutTests/js/regress/arrowfunction-call-in-function.html        2016-02-24 17:36:12 UTC (rev 197033)
</span><span class="lines">@@ -0,0 +1,12 @@
</span><ins>+&lt;!DOCTYPE HTML PUBLIC &quot;-//IETF//DTD HTML//EN&quot;&gt;
+&lt;html&gt;
+&lt;head&gt;
+&lt;script src=&quot;../../resources/js-test-pre.js&quot;&gt;&lt;/script&gt;
+&lt;/head&gt;
+&lt;body&gt;
+&lt;script src=&quot;../../resources/regress-pre.js&quot;&gt;&lt;/script&gt;
+&lt;script src=&quot;script-tests/arrowfunction-call-in-function.js&quot;&gt;&lt;/script&gt;
+&lt;script src=&quot;../../resources/regress-post.js&quot;&gt;&lt;/script&gt;
+&lt;script src=&quot;../../resources/js-test-post.js&quot;&gt;&lt;/script&gt;
+&lt;/body&gt;
+&lt;/html&gt;
</ins></span></pre></div>
<a id="trunkLayoutTestsjsregressscripttestsarrowfunctioncallinclassconstructorjs"></a>
<div class="addfile"><h4>Added: trunk/LayoutTests/js/regress/script-tests/arrowfunction-call-in-class-constructor.js (0 => 197033)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/js/regress/script-tests/arrowfunction-call-in-class-constructor.js                                (rev 0)
+++ trunk/LayoutTests/js/regress/script-tests/arrowfunction-call-in-class-constructor.js        2016-02-24 17:36:12 UTC (rev 197033)
</span><span class="lines">@@ -0,0 +1,23 @@
</span><ins>+var testValue  = 'test-value';
+
+class A {
+    constructor() {
+        this.value = testValue;
+    }
+}
+
+class B extends A {
+    constructor() {
+        super();
+        var arrow  = () =&gt; testValue;
+        arrow();
+    }
+}
+
+noInline(B);
+
+for (let i = 0; i &lt; 1000000; ++i) {
+    let b = new B();
+    if (b.value != testValue)
+        throw &quot;Error: bad result: &quot; + result;
+}
</ins></span></pre></div>
<a id="trunkLayoutTestsjsregressscripttestsarrowfunctioncallinclassmethodjs"></a>
<div class="addfile"><h4>Added: trunk/LayoutTests/js/regress/script-tests/arrowfunction-call-in-class-method.js (0 => 197033)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/js/regress/script-tests/arrowfunction-call-in-class-method.js                                (rev 0)
+++ trunk/LayoutTests/js/regress/script-tests/arrowfunction-call-in-class-method.js        2016-02-24 17:36:12 UTC (rev 197033)
</span><span class="lines">@@ -0,0 +1,24 @@
</span><ins>+var testValue  = 'test-value';
+
+class A {
+    constructor() {
+        this.value = testValue;
+    }
+
+    getValue () {
+        return this.value;
+    }
+}
+
+class B extends A {
+    getParentValue() {
+        var arrow  = () =&gt; testValue;
+        return arrow();
+    }
+}
+
+for (let i = 0; i &lt; 100000; ++i) {
+    let b = new B();
+    if (b.getParentValue() != testValue)
+        throw &quot;Error: bad result: &quot; + result;
+}
</ins></span></pre></div>
<a id="trunkLayoutTestsjsregressscripttestsarrowfunctioncallinfunctionjs"></a>
<div class="addfile"><h4>Added: trunk/LayoutTests/js/regress/script-tests/arrowfunction-call-in-function.js (0 => 197033)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/js/regress/script-tests/arrowfunction-call-in-function.js                                (rev 0)
+++ trunk/LayoutTests/js/regress/script-tests/arrowfunction-call-in-function.js        2016-02-24 17:36:12 UTC (rev 197033)
</span><span class="lines">@@ -0,0 +1,11 @@
</span><ins>+function bar(a, b) {
+    return ((_a, _b) =&gt; _a + _b)(a, b);
+}
+
+noInline(bar);
+
+for (let i = 0; i &lt; 1000000; ++i) {
+    let result = bar(1, 2);
+    if (result != 3)
+        throw &quot;Error: bad result: &quot; + result;
+}
</ins></span></pre></div>
<a id="trunkLayoutTestsjsregressscripttestsarrowfunctioncalljs"></a>
<div class="modfile"><h4>Modified: trunk/LayoutTests/js/regress/script-tests/arrowfunction-call.js (197032 => 197033)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/js/regress/script-tests/arrowfunction-call.js        2016-02-24 17:26:52 UTC (rev 197032)
+++ trunk/LayoutTests/js/regress/script-tests/arrowfunction-call.js        2016-02-24 17:36:12 UTC (rev 197033)
</span><span class="lines">@@ -8,8 +8,8 @@
</span><span class="cx"> 
</span><span class="cx"> noInline(bar);
</span><span class="cx"> 
</span><del>-for (var i = 0; i &lt; 1000000; ++i) {
-    var result = bar(1, 2);
</del><ins>+for (let i = 0; i &lt; 1000000; ++i) {
+    let result = bar(1, 2);
</ins><span class="cx">     if (result != 3)
</span><span class="cx">         throw &quot;Error: bad result: &quot; + result;
</span><span class="cx"> }
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/ChangeLog (197032 => 197033)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/ChangeLog        2016-02-24 17:26:52 UTC (rev 197032)
+++ trunk/Source/JavaScriptCore/ChangeLog        2016-02-24 17:36:12 UTC (rev 197033)
</span><span class="lines">@@ -1,3 +1,96 @@
</span><ins>+2016-02-24  Skachkov Oleksandr  &lt;gskachkov@gmail.com&gt;
+
+        [ES6] Arrow function syntax. Emit loading&amp;putting this/super only if they are used in arrow function
+        https://bugs.webkit.org/show_bug.cgi?id=153981
+
+        Reviewed by Saam Barati.
+       
+        In first iteration of implemenation arrow function, we emit load and store variables 'this', 'arguments',
+        'super', 'new.target' in case if arrow function is exist even variables are not used in arrow function. 
+        Current patch added logic that prevent from emiting those varibles if they are not used in arrow function.
+        During syntax analyze parser store information about using variables in arrow function inside of 
+        the ordinary function scope and then put to BytecodeGenerator through UnlinkedCodeBlock
+
+        * bytecode/ExecutableInfo.h:
+        (JSC::ExecutableInfo::ExecutableInfo):
+        (JSC::ExecutableInfo::arrowFunctionCodeFeatures):
+        * bytecode/UnlinkedCodeBlock.cpp:
+        (JSC::UnlinkedCodeBlock::UnlinkedCodeBlock):
+        * bytecode/UnlinkedCodeBlock.h:
+        (JSC::UnlinkedCodeBlock::arrowFunctionCodeFeatures):
+        (JSC::UnlinkedCodeBlock::doAnyInnerArrowFunctionsUseArguments):
+        (JSC::UnlinkedCodeBlock::doAnyInnerArrowFunctionsUseSuperCall):
+        (JSC::UnlinkedCodeBlock::doAnyInnerArrowFunctionsUseSuperProperty):
+        (JSC::UnlinkedCodeBlock::doAnyInnerArrowFunctionsUseEval):
+        (JSC::UnlinkedCodeBlock::doAnyInnerArrowFunctionsUseThis):
+        (JSC::UnlinkedCodeBlock::doAnyInnerArrowFunctionsUseNewTarget):
+        * bytecode/UnlinkedFunctionExecutable.cpp:
+        (JSC::generateUnlinkedFunctionCodeBlock):
+        (JSC::UnlinkedFunctionExecutable::UnlinkedFunctionExecutable):
+        * bytecode/UnlinkedFunctionExecutable.h:
+        * bytecompiler/BytecodeGenerator.cpp:
+        (JSC::BytecodeGenerator::BytecodeGenerator):
+        (JSC::BytecodeGenerator::initializeArrowFunctionContextScopeIfNeeded):
+        (JSC::BytecodeGenerator::emitLoadArrowFunctionLexicalEnvironment):
+        (JSC::BytecodeGenerator::emitLoadThisFromArrowFunctionLexicalEnvironment):
+        (JSC::BytecodeGenerator::emitLoadNewTargetFromArrowFunctionLexicalEnvironment):
+        (JSC::BytecodeGenerator::emitLoadDerivedConstructorFromArrowFunctionLexicalEnvironment):
+        (JSC::BytecodeGenerator::isThisUsedInInnerArrowFunction):
+        (JSC::BytecodeGenerator::isArgumentsUsedInInnerArrowFunction):
+        (JSC::BytecodeGenerator::isNewTargetUsedInInnerArrowFunction):
+        (JSC::BytecodeGenerator::isSuperUsedInInnerArrowFunction):
+        (JSC::BytecodeGenerator::emitPutNewTargetToArrowFunctionContextScope):
+        (JSC::BytecodeGenerator::emitPutDerivedConstructorToArrowFunctionContextScope):
+        (JSC::BytecodeGenerator::emitPutThisToArrowFunctionContextScope):
+        * bytecompiler/BytecodeGenerator.h:
+        * bytecompiler/NodesCodegen.cpp:
+        (JSC::ThisNode::emitBytecode):
+        (JSC::EvalFunctionCallNode::emitBytecode):
+        (JSC::FunctionCallValueNode::emitBytecode):
+        (JSC::FunctionNode::emitBytecode):
+        * parser/ASTBuilder.h:
+        (JSC::ASTBuilder::createFunctionMetadata):
+        * parser/Nodes.cpp:
+        (JSC::FunctionMetadataNode::FunctionMetadataNode):
+        * parser/Nodes.h:
+        * parser/Parser.cpp:
+        (JSC::Parser&lt;LexerType&gt;::parseGeneratorFunctionSourceElements):
+        (JSC::Parser&lt;LexerType&gt;::parseFunctionBody):
+        (JSC::Parser&lt;LexerType&gt;::parseFunctionInfo):
+        (JSC::Parser&lt;LexerType&gt;::parseProperty):
+        (JSC::Parser&lt;LexerType&gt;::parsePrimaryExpression):
+        (JSC::Parser&lt;LexerType&gt;::parseMemberExpression):
+        * parser/Parser.h:
+        (JSC::Scope::Scope):
+        (JSC::Scope::isArrowFunctionBoundary):
+        (JSC::Scope::innerArrowFunctionFeatures):
+        (JSC::Scope::setInnerArrowFunctionUseSuperCall):
+        (JSC::Scope::setInnerArrowFunctionUseSuperProperty):
+        (JSC::Scope::setInnerArrowFunctionUseEval):
+        (JSC::Scope::setInnerArrowFunctionUseThis):
+        (JSC::Scope::setInnerArrowFunctionUseNewTarget):
+        (JSC::Scope::setInnerArrowFunctionUseArguments):
+        (JSC::Scope::setInnerArrowFunctionUseEvalAndUseArgumentsIfNeeded):
+        (JSC::Scope::collectFreeVariables):
+        (JSC::Scope::mergeInnerArrowFunctionFeatures):
+        (JSC::Scope::fillParametersForSourceProviderCache):
+        (JSC::Scope::restoreFromSourceProviderCache):
+        (JSC::Scope::setIsFunction):
+        (JSC::Scope::setIsArrowFunction):
+        (JSC::Parser::closestParentNonArrowFunctionNonLexicalScope):
+        (JSC::Parser::pushScope):
+        (JSC::Parser::popScopeInternal):
+        * parser/ParserModes.h:
+        * parser/SourceProviderCacheItem.h:
+        (JSC::SourceProviderCacheItem::SourceProviderCacheItem):
+        * parser/SyntaxChecker.h:
+        (JSC::SyntaxChecker::createFunctionMetadata):
+        * tests/stress/arrowfunction-lexical-bind-arguments-non-strict-1.js:
+        * tests/stress/arrowfunction-lexical-bind-arguments-strict.js:
+        * tests/stress/arrowfunction-lexical-bind-newtarget.js:
+        * tests/stress/arrowfunction-lexical-bind-superproperty.js:
+        * tests/stress/arrowfunction-lexical-bind-this-8.js: Added.
+
</ins><span class="cx"> 2016-02-23  Brian Burg  &lt;bburg@apple.com&gt;
</span><span class="cx"> 
</span><span class="cx">         Web Inspector: teach the Objective-C protocol generators about --frontend and --backend directives
</span></span></pre></div>
<a id="trunkSourceJavaScriptCorebytecodeExecutableInfoh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/bytecode/ExecutableInfo.h (197032 => 197033)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/bytecode/ExecutableInfo.h        2016-02-24 17:26:52 UTC (rev 197032)
+++ trunk/Source/JavaScriptCore/bytecode/ExecutableInfo.h        2016-02-24 17:36:12 UTC (rev 197033)
</span><span class="lines">@@ -35,7 +35,7 @@
</span><span class="cx"> // FIXME: These flags, ParserModes and propagation to XXXCodeBlocks should be reorganized.
</span><span class="cx"> // https://bugs.webkit.org/show_bug.cgi?id=151547
</span><span class="cx"> struct ExecutableInfo {
</span><del>-    ExecutableInfo(bool usesEval, bool isStrictMode, bool isConstructor, bool isBuiltinFunction, ConstructorKind constructorKind, SuperBinding superBinding, SourceParseMode parseMode, DerivedContextType derivedContextType, bool isArrowFunctionContext, bool isClassContext)
</del><ins>+    ExecutableInfo(bool usesEval, bool isStrictMode, bool isConstructor, bool isBuiltinFunction, ConstructorKind constructorKind, SuperBinding superBinding, SourceParseMode parseMode, DerivedContextType derivedContextType, bool isArrowFunctionContext, bool isClassContext, ArrowFunctionCodeFeatures arrowFunctionCodeFeatures = NoArrowFunctionFeatures)
</ins><span class="cx">         : m_usesEval(usesEval)
</span><span class="cx">         , m_isStrictMode(isStrictMode)
</span><span class="cx">         , m_isConstructor(isConstructor)
</span><span class="lines">@@ -46,6 +46,7 @@
</span><span class="cx">         , m_derivedContextType(static_cast&lt;unsigned&gt;(derivedContextType))
</span><span class="cx">         , m_isArrowFunctionContext(isArrowFunctionContext)
</span><span class="cx">         , m_isClassContext(isClassContext)
</span><ins>+        , m_arrowFunctionCodeFeatures(arrowFunctionCodeFeatures)
</ins><span class="cx">     {
</span><span class="cx">         ASSERT(m_constructorKind == static_cast&lt;unsigned&gt;(constructorKind));
</span><span class="cx">         ASSERT(m_superBinding == static_cast&lt;unsigned&gt;(superBinding));
</span><span class="lines">@@ -61,6 +62,7 @@
</span><span class="cx">     DerivedContextType derivedContextType() const { return static_cast&lt;DerivedContextType&gt;(m_derivedContextType); }
</span><span class="cx">     bool isArrowFunctionContext() const { return m_isArrowFunctionContext; }
</span><span class="cx">     bool isClassContext() const { return m_isClassContext; }
</span><ins>+    ArrowFunctionCodeFeatures arrowFunctionCodeFeatures() const { return m_arrowFunctionCodeFeatures; }
</ins><span class="cx"> 
</span><span class="cx"> private:
</span><span class="cx">     unsigned m_usesEval : 1;
</span><span class="lines">@@ -73,6 +75,7 @@
</span><span class="cx">     unsigned m_derivedContextType : 2;
</span><span class="cx">     unsigned m_isArrowFunctionContext : 1;
</span><span class="cx">     unsigned m_isClassContext : 1;
</span><ins>+    ArrowFunctionCodeFeatures m_arrowFunctionCodeFeatures;
</ins><span class="cx"> };
</span><span class="cx"> 
</span><span class="cx"> } // namespace JSC
</span></span></pre></div>
<a id="trunkSourceJavaScriptCorebytecodeUnlinkedCodeBlockcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/bytecode/UnlinkedCodeBlock.cpp (197032 => 197033)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/bytecode/UnlinkedCodeBlock.cpp        2016-02-24 17:26:52 UTC (rev 197032)
+++ trunk/Source/JavaScriptCore/bytecode/UnlinkedCodeBlock.cpp        2016-02-24 17:36:12 UTC (rev 197033)
</span><span class="lines">@@ -71,6 +71,7 @@
</span><span class="cx">     , m_firstLine(0)
</span><span class="cx">     , m_lineCount(0)
</span><span class="cx">     , m_endColumn(UINT_MAX)
</span><ins>+    , m_arrowFunctionCodeFeatures(info.arrowFunctionCodeFeatures())
</ins><span class="cx">     , m_parseMode(info.parseMode())
</span><span class="cx">     , m_features(0)
</span><span class="cx">     , m_codeType(codeType)
</span></span></pre></div>
<a id="trunkSourceJavaScriptCorebytecodeUnlinkedCodeBlockh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/bytecode/UnlinkedCodeBlock.h (197032 => 197033)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/bytecode/UnlinkedCodeBlock.h        2016-02-24 17:26:52 UTC (rev 197032)
+++ trunk/Source/JavaScriptCore/bytecode/UnlinkedCodeBlock.h        2016-02-24 17:36:12 UTC (rev 197033)
</span><span class="lines">@@ -122,6 +122,14 @@
</span><span class="cx">     DerivedContextType derivedContextType() const { return static_cast&lt;DerivedContextType&gt;(m_derivedContextType); }
</span><span class="cx">     bool isArrowFunctionContext() const { return m_isArrowFunctionContext; }
</span><span class="cx">     bool isClassContext() const { return m_isClassContext; }
</span><ins>+    ArrowFunctionCodeFeatures arrowFunctionCodeFeatures() const { return m_arrowFunctionCodeFeatures; }
+    
+    bool doAnyInnerArrowFunctionsUseArguments() { return m_arrowFunctionCodeFeatures &amp; ArgumentsArrowFunctionFeature; }
+    bool doAnyInnerArrowFunctionsUseSuperCall() { return m_arrowFunctionCodeFeatures &amp; SuperCallArrowFunctionFeature; }
+    bool doAnyInnerArrowFunctionsUseSuperProperty() { return m_arrowFunctionCodeFeatures &amp; SuperPropertyArrowFunctionFeature; }
+    bool doAnyInnerArrowFunctionsUseEval() { return m_arrowFunctionCodeFeatures &amp; EvalArrowFunctionFeature; }
+    bool doAnyInnerArrowFunctionsUseThis() { return m_arrowFunctionCodeFeatures &amp; ThisArrowFunctionFeature; }
+    bool doAnyInnerArrowFunctionsUseNewTarget() { return m_arrowFunctionCodeFeatures &amp; NewTargetArrowFunctionFeature; }
</ins><span class="cx"> 
</span><span class="cx">     void addExpressionInfo(unsigned instructionOffset, int divot,
</span><span class="cx">         int startOffset, int endOffset, unsigned line, unsigned column);
</span><span class="lines">@@ -391,7 +399,8 @@
</span><span class="cx">     unsigned m_firstLine;
</span><span class="cx">     unsigned m_lineCount;
</span><span class="cx">     unsigned m_endColumn;
</span><del>-
</del><ins>+    
+    ArrowFunctionCodeFeatures m_arrowFunctionCodeFeatures;
</ins><span class="cx">     SourceParseMode m_parseMode;
</span><span class="cx">     CodeFeatures m_features;
</span><span class="cx">     CodeType m_codeType;
</span></span></pre></div>
<a id="trunkSourceJavaScriptCorebytecodeUnlinkedFunctionExecutablecpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/bytecode/UnlinkedFunctionExecutable.cpp (197032 => 197033)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/bytecode/UnlinkedFunctionExecutable.cpp        2016-02-24 17:26:52 UTC (rev 197032)
+++ trunk/Source/JavaScriptCore/bytecode/UnlinkedFunctionExecutable.cpp        2016-02-24 17:36:12 UTC (rev 197033)
</span><span class="lines">@@ -69,7 +69,7 @@
</span><span class="cx">     bool isClassContext = executable-&gt;superBinding() == SuperBinding::Needed;
</span><span class="cx"> 
</span><span class="cx">     UnlinkedFunctionCodeBlock* result = UnlinkedFunctionCodeBlock::create(&amp;vm, FunctionCode,
</span><del>-        ExecutableInfo(function-&gt;usesEval(), function-&gt;isStrictMode(), kind == CodeForConstruct, functionKind == UnlinkedBuiltinFunction, executable-&gt;constructorKind(), executable-&gt;superBinding(), parseMode, executable-&gt;derivedContextType(), false, isClassContext));
</del><ins>+        ExecutableInfo(function-&gt;usesEval(), function-&gt;isStrictMode(), kind == CodeForConstruct, functionKind == UnlinkedBuiltinFunction, executable-&gt;constructorKind(), executable-&gt;superBinding(), parseMode, executable-&gt;derivedContextType(), false, isClassContext, executable-&gt;arrowFunctionCodeFeatures()));
</ins><span class="cx"> 
</span><span class="cx">     auto generator(std::make_unique&lt;BytecodeGenerator&gt;(vm, function.get(), result, debuggerMode, profilerMode, executable-&gt;parentScopeTDZVariables()));
</span><span class="cx">     error = generator-&gt;generate();
</span><span class="lines">@@ -101,6 +101,7 @@
</span><span class="cx">     , m_superBinding(static_cast&lt;unsigned&gt;(node-&gt;superBinding()))
</span><span class="cx">     , m_derivedContextType(static_cast&lt;unsigned&gt;(derivedContextType))
</span><span class="cx">     , m_sourceParseMode(static_cast&lt;unsigned&gt;(node-&gt;parseMode()))
</span><ins>+    , m_arrowFunctionCodeFeatures(node-&gt;arrowFunctionCodeFeatures())
</ins><span class="cx">     , m_name(node-&gt;ident())
</span><span class="cx">     , m_inferredName(node-&gt;inferredName())
</span><span class="cx">     , m_sourceOverride(WTFMove(sourceOverride))
</span></span></pre></div>
<a id="trunkSourceJavaScriptCorebytecodeUnlinkedFunctionExecutableh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/bytecode/UnlinkedFunctionExecutable.h (197032 => 197033)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/bytecode/UnlinkedFunctionExecutable.h        2016-02-24 17:26:52 UTC (rev 197032)
+++ trunk/Source/JavaScriptCore/bytecode/UnlinkedFunctionExecutable.h        2016-02-24 17:36:12 UTC (rev 197033)
</span><span class="lines">@@ -84,6 +84,7 @@
</span><span class="cx">     FunctionMode functionMode() const { return static_cast&lt;FunctionMode&gt;(m_functionMode); }
</span><span class="cx">     ConstructorKind constructorKind() const { return static_cast&lt;ConstructorKind&gt;(m_constructorKind); }
</span><span class="cx">     SuperBinding superBinding() const { return static_cast&lt;SuperBinding&gt;(m_superBinding); }
</span><ins>+    ArrowFunctionCodeFeatures arrowFunctionCodeFeatures() const { return m_arrowFunctionCodeFeatures; }
</ins><span class="cx"> 
</span><span class="cx">     unsigned unlinkedFunctionNameStart() const { return m_unlinkedFunctionNameStart; }
</span><span class="cx">     unsigned unlinkedBodyStartColumn() const { return m_unlinkedBodyStartColumn; }
</span><span class="lines">@@ -156,6 +157,7 @@
</span><span class="cx">     unsigned m_superBinding : 1;
</span><span class="cx">     unsigned m_derivedContextType: 2;
</span><span class="cx">     unsigned m_sourceParseMode : 4; // SourceParseMode
</span><ins>+    ArrowFunctionCodeFeatures m_arrowFunctionCodeFeatures;
</ins><span class="cx"> 
</span><span class="cx">     WriteBarrier&lt;UnlinkedFunctionCodeBlock&gt; m_unlinkedCodeBlockForCall;
</span><span class="cx">     WriteBarrier&lt;UnlinkedFunctionCodeBlock&gt; m_unlinkedCodeBlockForConstruct;
</span></span></pre></div>
<a id="trunkSourceJavaScriptCorebytecompilerBytecodeGeneratorcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/bytecompiler/BytecodeGenerator.cpp (197032 => 197033)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/bytecompiler/BytecodeGenerator.cpp        2016-02-24 17:26:52 UTC (rev 197032)
+++ trunk/Source/JavaScriptCore/bytecompiler/BytecodeGenerator.cpp        2016-02-24 17:36:12 UTC (rev 197033)
</span><span class="lines">@@ -243,7 +243,7 @@
</span><span class="cx">     bool shouldCaptureSomeOfTheThings = m_shouldEmitDebugHooks || functionNode-&gt;needsActivation() || containsArrowOrEvalButNotInArrowBlock;
</span><span class="cx"> 
</span><span class="cx">     bool shouldCaptureAllOfTheThings = m_shouldEmitDebugHooks || codeBlock-&gt;usesEval();
</span><del>-    bool needsArguments = (functionNode-&gt;usesArguments() || codeBlock-&gt;usesEval() || (functionNode-&gt;usesArrowFunction() &amp;&amp; !codeBlock-&gt;isArrowFunction()));
</del><ins>+    bool needsArguments = (functionNode-&gt;usesArguments() || codeBlock-&gt;usesEval() || (functionNode-&gt;usesArrowFunction() &amp;&amp; !codeBlock-&gt;isArrowFunction() &amp;&amp; isArgumentsUsedInInnerArrowFunction()));
</ins><span class="cx"> 
</span><span class="cx">     // Generator never provides &quot;arguments&quot;. &quot;arguments&quot; reference will be resolved in an upper generator function scope.
</span><span class="cx">     if (parseMode == SourceParseMode::GeneratorBodyMode)
</span><span class="lines">@@ -572,7 +572,7 @@
</span><span class="cx">     // Loading |this| inside an arrow function must be done after initializeDefaultParameterValuesAndSetupFunctionScopeStack()
</span><span class="cx">     // because that function sets up the SymbolTable stack and emitLoadThisFromArrowFunctionLexicalEnvironment()
</span><span class="cx">     // consults the SymbolTable stack
</span><del>-    if (SourceParseMode::ArrowFunctionMode == parseMode &amp;&amp; (functionNode-&gt;usesThis() || isDerivedClassContext() || isDerivedConstructorContext()))
</del><ins>+    if (SourceParseMode::ArrowFunctionMode == parseMode &amp;&amp; (functionNode-&gt;usesThis() || isThisUsedInInnerArrowFunction()))
</ins><span class="cx">         emitLoadThisFromArrowFunctionLexicalEnvironment();
</span><span class="cx">     
</span><span class="cx">     if (needsToUpdateArrowFunctionContext() &amp;&amp; !codeBlock-&gt;isArrowFunction()) {
</span><span class="lines">@@ -888,16 +888,18 @@
</span><span class="cx">         
</span><span class="cx">         if (!m_codeBlock-&gt;isArrowFunction()) {
</span><span class="cx">             ScopeOffset offset;
</span><ins>+            
+            if (isThisUsedInInnerArrowFunction()) {
+                offset = symbolTable-&gt;takeNextScopeOffset();
+                symbolTable-&gt;set(propertyNames().thisIdentifier.impl(), SymbolTableEntry(VarOffset(offset)));
+            }
</ins><span class="cx"> 
</span><del>-            offset = symbolTable-&gt;takeNextScopeOffset();
-            symbolTable-&gt;set(propertyNames().thisIdentifier.impl(), SymbolTableEntry(VarOffset(offset)));
-
-            if (m_codeType == FunctionCode) {
</del><ins>+            if (m_codeType == FunctionCode &amp;&amp; isNewTargetUsedInInnerArrowFunction()) {
</ins><span class="cx">                 offset = symbolTable-&gt;takeNextScopeOffset();
</span><span class="cx">                 symbolTable-&gt;set(propertyNames().newTargetLocalPrivateName.impl(), SymbolTableEntry(VarOffset(offset)));
</span><span class="cx">             }
</span><span class="cx">             
</span><del>-            if (isConstructor() &amp;&amp; constructorKind() == ConstructorKind::Derived) {
</del><ins>+            if (isConstructor() &amp;&amp; constructorKind() == ConstructorKind::Derived &amp;&amp; isSuperUsedInInnerArrowFunction()) {
</ins><span class="cx">                 offset = symbolTable-&gt;takeNextScopeOffset();
</span><span class="cx">                 symbolTable-&gt;set(propertyNames().derivedConstructorPrivateName.impl(), SymbolTableEntry(VarOffset(offset)));
</span><span class="cx">             }
</span><span class="lines">@@ -907,28 +909,33 @@
</span><span class="cx">     }
</span><span class="cx"> 
</span><span class="cx">     VariableEnvironment environment;
</span><del>-    auto addResult = environment.add(propertyNames().thisIdentifier);
-    addResult.iterator-&gt;value.setIsCaptured();
-    addResult.iterator-&gt;value.setIsConst();
</del><ins>+
+    if (isThisUsedInInnerArrowFunction()) {
+        auto addResult = environment.add(propertyNames().thisIdentifier);
+        addResult.iterator-&gt;value.setIsCaptured();
+        addResult.iterator-&gt;value.setIsConst();
+    }
</ins><span class="cx">     
</span><del>-    if (m_codeType == FunctionCode)  {
</del><ins>+    if (m_codeType == FunctionCode &amp;&amp; isNewTargetUsedInInnerArrowFunction()) {
</ins><span class="cx">         auto addTarget = environment.add(propertyNames().newTargetLocalPrivateName);
</span><span class="cx">         addTarget.iterator-&gt;value.setIsCaptured();
</span><span class="cx">         addTarget.iterator-&gt;value.setIsLet();
</span><span class="cx">     }
</span><span class="cx"> 
</span><del>-    if (isConstructor() &amp;&amp; constructorKind() == ConstructorKind::Derived) {
</del><ins>+    if (isConstructor() &amp;&amp; constructorKind() == ConstructorKind::Derived &amp;&amp; isSuperUsedInInnerArrowFunction()) {
</ins><span class="cx">         auto derivedConstructor = environment.add(propertyNames().derivedConstructorPrivateName);
</span><span class="cx">         derivedConstructor.iterator-&gt;value.setIsCaptured();
</span><span class="cx">         derivedConstructor.iterator-&gt;value.setIsLet();
</span><span class="cx">     }
</span><span class="cx"> 
</span><del>-    size_t size = m_symbolTableStack.size();
-    pushLexicalScopeInternal(environment, TDZCheckOptimization::Optimize, NestedScopeType::IsNotNested, nullptr, TDZRequirement::UnderTDZ, ScopeType::LetConstScope, ScopeRegisterType::Block);
</del><ins>+    if (environment.size() &gt; 0) {
+        size_t size = m_symbolTableStack.size();
+        pushLexicalScopeInternal(environment, TDZCheckOptimization::Optimize, NestedScopeType::IsNotNested, nullptr, TDZRequirement::UnderTDZ, ScopeType::LetConstScope, ScopeRegisterType::Block);
</ins><span class="cx"> 
</span><del>-    ASSERT_UNUSED(size, m_symbolTableStack.size() == size + 1);
</del><ins>+        ASSERT_UNUSED(size, m_symbolTableStack.size() == size + 1);
</ins><span class="cx"> 
</span><del>-    m_arrowFunctionContextLexicalEnvironmentRegister = m_symbolTableStack.last().m_scope;
</del><ins>+        m_arrowFunctionContextLexicalEnvironmentRegister = m_symbolTableStack.last().m_scope;
+    }
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> RegisterID* BytecodeGenerator::initializeNextParameter()
</span><span class="lines">@@ -4000,16 +4007,16 @@
</span><span class="cx">     m_forInContextStack.removeLast();
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-RegisterID* BytecodeGenerator::emitLoadArrowFunctionLexicalEnvironment()
</del><ins>+RegisterID* BytecodeGenerator::emitLoadArrowFunctionLexicalEnvironment(const Identifier&amp; identifier)
</ins><span class="cx"> {
</span><span class="cx">     ASSERT(m_codeBlock-&gt;isArrowFunction() || m_codeBlock-&gt;isArrowFunctionContext() || constructorKind() == ConstructorKind::Derived);
</span><span class="cx"> 
</span><del>-    return emitResolveScope(nullptr, variable(propertyNames().thisIdentifier, ThisResolutionType::Scoped));
</del><ins>+    return emitResolveScope(nullptr, variable(identifier, ThisResolutionType::Scoped));
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> void BytecodeGenerator::emitLoadThisFromArrowFunctionLexicalEnvironment()
</span><span class="cx"> {
</span><del>-    emitGetFromScope(thisRegister(), emitLoadArrowFunctionLexicalEnvironment(), variable(propertyNames().thisIdentifier, ThisResolutionType::Scoped), DoNotThrowIfNotFound);
</del><ins>+    emitGetFromScope(thisRegister(), emitLoadArrowFunctionLexicalEnvironment(propertyNames().thisIdentifier), variable(propertyNames().thisIdentifier, ThisResolutionType::Scoped), DoNotThrowIfNotFound);
</ins><span class="cx"> }
</span><span class="cx">     
</span><span class="cx"> RegisterID* BytecodeGenerator::emitLoadNewTargetFromArrowFunctionLexicalEnvironment()
</span><span class="lines">@@ -4017,7 +4024,7 @@
</span><span class="cx">     m_isNewTargetLoadedInArrowFunction = true;
</span><span class="cx"> 
</span><span class="cx">     Variable newTargetVar = variable(propertyNames().newTargetLocalPrivateName);
</span><del>-    emitMove(m_newTargetRegister, emitGetFromScope(newTemporary(), emitLoadArrowFunctionLexicalEnvironment(), newTargetVar, ThrowIfNotFound));
</del><ins>+    emitMove(m_newTargetRegister, emitGetFromScope(newTemporary(), emitLoadArrowFunctionLexicalEnvironment(propertyNames().newTargetLocalPrivateName), newTargetVar, ThrowIfNotFound));
</ins><span class="cx">     
</span><span class="cx">     return m_newTargetRegister;
</span><span class="cx"> }
</span><span class="lines">@@ -4025,35 +4032,61 @@
</span><span class="cx"> RegisterID* BytecodeGenerator::emitLoadDerivedConstructorFromArrowFunctionLexicalEnvironment()
</span><span class="cx"> {
</span><span class="cx">     Variable protoScopeVar = variable(propertyNames().derivedConstructorPrivateName);
</span><del>-    return emitGetFromScope(newTemporary(), emitLoadArrowFunctionLexicalEnvironment(), protoScopeVar, ThrowIfNotFound);
</del><ins>+    return emitGetFromScope(newTemporary(), emitLoadArrowFunctionLexicalEnvironment(propertyNames().derivedConstructorPrivateName), protoScopeVar, ThrowIfNotFound);
</ins><span class="cx"> }
</span><span class="cx">     
</span><ins>+bool BytecodeGenerator::isThisUsedInInnerArrowFunction() 
+{
+    return m_codeBlock-&gt;doAnyInnerArrowFunctionsUseThis() || m_codeBlock-&gt;doAnyInnerArrowFunctionsUseSuperProperty() || m_codeBlock-&gt;doAnyInnerArrowFunctionsUseSuperCall() || m_codeBlock-&gt;doAnyInnerArrowFunctionsUseEval() || m_codeBlock-&gt;usesEval();
+}
+    
+bool BytecodeGenerator::isArgumentsUsedInInnerArrowFunction()
+{
+    return m_codeBlock-&gt;doAnyInnerArrowFunctionsUseArguments() || m_codeBlock-&gt;doAnyInnerArrowFunctionsUseEval();
+}
+
+bool BytecodeGenerator::isNewTargetUsedInInnerArrowFunction()
+{
+    return m_codeBlock-&gt;doAnyInnerArrowFunctionsUseNewTarget() || m_codeBlock-&gt;doAnyInnerArrowFunctionsUseSuperCall();
+}
+
+bool BytecodeGenerator::isSuperUsedInInnerArrowFunction()
+{
+    return m_codeBlock-&gt;doAnyInnerArrowFunctionsUseSuperCall() || m_codeBlock-&gt;doAnyInnerArrowFunctionsUseSuperProperty();
+}
+
</ins><span class="cx"> void BytecodeGenerator::emitPutNewTargetToArrowFunctionContextScope()
</span><span class="cx"> {
</span><del>-    ASSERT(m_arrowFunctionContextLexicalEnvironmentRegister != nullptr);
</del><ins>+    if (isNewTargetUsedInInnerArrowFunction()) {
+        ASSERT(m_arrowFunctionContextLexicalEnvironmentRegister);
</ins><span class="cx">         
</span><del>-    Variable newTargetVar = variable(propertyNames().newTargetLocalPrivateName);
-    emitPutToScope(m_arrowFunctionContextLexicalEnvironmentRegister, newTargetVar, newTarget(), DoNotThrowIfNotFound, Initialization);
</del><ins>+        Variable newTargetVar = variable(propertyNames().newTargetLocalPrivateName);
+        emitPutToScope(m_arrowFunctionContextLexicalEnvironmentRegister, newTargetVar, newTarget(), DoNotThrowIfNotFound, Initialization);
+    }
</ins><span class="cx"> }
</span><span class="cx">     
</span><span class="cx"> void BytecodeGenerator::emitPutDerivedConstructorToArrowFunctionContextScope()
</span><span class="cx"> {
</span><span class="cx">     if ((isConstructor() &amp;&amp; constructorKind() == ConstructorKind::Derived) || m_codeBlock-&gt;isClassContext()) {
</span><del>-        ASSERT(m_arrowFunctionContextLexicalEnvironmentRegister);
</del><ins>+        if (isSuperUsedInInnerArrowFunction()) {
+            ASSERT(m_arrowFunctionContextLexicalEnvironmentRegister);
</ins><span class="cx">             
</span><del>-        Variable protoScope = variable(propertyNames().derivedConstructorPrivateName);
-        emitPutToScope(m_arrowFunctionContextLexicalEnvironmentRegister, protoScope, &amp;m_calleeRegister, DoNotThrowIfNotFound, Initialization);
</del><ins>+            Variable protoScope = variable(propertyNames().derivedConstructorPrivateName);
+            emitPutToScope(m_arrowFunctionContextLexicalEnvironmentRegister, protoScope, &amp;m_calleeRegister, DoNotThrowIfNotFound, Initialization);
+        }
</ins><span class="cx">     }
</span><span class="cx"> }
</span><del>-
</del><ins>+    
</ins><span class="cx"> void BytecodeGenerator::emitPutThisToArrowFunctionContextScope()
</span><span class="cx"> {
</span><del>-    ASSERT(isDerivedConstructorContext() || m_arrowFunctionContextLexicalEnvironmentRegister != nullptr);
</del><ins>+    if (isThisUsedInInnerArrowFunction()) {
+        ASSERT(isDerivedConstructorContext() || m_arrowFunctionContextLexicalEnvironmentRegister != nullptr);
</ins><span class="cx"> 
</span><del>-    Variable thisVar = variable(propertyNames().thisIdentifier, ThisResolutionType::Scoped);
-    RegisterID* scope = isDerivedConstructorContext() ? emitLoadArrowFunctionLexicalEnvironment() : m_arrowFunctionContextLexicalEnvironmentRegister;
</del><ins>+        Variable thisVar = variable(propertyNames().thisIdentifier, ThisResolutionType::Scoped);
+        RegisterID* scope = isDerivedConstructorContext() ? emitLoadArrowFunctionLexicalEnvironment(propertyNames().thisIdentifier) : m_arrowFunctionContextLexicalEnvironmentRegister;
</ins><span class="cx">     
</span><del>-    emitPutToScope(scope, thisVar, thisRegister(), DoNotThrowIfNotFound, NotInitialization);
</del><ins>+        emitPutToScope(scope, thisVar, thisRegister(), ThrowIfNotFound, NotInitialization);
+    }
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> void BytecodeGenerator::pushStructureForInScope(RegisterID* localRegister, RegisterID* indexRegister, RegisterID* propertyRegister, RegisterID* enumeratorRegister)
</span></span></pre></div>
<a id="trunkSourceJavaScriptCorebytecompilerBytecodeGeneratorh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/bytecompiler/BytecodeGenerator.h (197032 => 197033)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/bytecompiler/BytecodeGenerator.h        2016-02-24 17:26:52 UTC (rev 197032)
+++ trunk/Source/JavaScriptCore/bytecompiler/BytecodeGenerator.h        2016-02-24 17:36:12 UTC (rev 197033)
</span><span class="lines">@@ -494,7 +494,7 @@
</span><span class="cx"> 
</span><span class="cx">         void emitProfileControlFlow(int);
</span><span class="cx">         
</span><del>-        RegisterID* emitLoadArrowFunctionLexicalEnvironment();
</del><ins>+        RegisterID* emitLoadArrowFunctionLexicalEnvironment(const Identifier&amp;);
</ins><span class="cx">         void emitLoadThisFromArrowFunctionLexicalEnvironment();
</span><span class="cx">         RegisterID* emitLoadNewTargetFromArrowFunctionLexicalEnvironment();
</span><span class="cx"> 
</span><span class="lines">@@ -717,8 +717,13 @@
</span><span class="cx">         RegisterID* emitGetParentScope(RegisterID* dst, RegisterID* scope);
</span><span class="cx">         void emitPushFunctionNameScope(const Identifier&amp; property, RegisterID* value, bool isCaptured);
</span><span class="cx">         void emitNewFunctionExpressionCommon(RegisterID*, BaseFuncExprNode*);
</span><ins>+        
+        bool isNewTargetUsedInInnerArrowFunction();
+        bool isSuperUsedInInnerArrowFunction();
+        bool isArgumentsUsedInInnerArrowFunction();
</ins><span class="cx"> 
</span><span class="cx">     public:
</span><ins>+        bool isThisUsedInInnerArrowFunction();
</ins><span class="cx">         void pushLexicalScope(VariableEnvironmentNode*, TDZCheckOptimization, NestedScopeType = NestedScopeType::IsNotNested, RegisterID** constantSymbolTableResult = nullptr);
</span><span class="cx">         void popLexicalScope(VariableEnvironmentNode*);
</span><span class="cx">         void prepareLexicalScopeForNextForLoopIteration(VariableEnvironmentNode*, RegisterID* loopSymbolTable);
</span></span></pre></div>
<a id="trunkSourceJavaScriptCorebytecompilerNodesCodegencpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/bytecompiler/NodesCodegen.cpp (197032 => 197033)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/bytecompiler/NodesCodegen.cpp        2016-02-24 17:26:52 UTC (rev 197032)
+++ trunk/Source/JavaScriptCore/bytecompiler/NodesCodegen.cpp        2016-02-24 17:36:12 UTC (rev 197033)
</span><span class="lines">@@ -146,7 +146,7 @@
</span><span class="cx"> 
</span><span class="cx"> RegisterID* ThisNode::emitBytecode(BytecodeGenerator&amp; generator, RegisterID* dst)
</span><span class="cx"> {
</span><del>-    if (generator.constructorKind() == ConstructorKind::Derived &amp;&amp; generator.needsToUpdateArrowFunctionContext())
</del><ins>+    if (generator.constructorKind() == ConstructorKind::Derived &amp;&amp; generator.needsToUpdateArrowFunctionContext() &amp;&amp; generator.isThisUsedInInnerArrowFunction())
</ins><span class="cx">         generator.emitLoadThisFromArrowFunctionLexicalEnvironment();
</span><span class="cx"> 
</span><span class="cx">     if (m_shouldAlwaysEmitTDZCheck || generator.constructorKind() == ConstructorKind::Derived || generator.isDerivedConstructorContext())
</span><span class="lines">@@ -723,7 +723,7 @@
</span><span class="cx">     //       eval(&quot;this.id = 'B'&quot;);
</span><span class="cx">     //    }
</span><span class="cx">     // }
</span><del>-    if (generator.constructorKind() == ConstructorKind::Derived &amp;&amp; generator.needsToUpdateArrowFunctionContext())
</del><ins>+    if (generator.constructorKind() == ConstructorKind::Derived &amp;&amp; generator.needsToUpdateArrowFunctionContext() &amp;&amp; generator.isThisUsedInInnerArrowFunction())
</ins><span class="cx">         generator.emitLoadThisFromArrowFunctionLexicalEnvironment();
</span><span class="cx"> 
</span><span class="cx">     Variable var = generator.variable(generator.propertyNames().eval);
</span><span class="lines">@@ -762,7 +762,7 @@
</span><span class="cx">         bool isConstructorKindDerived = generator.constructorKind() == ConstructorKind::Derived;
</span><span class="cx">         if (generator.isDerivedConstructorContext() || (isConstructorKindDerived &amp;&amp; generator.needsToUpdateArrowFunctionContext()))
</span><span class="cx">             generator.emitPutThisToArrowFunctionContextScope();
</span><del>-        
</del><ins>+
</ins><span class="cx">         return ret;
</span><span class="cx">     }
</span><span class="cx">     generator.emitLoad(callArguments.thisRegister(), jsUndefined());
</span><span class="lines">@@ -3138,7 +3138,7 @@
</span><span class="cx"> 
</span><span class="cx">         // If there is no return we must automatically insert one.
</span><span class="cx">         if (!returnNode) {
</span><del>-            if (generator.constructorKind() == ConstructorKind::Derived &amp;&amp; generator.needsToUpdateArrowFunctionContext())
</del><ins>+            if (generator.constructorKind() == ConstructorKind::Derived &amp;&amp; generator.needsToUpdateArrowFunctionContext() &amp;&amp; generator.isThisUsedInInnerArrowFunction())
</ins><span class="cx">                 generator.emitLoadThisFromArrowFunctionLexicalEnvironment(); // Arrow function can invoke 'super' in constructor and before leave constructor we need load 'this' from lexical arrow function environment
</span><span class="cx">             
</span><span class="cx">             RegisterID* r0 = generator.isConstructor() ? generator.thisRegister() : generator.emitLoad(0, jsUndefined());
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreparserASTBuilderh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/parser/ASTBuilder.h (197032 => 197033)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/parser/ASTBuilder.h        2016-02-24 17:26:52 UTC (rev 197032)
+++ trunk/Source/JavaScriptCore/parser/ASTBuilder.h        2016-02-24 17:36:12 UTC (rev 197033)
</span><span class="lines">@@ -372,12 +372,12 @@
</span><span class="cx">         const JSTokenLocation&amp; startLocation, const JSTokenLocation&amp; endLocation, 
</span><span class="cx">         unsigned startColumn, unsigned endColumn, int functionKeywordStart, 
</span><span class="cx">         int functionNameStart, int parametersStart, bool inStrictContext, 
</span><del>-        ConstructorKind constructorKind, SuperBinding superBinding, unsigned parameterCount, SourceParseMode mode, bool isArrowFunctionBodyExpression)
</del><ins>+        ConstructorKind constructorKind, SuperBinding superBinding, unsigned parameterCount, SourceParseMode mode, bool isArrowFunctionBodyExpression, ArrowFunctionCodeFeatures arrowFunctionCodeFeatures = NoArrowFunctionFeatures)
</ins><span class="cx">     {
</span><span class="cx">         return new (m_parserArena) FunctionMetadataNode(
</span><span class="cx">             m_parserArena, startLocation, endLocation, startColumn, endColumn, 
</span><span class="cx">             functionKeywordStart, functionNameStart, parametersStart, 
</span><del>-            inStrictContext, constructorKind, superBinding, parameterCount, mode, isArrowFunctionBodyExpression);
</del><ins>+            inStrictContext, constructorKind, superBinding, parameterCount, mode, isArrowFunctionBodyExpression, arrowFunctionCodeFeatures);
</ins><span class="cx">     }
</span><span class="cx"> 
</span><span class="cx">     ExpressionNode* createArrowFunctionExpr(const JSTokenLocation&amp; location, const ParserFunctionInfo&lt;ASTBuilder&gt;&amp; functionInfo)
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreparserNodescpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/parser/Nodes.cpp (197032 => 197033)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/parser/Nodes.cpp        2016-02-24 17:26:52 UTC (rev 197032)
+++ trunk/Source/JavaScriptCore/parser/Nodes.cpp        2016-02-24 17:36:12 UTC (rev 197033)
</span><span class="lines">@@ -146,7 +146,7 @@
</span><span class="cx">     ParserArena&amp;, const JSTokenLocation&amp; startLocation, 
</span><span class="cx">     const JSTokenLocation&amp; endLocation, unsigned startColumn, unsigned endColumn, 
</span><span class="cx">     int functionKeywordStart, int functionNameStart, int parametersStart, bool isInStrictContext, 
</span><del>-    ConstructorKind constructorKind, SuperBinding superBinding, unsigned parameterCount, SourceParseMode mode, bool isArrowFunctionBodyExpression)
</del><ins>+    ConstructorKind constructorKind, SuperBinding superBinding, unsigned parameterCount, SourceParseMode mode, bool isArrowFunctionBodyExpression, ArrowFunctionCodeFeatures arrowFunctionCodeFeatures)
</ins><span class="cx">         : Node(endLocation)
</span><span class="cx">         , m_startColumn(startColumn)
</span><span class="cx">         , m_endColumn(endColumn)
</span><span class="lines">@@ -160,6 +160,7 @@
</span><span class="cx">         , m_superBinding(static_cast&lt;unsigned&gt;(superBinding))
</span><span class="cx">         , m_constructorKind(static_cast&lt;unsigned&gt;(constructorKind))
</span><span class="cx">         , m_isArrowFunctionBodyExpression(isArrowFunctionBodyExpression)
</span><ins>+        , m_arrowFunctionCodeFeatures(arrowFunctionCodeFeatures)
</ins><span class="cx"> {
</span><span class="cx">     ASSERT(m_superBinding == static_cast&lt;unsigned&gt;(superBinding));
</span><span class="cx">     ASSERT(m_constructorKind == static_cast&lt;unsigned&gt;(constructorKind));
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreparserNodesh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/parser/Nodes.h (197032 => 197033)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/parser/Nodes.h        2016-02-24 17:26:52 UTC (rev 197032)
+++ trunk/Source/JavaScriptCore/parser/Nodes.h        2016-02-24 17:36:12 UTC (rev 197033)
</span><span class="lines">@@ -1824,7 +1824,7 @@
</span><span class="cx">             ParserArena&amp;, const JSTokenLocation&amp; start, const JSTokenLocation&amp; end, 
</span><span class="cx">             unsigned startColumn, unsigned endColumn, int functionKeywordStart, 
</span><span class="cx">             int functionNameStart, int parametersStart, bool isInStrictContext, 
</span><del>-            ConstructorKind, SuperBinding, unsigned, SourceParseMode, bool isArrowFunctionBodyExpression);
</del><ins>+            ConstructorKind, SuperBinding, unsigned, SourceParseMode, bool isArrowFunctionBodyExpression, ArrowFunctionCodeFeatures = NoArrowFunctionFeatures);
</ins><span class="cx"> 
</span><span class="cx">         void finishParsing(const SourceCode&amp;, const Identifier&amp;, FunctionMode);
</span><span class="cx">         
</span><span class="lines">@@ -1852,6 +1852,7 @@
</span><span class="cx">         SuperBinding superBinding() { return static_cast&lt;SuperBinding&gt;(m_superBinding); }
</span><span class="cx">         ConstructorKind constructorKind() { return static_cast&lt;ConstructorKind&gt;(m_constructorKind); }
</span><span class="cx">         bool isArrowFunctionBodyExpression() const { return m_isArrowFunctionBodyExpression; }
</span><ins>+        ArrowFunctionCodeFeatures arrowFunctionCodeFeatures() const { return m_arrowFunctionCodeFeatures;}
</ins><span class="cx"> 
</span><span class="cx">         void setLoc(unsigned firstLine, unsigned lastLine, int startOffset, int lineStartOffset)
</span><span class="cx">         {
</span><span class="lines">@@ -1879,6 +1880,7 @@
</span><span class="cx">         unsigned m_superBinding : 1;
</span><span class="cx">         unsigned m_constructorKind : 2;
</span><span class="cx">         unsigned m_isArrowFunctionBodyExpression : 1;
</span><ins>+        ArrowFunctionCodeFeatures m_arrowFunctionCodeFeatures;
</ins><span class="cx">     };
</span><span class="cx"> 
</span><span class="cx">     class FunctionNode final : public ScopeNode {
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreparserParsercpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/parser/Parser.cpp (197032 => 197033)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/parser/Parser.cpp        2016-02-24 17:26:52 UTC (rev 197032)
+++ trunk/Source/JavaScriptCore/parser/Parser.cpp        2016-02-24 17:36:12 UTC (rev 197033)
</span><span class="lines">@@ -519,7 +519,7 @@
</span><span class="cx">         failIfFalse(parseSourceElements(generatorFunctionContext, mode), &quot;Cannot parse the body of a generator&quot;);
</span><span class="cx">         popScope(generatorBodyScope, TreeBuilder::NeedsFreeVariableInfo);
</span><span class="cx">     }
</span><del>-    info.body = context.createFunctionMetadata(startLocation, tokenLocation(), startColumn, tokenColumn(), functionKeywordStart, functionNameStart, parametersStart, strictMode(), ConstructorKind::None, m_superBinding, info.parameterCount, SourceParseMode::GeneratorBodyMode, false);
</del><ins>+    info.body = context.createFunctionMetadata(startLocation, tokenLocation(), startColumn, tokenColumn(), functionKeywordStart, functionNameStart, parametersStart, strictMode(), ConstructorKind::None, m_superBinding, info.parameterCount, SourceParseMode::GeneratorBodyMode, false, currentFunctionScope()-&gt;innerArrowFunctionFeatures());
</ins><span class="cx"> 
</span><span class="cx">     info.endLine = tokenLine();
</span><span class="cx">     info.endOffset = m_token.m_data.offset;
</span><span class="lines">@@ -1735,7 +1735,7 @@
</span><span class="cx">         next();
</span><span class="cx">         if (match(CLOSEBRACE)) {
</span><span class="cx">             unsigned endColumn = tokenColumn();
</span><del>-            return context.createFunctionMetadata(startLocation, tokenLocation(), startColumn, endColumn, functionKeywordStart, functionNameStart, parametersStart, strictMode(), constructorKind, superBinding, parameterCount, parseMode, isArrowFunctionBodyExpression);
</del><ins>+            return context.createFunctionMetadata(startLocation, tokenLocation(), startColumn, endColumn, functionKeywordStart, functionNameStart, parametersStart, strictMode(), constructorKind, superBinding, parameterCount, parseMode, isArrowFunctionBodyExpression, currentFunctionScope()-&gt;innerArrowFunctionFeatures());
</ins><span class="cx">         }
</span><span class="cx">     }
</span><span class="cx"> 
</span><span class="lines">@@ -1747,7 +1747,7 @@
</span><span class="cx">     else
</span><span class="cx">         failIfFalse(parseSourceElements(syntaxChecker, CheckForStrictMode), bodyType == StandardFunctionBodyBlock ? &quot;Cannot parse body of this function&quot; : &quot;Cannot parse body of this arrow function&quot;);
</span><span class="cx">     unsigned endColumn = tokenColumn();
</span><del>-    return context.createFunctionMetadata(startLocation, tokenLocation(), startColumn, endColumn, functionKeywordStart, functionNameStart, parametersStart, strictMode(), constructorKind, superBinding, parameterCount, parseMode, isArrowFunctionBodyExpression);
</del><ins>+    return context.createFunctionMetadata(startLocation, tokenLocation(), startColumn, endColumn, functionKeywordStart, functionNameStart, parametersStart, strictMode(), constructorKind, superBinding, parameterCount, parseMode, isArrowFunctionBodyExpression, currentFunctionScope()-&gt;innerArrowFunctionFeatures());
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> static const char* stringForFunctionMode(SourceParseMode mode)
</span><span class="lines">@@ -1988,7 +1988,7 @@
</span><span class="cx">         functionInfo.body = context.createFunctionMetadata(
</span><span class="cx">             startLocation, endLocation, functionInfo.bodyStartColumn, bodyEndColumn, 
</span><span class="cx">             functionKeywordStart, functionNameStart, parametersStart, 
</span><del>-            cachedInfo-&gt;strictMode, constructorKind, expectedSuperBinding, cachedInfo-&gt;parameterCount, mode, functionBodyType == ArrowFunctionBodyExpression);
</del><ins>+            cachedInfo-&gt;strictMode, constructorKind, expectedSuperBinding, cachedInfo-&gt;parameterCount, mode, functionBodyType == ArrowFunctionBodyExpression, cachedInfo-&gt;innerArrowFunctionFeatures);
</ins><span class="cx">         
</span><span class="cx">         functionScope-&gt;restoreFromSourceProviderCache(cachedInfo);
</span><span class="cx">         popScope(functionScope, TreeBuilder::NeedsFreeVariableInfo);
</span><span class="lines">@@ -2064,12 +2064,18 @@
</span><span class="cx">                 : closestParentNonArrowFunctionNonLexicalScope()-&gt;constructorKind();
</span><span class="cx">             semanticFailIfTrue(functionConstructorKind == ConstructorKind::None, &quot;Cannot call super() outside of a class constructor&quot;);
</span><span class="cx">             semanticFailIfTrue(functionConstructorKind != ConstructorKind::Derived, &quot;Cannot call super() in a base class constructor&quot;);
</span><ins>+            
+            if (functionBodyType == ArrowFunctionBodyBlock || functionBodyType == ArrowFunctionBodyExpression)
+                functionScope-&gt;setInnerArrowFunctionUseSuperCall();
</ins><span class="cx">         }
</span><span class="cx">         if (functionScope-&gt;needsSuperBinding()) {
</span><span class="cx">             SuperBinding functionSuperBinding = functionBodyType == StandardFunctionBodyBlock
</span><span class="cx">                 ? expectedSuperBinding
</span><span class="cx">                 : closestParentNonArrowFunctionNonLexicalScope()-&gt;expectedSuperBinding();
</span><span class="cx">             semanticFailIfTrue(functionSuperBinding == SuperBinding::NotNeeded, &quot;super can only be used in a method of a derived class&quot;);
</span><ins>+
+            if (functionBodyType == ArrowFunctionBodyBlock || functionBodyType == ArrowFunctionBodyExpression)
+                functionScope-&gt;setInnerArrowFunctionUseSuperProperty();
</ins><span class="cx">         }
</span><span class="cx">     }
</span><span class="cx"> 
</span><span class="lines">@@ -3207,6 +3213,8 @@
</span><span class="cx">             JSTextPosition start = tokenStartPosition();
</span><span class="cx">             JSTokenLocation location(tokenLocation());
</span><span class="cx">             currentScope()-&gt;useVariable(ident, m_vm-&gt;propertyNames-&gt;eval == *ident);
</span><ins>+            if (currentScope()-&gt;isArrowFunction())
+                currentScope()-&gt;setInnerArrowFunctionUseEval();
</ins><span class="cx">             TreeExpression node = context.createResolve(location, *ident, start, lastTokenEndPosition());
</span><span class="cx">             return context.createProperty(ident, node, static_cast&lt;PropertyNode::Type&gt;(PropertyNode::Constant | PropertyNode::Shorthand), PropertyNode::KnownDirect, complete);
</span><span class="cx">         }
</span><span class="lines">@@ -3620,6 +3628,8 @@
</span><span class="cx">     case THISTOKEN: {
</span><span class="cx">         JSTokenLocation location(tokenLocation());
</span><span class="cx">         next();
</span><ins>+        if (currentScope()-&gt;isArrowFunction())
+            currentScope()-&gt;setInnerArrowFunctionUseThis();
</ins><span class="cx">         return context.createThisExpr(location, m_thisTDZMode);
</span><span class="cx">     }
</span><span class="cx">     case IDENT: {
</span><span class="lines">@@ -3795,6 +3805,8 @@
</span><span class="cx">             if (m_vm-&gt;propertyNames-&gt;target == *ident) {
</span><span class="cx">                 semanticFailIfFalse(currentScope()-&gt;isFunction(), &quot;new.target is only valid inside functions&quot;);
</span><span class="cx">                 baseIsNewTarget = true;
</span><ins>+                if (currentScope()-&gt;isArrowFunction())
+                    currentScope()-&gt;setInnerArrowFunctionUseNewTarget();
</ins><span class="cx">                 base = context.createNewTargetExpr(location);
</span><span class="cx">                 newCount--;
</span><span class="cx">                 next();
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreparserParserh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/parser/Parser.h (197032 => 197033)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/parser/Parser.h        2016-02-24 17:26:52 UTC (rev 197032)
+++ trunk/Source/JavaScriptCore/parser/Parser.h        2016-02-24 17:36:12 UTC (rev 197033)
</span><span class="lines">@@ -158,7 +158,7 @@
</span><span class="cx"> };
</span><span class="cx"> 
</span><span class="cx"> struct Scope {
</span><del>-    Scope(const VM* vm, bool isFunction, bool isGenerator, bool strictMode)
</del><ins>+    Scope(const VM* vm, bool isFunction, bool isGenerator, bool strictMode, bool isArrowFunction)
</ins><span class="cx">         : m_vm(vm)
</span><span class="cx">         , m_shadowsArguments(false)
</span><span class="cx">         , m_usesEval(false)
</span><span class="lines">@@ -170,7 +170,8 @@
</span><span class="cx">         , m_strictMode(strictMode)
</span><span class="cx">         , m_isFunction(isFunction)
</span><span class="cx">         , m_isGenerator(isGenerator)
</span><del>-        , m_isArrowFunction(false)
</del><ins>+        , m_isArrowFunction(isArrowFunction)
+        , m_isArrowFunctionBoundary(false)
</ins><span class="cx">         , m_isLexicalScope(false)
</span><span class="cx">         , m_isFunctionBoundary(false)
</span><span class="cx">         , m_isValidStrictMode(true)
</span><span class="lines">@@ -179,6 +180,7 @@
</span><span class="cx">         , m_expectedSuperBinding(static_cast&lt;unsigned&gt;(SuperBinding::NotNeeded))
</span><span class="cx">         , m_loopDepth(0)
</span><span class="cx">         , m_switchDepth(0)
</span><ins>+        , m_innerArrowFunctionFeatures(0)
</ins><span class="cx">     {
</span><span class="cx">     }
</span><span class="cx"> 
</span><span class="lines">@@ -195,6 +197,7 @@
</span><span class="cx">         , m_isFunction(rhs.m_isFunction)
</span><span class="cx">         , m_isGenerator(rhs.m_isGenerator)
</span><span class="cx">         , m_isArrowFunction(rhs.m_isArrowFunction)
</span><ins>+        , m_isArrowFunctionBoundary(rhs.m_isArrowFunctionBoundary)
</ins><span class="cx">         , m_isLexicalScope(rhs.m_isLexicalScope)
</span><span class="cx">         , m_isFunctionBoundary(rhs.m_isFunctionBoundary)
</span><span class="cx">         , m_isValidStrictMode(rhs.m_isValidStrictMode)
</span><span class="lines">@@ -203,6 +206,7 @@
</span><span class="cx">         , m_expectedSuperBinding(rhs.m_expectedSuperBinding)
</span><span class="cx">         , m_loopDepth(rhs.m_loopDepth)
</span><span class="cx">         , m_switchDepth(rhs.m_switchDepth)
</span><ins>+        , m_innerArrowFunctionFeatures(rhs.m_innerArrowFunctionFeatures)
</ins><span class="cx">         , m_moduleScopeData(rhs.m_moduleScopeData)
</span><span class="cx">     {
</span><span class="cx">         if (rhs.m_labels) {
</span><span class="lines">@@ -465,6 +469,7 @@
</span><span class="cx"> 
</span><span class="cx">     void setNeedsFullActivation() { m_needsFullActivation = true; }
</span><span class="cx">     bool needsFullActivation() const { return m_needsFullActivation; }
</span><ins>+    bool isArrowFunctionBoundary() { return m_isArrowFunctionBoundary; }
</ins><span class="cx">     bool isArrowFunction() { return m_isArrowFunction; }
</span><span class="cx"> 
</span><span class="cx">     bool hasDirectSuper() { return m_hasDirectSuper; }
</span><span class="lines">@@ -473,11 +478,31 @@
</span><span class="cx">     bool needsSuperBinding() { return m_needsSuperBinding; }
</span><span class="cx">     void setNeedsSuperBinding() { m_needsSuperBinding = true; }
</span><span class="cx">     
</span><ins>+    ArrowFunctionCodeFeatures innerArrowFunctionFeatures() { return m_innerArrowFunctionFeatures; }
+    
</ins><span class="cx">     void setExpectedSuperBinding(SuperBinding superBinding) { m_expectedSuperBinding = static_cast&lt;unsigned&gt;(superBinding); }
</span><span class="cx">     SuperBinding expectedSuperBinding() const { return static_cast&lt;SuperBinding&gt;(m_expectedSuperBinding); }
</span><span class="cx">     void setConstructorKind(ConstructorKind constructorKind) { m_constructorKind = static_cast&lt;unsigned&gt;(constructorKind); }
</span><span class="cx">     ConstructorKind constructorKind() const { return static_cast&lt;ConstructorKind&gt;(m_constructorKind); }
</span><span class="cx"> 
</span><ins>+    void setInnerArrowFunctionUseSuperCall() { m_innerArrowFunctionFeatures |= SuperCallArrowFunctionFeature; }
+    void setInnerArrowFunctionUseSuperProperty() { m_innerArrowFunctionFeatures |= SuperPropertyArrowFunctionFeature; }
+    void setInnerArrowFunctionUseEval() { m_innerArrowFunctionFeatures |= EvalArrowFunctionFeature; }
+    void setInnerArrowFunctionUseThis() { m_innerArrowFunctionFeatures |= ThisArrowFunctionFeature; }
+    void setInnerArrowFunctionUseNewTarget() { m_innerArrowFunctionFeatures |= NewTargetArrowFunctionFeature; }
+    void setInnerArrowFunctionUseArguments() { m_innerArrowFunctionFeatures |= ArgumentsArrowFunctionFeature; }
+
+    void setInnerArrowFunctionUseEvalAndUseArgumentsIfNeeded()
+    {
+        ASSERT(m_isArrowFunction);
+
+        if (m_usesEval)
+            setInnerArrowFunctionUseEval();
+        
+        if (m_usedVariables.contains(m_vm-&gt;propertyNames-&gt;arguments.impl()))
+            setInnerArrowFunctionUseArguments();
+    }
+    
</ins><span class="cx">     void collectFreeVariables(Scope* nestedScope, bool shouldTrackClosedVariables)
</span><span class="cx">     {
</span><span class="cx">         if (nestedScope-&gt;m_usesEval)
</span><span class="lines">@@ -489,7 +514,7 @@
</span><span class="cx">                     continue;
</span><span class="cx"> 
</span><span class="cx">                 // &quot;arguments&quot; reference should be resolved at function boudary.
</span><del>-                if (nestedScope-&gt;isFunctionBoundary() &amp;&amp; nestedScope-&gt;hasArguments() &amp;&amp; impl == m_vm-&gt;propertyNames-&gt;arguments.impl() &amp;&amp; !nestedScope-&gt;isArrowFunction())
</del><ins>+                if (nestedScope-&gt;isFunctionBoundary() &amp;&amp; nestedScope-&gt;hasArguments() &amp;&amp; impl == m_vm-&gt;propertyNames-&gt;arguments.impl() &amp;&amp; !nestedScope-&gt;isArrowFunctionBoundary())
</ins><span class="cx">                     continue;
</span><span class="cx"> 
</span><span class="cx">                 m_usedVariables.add(impl);
</span><span class="lines">@@ -518,6 +543,11 @@
</span><span class="cx">         }
</span><span class="cx">     }
</span><span class="cx">     
</span><ins>+    void mergeInnerArrowFunctionFeatures(ArrowFunctionCodeFeatures arrowFunctionCodeFeatures)
+    {
+        m_innerArrowFunctionFeatures = m_innerArrowFunctionFeatures | arrowFunctionCodeFeatures;
+    }
+    
</ins><span class="cx">     void getCapturedVars(IdentifierSet&amp; capturedVariables, bool&amp; modifiedParameter, bool&amp; modifiedArguments)
</span><span class="cx">     {
</span><span class="cx">         if (m_needsFullActivation || m_usesEval) {
</span><span class="lines">@@ -568,6 +598,7 @@
</span><span class="cx">         parameters.usesEval = m_usesEval;
</span><span class="cx">         parameters.strictMode = m_strictMode;
</span><span class="cx">         parameters.needsFullActivation = m_needsFullActivation;
</span><ins>+        parameters.innerArrowFunctionFeatures = m_innerArrowFunctionFeatures;
</ins><span class="cx">         copyCapturedVariablesToVector(m_writtenVariables, parameters.writtenVariables);
</span><span class="cx">         copyCapturedVariablesToVector(m_usedVariables, parameters.usedVariables);
</span><span class="cx">     }
</span><span class="lines">@@ -577,6 +608,7 @@
</span><span class="cx">         ASSERT(m_isFunction);
</span><span class="cx">         m_usesEval = info-&gt;usesEval;
</span><span class="cx">         m_strictMode = info-&gt;strictMode;
</span><ins>+        m_innerArrowFunctionFeatures = info-&gt;innerArrowFunctionFeatures;
</ins><span class="cx">         m_needsFullActivation = info-&gt;needsFullActivation;
</span><span class="cx">         for (unsigned i = 0; i &lt; info-&gt;usedVariablesCount; ++i)
</span><span class="cx">             m_usedVariables.add(info-&gt;usedVariables()[i]);
</span><span class="lines">@@ -592,6 +624,8 @@
</span><span class="cx">         m_hasArguments = true;
</span><span class="cx">         setIsLexicalScope();
</span><span class="cx">         m_isGenerator = false;
</span><ins>+        m_isArrowFunctionBoundary = false;
+        m_isArrowFunction = false;
</ins><span class="cx">     }
</span><span class="cx"> 
</span><span class="cx">     void setIsGeneratorFunction()
</span><span class="lines">@@ -610,6 +644,7 @@
</span><span class="cx">     void setIsArrowFunction()
</span><span class="cx">     {
</span><span class="cx">         setIsFunction();
</span><ins>+        m_isArrowFunctionBoundary = true;
</ins><span class="cx">         m_isArrowFunction = true;
</span><span class="cx">     }
</span><span class="cx"> 
</span><span class="lines">@@ -630,6 +665,7 @@
</span><span class="cx">     bool m_isFunction : 1;
</span><span class="cx">     bool m_isGenerator : 1;
</span><span class="cx">     bool m_isArrowFunction : 1;
</span><ins>+    bool m_isArrowFunctionBoundary : 1;
</ins><span class="cx">     bool m_isLexicalScope : 1;
</span><span class="cx">     bool m_isFunctionBoundary : 1;
</span><span class="cx">     bool m_isValidStrictMode : 1;
</span><span class="lines">@@ -638,6 +674,7 @@
</span><span class="cx">     unsigned m_expectedSuperBinding : 2;
</span><span class="cx">     int m_loopDepth;
</span><span class="cx">     int m_switchDepth;
</span><ins>+    ArrowFunctionCodeFeatures m_innerArrowFunctionFeatures;
</ins><span class="cx"> 
</span><span class="cx">     typedef Vector&lt;ScopeLabelInfo, 2&gt; LabelStack;
</span><span class="cx">     std::unique_ptr&lt;LabelStack&gt; m_labels;
</span><span class="lines">@@ -896,9 +933,8 @@
</span><span class="cx">     {
</span><span class="cx">         unsigned i = m_scopeStack.size() - 1;
</span><span class="cx">         ASSERT(i &lt; m_scopeStack.size() &amp;&amp; m_scopeStack.size());
</span><del>-        while (i &amp;&amp; (!m_scopeStack[i].isFunctionBoundary() || m_scopeStack[i].isArrowFunction()))
</del><ins>+        while (i &amp;&amp; (!m_scopeStack[i].isFunctionBoundary() || m_scopeStack[i].isArrowFunctionBoundary()))
</ins><span class="cx">             i--;
</span><del>-        // When reaching the top level scope (it can be non function scope), we return it.
</del><span class="cx">         return ScopeRef(&amp;m_scopeStack, i);
</span><span class="cx">     }
</span><span class="cx">     
</span><span class="lines">@@ -907,12 +943,14 @@
</span><span class="cx">         bool isFunction = false;
</span><span class="cx">         bool isStrict = false;
</span><span class="cx">         bool isGenerator = false;
</span><ins>+        bool isArrowFunction = false;
</ins><span class="cx">         if (!m_scopeStack.isEmpty()) {
</span><span class="cx">             isStrict = m_scopeStack.last().strictMode();
</span><span class="cx">             isFunction = m_scopeStack.last().isFunction();
</span><span class="cx">             isGenerator = m_scopeStack.last().isGenerator();
</span><ins>+            isArrowFunction = m_scopeStack.last().isArrowFunction();
</ins><span class="cx">         }
</span><del>-        m_scopeStack.append(Scope(m_vm, isFunction, isGenerator, isStrict));
</del><ins>+        m_scopeStack.append(Scope(m_vm, isFunction, isGenerator, isStrict, isArrowFunction));
</ins><span class="cx">         return currentScope();
</span><span class="cx">     }
</span><span class="cx">     
</span><span class="lines">@@ -921,6 +959,13 @@
</span><span class="cx">         ASSERT_UNUSED(scope, scope.index() == m_scopeStack.size() - 1);
</span><span class="cx">         ASSERT(m_scopeStack.size() &gt; 1);
</span><span class="cx">         m_scopeStack[m_scopeStack.size() - 2].collectFreeVariables(&amp;m_scopeStack.last(), shouldTrackClosedVariables);
</span><ins>+        
+        if (m_scopeStack.last().isArrowFunction())
+            m_scopeStack.last().setInnerArrowFunctionUseEvalAndUseArgumentsIfNeeded();
+        
+        if (!(m_scopeStack.last().isFunctionBoundary() &amp;&amp; !m_scopeStack.last().isArrowFunctionBoundary()))
+            m_scopeStack[m_scopeStack.size() - 2].mergeInnerArrowFunctionFeatures(m_scopeStack.last().innerArrowFunctionFeatures());
+
</ins><span class="cx">         if (!m_scopeStack.last().isFunctionBoundary() &amp;&amp; m_scopeStack.last().needsFullActivation())
</span><span class="cx">             m_scopeStack[m_scopeStack.size() - 2].setNeedsFullActivation();
</span><span class="cx">         m_scopeStack.removeLast();
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreparserParserModesh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/parser/ParserModes.h (197032 => 197033)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/parser/ParserModes.h        2016-02-24 17:26:52 UTC (rev 197032)
+++ trunk/Source/JavaScriptCore/parser/ParserModes.h        2016-02-24 17:36:12 UTC (rev 197033)
</span><span class="lines">@@ -161,6 +161,17 @@
</span><span class="cx"> 
</span><span class="cx"> const CodeFeatures AllFeatures = EvalFeature | ArgumentsFeature | WithFeature | ThisFeature | StrictModeFeature | ShadowsArgumentsFeature | ModifiedParameterFeature | ArrowFunctionFeature | ArrowFunctionContextFeature;
</span><span class="cx"> 
</span><ins>+typedef uint8_t ArrowFunctionCodeFeatures;
+    
+const ArrowFunctionCodeFeatures NoArrowFunctionFeatures =                0;
+const ArrowFunctionCodeFeatures EvalArrowFunctionFeature =          1 &lt;&lt; 0;
+const ArrowFunctionCodeFeatures ArgumentsArrowFunctionFeature =     1 &lt;&lt; 1;
+const ArrowFunctionCodeFeatures ThisArrowFunctionFeature =          1 &lt;&lt; 2;
+const ArrowFunctionCodeFeatures SuperCallArrowFunctionFeature =     1 &lt;&lt; 3;
+const ArrowFunctionCodeFeatures SuperPropertyArrowFunctionFeature = 1 &lt;&lt; 4;
+const ArrowFunctionCodeFeatures NewTargetArrowFunctionFeature =     1 &lt;&lt; 5;
+    
+const ArrowFunctionCodeFeatures AllArrowFunctionCodeFeatures = EvalArrowFunctionFeature | ArgumentsArrowFunctionFeature | ThisArrowFunctionFeature | SuperCallArrowFunctionFeature | SuperPropertyArrowFunctionFeature | NewTargetArrowFunctionFeature;
</ins><span class="cx"> } // namespace JSC
</span><span class="cx"> 
</span><span class="cx"> #endif // ParserModes_h
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreparserSourceProviderCacheItemh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/parser/SourceProviderCacheItem.h (197032 => 197033)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/parser/SourceProviderCacheItem.h        2016-02-24 17:26:52 UTC (rev 197032)
+++ trunk/Source/JavaScriptCore/parser/SourceProviderCacheItem.h        2016-02-24 17:36:12 UTC (rev 197033)
</span><span class="lines">@@ -44,6 +44,7 @@
</span><span class="cx">     bool needsFullActivation;
</span><span class="cx">     bool usesEval;
</span><span class="cx">     bool strictMode;
</span><ins>+    ArrowFunctionCodeFeatures innerArrowFunctionFeatures;
</ins><span class="cx">     Vector&lt;RefPtr&lt;UniquedStringImpl&gt;&gt; usedVariables;
</span><span class="cx">     Vector&lt;RefPtr&lt;UniquedStringImpl&gt;&gt; writtenVariables;
</span><span class="cx">     bool isBodyArrowExpression { false };
</span><span class="lines">@@ -87,6 +88,8 @@
</span><span class="cx">     bool usesEval : 1;
</span><span class="cx"> 
</span><span class="cx">     bool strictMode : 1;
</span><ins>+    
+    ArrowFunctionCodeFeatures innerArrowFunctionFeatures;
</ins><span class="cx"> 
</span><span class="cx">     unsigned lastTockenLineStartOffset;
</span><span class="cx">     unsigned usedVariablesCount;
</span><span class="lines">@@ -127,6 +130,7 @@
</span><span class="cx">     , parameterCount(parameters.parameterCount)
</span><span class="cx">     , usesEval(parameters.usesEval)
</span><span class="cx">     , strictMode(parameters.strictMode)
</span><ins>+    , innerArrowFunctionFeatures(parameters.innerArrowFunctionFeatures)
</ins><span class="cx">     , lastTockenLineStartOffset(parameters.lastTockenLineStartOffset)
</span><span class="cx">     , usedVariablesCount(parameters.usedVariables.size())
</span><span class="cx">     , writtenVariablesCount(parameters.writtenVariables.size())
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreparserSyntaxCheckerh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/parser/SyntaxChecker.h (197032 => 197033)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/parser/SyntaxChecker.h        2016-02-24 17:26:52 UTC (rev 197032)
+++ trunk/Source/JavaScriptCore/parser/SyntaxChecker.h        2016-02-24 17:36:12 UTC (rev 197033)
</span><span class="lines">@@ -183,7 +183,7 @@
</span><span class="cx">     ExpressionType createYield(const JSTokenLocation&amp;, ExpressionType, bool, int, int, int) { return YieldExpr; }
</span><span class="cx">     ClassExpression createClassExpr(const JSTokenLocation&amp;, const Identifier&amp;, VariableEnvironment&amp;, ExpressionType, ExpressionType, PropertyList, PropertyList) { return ClassExpr; }
</span><span class="cx">     ExpressionType createFunctionExpr(const JSTokenLocation&amp;, const ParserFunctionInfo&lt;SyntaxChecker&gt;&amp;) { return FunctionExpr; }
</span><del>-    int createFunctionMetadata(const JSTokenLocation&amp;, const JSTokenLocation&amp;, int, int, bool, int, int, int, ConstructorKind, SuperBinding, unsigned, SourceParseMode, bool) { return FunctionBodyResult; }
</del><ins>+    int createFunctionMetadata(const JSTokenLocation&amp;, const JSTokenLocation&amp;, int, int, bool, int, int, int, ConstructorKind, SuperBinding, unsigned, SourceParseMode, bool, ArrowFunctionCodeFeatures = NoArrowFunctionFeatures) { return FunctionBodyResult; }
</ins><span class="cx">     ExpressionType createArrowFunctionExpr(const JSTokenLocation&amp;, const ParserFunctionInfo&lt;SyntaxChecker&gt;&amp;) { return FunctionExpr; }
</span><span class="cx">     void setFunctionNameStart(int, int) { }
</span><span class="cx">     int createArguments() { return ArgumentsResult; }
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoretestsstressarrowfunctionlexicalbindargumentsnonstrict1js"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/tests/stress/arrowfunction-lexical-bind-arguments-non-strict-1.js (197032 => 197033)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/tests/stress/arrowfunction-lexical-bind-arguments-non-strict-1.js        2016-02-24 17:26:52 UTC (rev 197032)
+++ trunk/Source/JavaScriptCore/tests/stress/arrowfunction-lexical-bind-arguments-non-strict-1.js        2016-02-24 17:36:12 UTC (rev 197033)
</span><span class="lines">@@ -214,3 +214,39 @@
</span><span class="cx"> for (var i = 0; i &lt; 10000; i++) {
</span><span class="cx">     testCase(boo('A' + i)('B' + i)('D' + i)('E' + i)('G' + i)[0], 'E' + i, txtMsg + &quot;#17&quot;);
</span><span class="cx"> }
</span><ins>+
+var testValue = 'test-value';
+
+function f_args () {
+    if (true) {
+        let someValue = '';
+        if (true) {
+            let anotherValue = 'value';
+            return () =&gt; () =&gt; () =&gt; arguments[0];
+        }
+    }
+
+    return () =&gt; 'no-value';
+}
+
+for (var i = 0; i &lt; 10000; i++) {
+    let v = f_args(testValue, 'anotherValue')()()();
+    testCase(v, testValue);
+}
+
+function f_args_eval () {
+    if (true) {
+        let someValue = '';
+        if (true) {
+            let anotherValue = 'value';
+            return () =&gt; () =&gt; () =&gt; eval('arguments[0]');
+        }
+    }
+
+    return () =&gt; 'no-value';
+}
+
+for (var i = 0; i &lt; 10000; i++) {
+    let v = f_args_eval(testValue, 'anotherValue')()()();
+    testCase(v, testValue);
+}
</ins></span></pre></div>
<a id="trunkSourceJavaScriptCoretestsstressarrowfunctionlexicalbindargumentsstrictjs"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/tests/stress/arrowfunction-lexical-bind-arguments-strict.js (197032 => 197033)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/tests/stress/arrowfunction-lexical-bind-arguments-strict.js        2016-02-24 17:26:52 UTC (rev 197032)
+++ trunk/Source/JavaScriptCore/tests/stress/arrowfunction-lexical-bind-arguments-strict.js        2016-02-24 17:36:12 UTC (rev 197033)
</span><span class="lines">@@ -131,3 +131,39 @@
</span><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> test();
</span><ins>+
+var testValue = 'test-value';
+
+function f_args () {
+    if (true) {
+        let someValue = '';
+        if (true) {
+            let anotherValue = 'value';
+            return () =&gt; () =&gt; () =&gt; arguments[0];
+        }
+    }
+
+    return () =&gt; 'no-value';
+}
+
+for (var i = 0; i &lt; 10000; i++) {
+    let v = f_args(testValue, 'anotherValue')()()();
+    testCase(v, testValue);
+}
+
+function f_args_eval () {
+    if (true) {
+        let someValue = '';
+        if (true) {
+            let anotherValue = 'value';
+            return () =&gt; () =&gt; () =&gt; eval('arguments[0]');
+        }
+    }
+
+    return () =&gt; 'no-value';
+}
+
+for (var i = 0; i &lt; 10000; i++) {
+    let v = f_args_eval(testValue, 'anotherValue')()()();
+    testCase(v, testValue);
+}
</ins></span></pre></div>
<a id="trunkSourceJavaScriptCoretestsstressarrowfunctionlexicalbindnewtargetjs"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/tests/stress/arrowfunction-lexical-bind-newtarget.js (197032 => 197033)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/tests/stress/arrowfunction-lexical-bind-newtarget.js        2016-02-24 17:26:52 UTC (rev 197032)
+++ trunk/Source/JavaScriptCore/tests/stress/arrowfunction-lexical-bind-newtarget.js        2016-02-24 17:36:12 UTC (rev 197033)
</span><span class="lines">@@ -66,7 +66,7 @@
</span><span class="cx">         new C(val);
</span><span class="cx">     }
</span><span class="cx">     catch (e) {
</span><del>-        result = e instanceof ReferenceError; 
</del><ins>+        result = e instanceof ReferenceError;
</ins><span class="cx">     }
</span><span class="cx"> 
</span><span class="cx">     return result;
</span><span class="lines">@@ -76,3 +76,17 @@
</span><span class="cx">     testCase(tryToCreateClass(true), true, &quot;Error: newTargetLocal should be hided variable&quot;);
</span><span class="cx">     testCase(tryToCreateClass(false), true, &quot;Error: newTargetLocal should be hided variable&quot;);
</span><span class="cx"> }
</span><ins>+
+function getTargetBlockScope() {
+    if (true) {
+        let someValue = '';
+        if (true)
+            return x =&gt; new.target;
+    }
+    return ()=&gt;value;
+}
+
+for (var i = 0; i &lt; 1000; i++) {
+    var undefinedTarget = getTargetBlockScope()()
+    testCase(undefinedTarget, undefined, &quot;Error: new.target is not lexically binded inside of the arrow function #4&quot;);
+}
</ins></span></pre></div>
<a id="trunkSourceJavaScriptCoretestsstressarrowfunctionlexicalbindsuperpropertyjs"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/tests/stress/arrowfunction-lexical-bind-superproperty.js (197032 => 197033)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/tests/stress/arrowfunction-lexical-bind-superproperty.js        2016-02-24 17:26:52 UTC (rev 197032)
+++ trunk/Source/JavaScriptCore/tests/stress/arrowfunction-lexical-bind-superproperty.js        2016-02-24 17:36:12 UTC (rev 197033)
</span><span class="lines">@@ -123,6 +123,20 @@
</span><span class="cx">      getParentValue() {
</span><span class="cx">          return super.getValue();
</span><span class="cx">      }
</span><ins>+
+     getValueBlockScope() {
+         if (true) {
+             var someValue ='';
+             if (true) {
+                 return () =&gt; {
+                    if (true) {
+                        let internalValue = '';
+                        return super.getValue();
+                    }
+                 }
+             }
+         }
+     }
</ins><span class="cx">  };
</span><span class="cx"> 
</span><span class="cx">  var g = new G();
</span><span class="lines">@@ -141,6 +155,8 @@
</span><span class="cx">     let setValue = g1.setValueCB();
</span><span class="cx">     setValue('new-value');
</span><span class="cx">     testCase(getValue(), 'new-value', 'Error: Some problem with using arrow and &quot;super&quot; inside of the method that retun arrow function');
</span><ins>+    getValue = g1.getValueBlockScope();
+    testCase(getValue(), 'new-value',  'Error: Some problem with using arrow and &quot;super&quot; with deep nesting inside of the method that retun arrow function');
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> var H = class H extends A {
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoretestsstressarrowfunctionlexicalbindthis8js"></a>
<div class="addfile"><h4>Added: trunk/Source/JavaScriptCore/tests/stress/arrowfunction-lexical-bind-this-8.js (0 => 197033)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/tests/stress/arrowfunction-lexical-bind-this-8.js                                (rev 0)
+++ trunk/Source/JavaScriptCore/tests/stress/arrowfunction-lexical-bind-this-8.js        2016-02-24 17:36:12 UTC (rev 197033)
</span><span class="lines">@@ -0,0 +1,89 @@
</span><ins>+var testCase = function (actual, expected, message) {
+    if (actual !== expected) {
+        throw message + &quot;. Expected '&quot; + expected + &quot;', but was '&quot; + actual + &quot;'&quot;;
+    }
+};
+
+let testValue = 'test-value';
+
+var f_this = function () {
+    let value = 'value';
+    if (true) {
+        let someValue = 'someValue';
+        if (true) {
+            let = anotherValue = 'value';
+            return () =&gt; () =&gt; () =&gt; this.value;
+        }
+    }
+
+    return () =&gt; value;
+}
+
+for (let i = 0; i &lt; 10000; i++) {
+    testCase(f_this.call({value : testValue})()()(), testValue);
+}
+
+var f_this_eval = function () {
+    if (true) {
+        let someValue = '';
+        if (true) {
+            let = anotherValue = 'value';
+            return () =&gt; () =&gt; () =&gt; eval('this.value');
+        }
+    }
+
+    return () =&gt; 'no-value';
+}
+
+for (let i = 0; i &lt; 10000; i++) {
+    testCase(f_this_eval.call({value : testValue}, false)()()(), testValue);
+}
+
+
+function f_this_branches (branch, returnThis) {
+    let value = 'value';
+    if (branch === 'A') {
+        let someValue = 'someValue';
+        if (true) {
+            let = anotherValue = 'value';
+            return () =&gt; () =&gt; () =&gt; {
+                if (returnThis)
+                    return this.value;
+                  else
+                    return anotherValue;
+            }
+        }
+    }
+
+    return () =&gt; value;
+}
+
+for (let i = 0; i &lt; 10000; i++) {
+    testCase(f_this_branches.call({value : testValue}, 'B')() == testValue, false);
+    testCase(f_this_branches.call({value : testValue}, 'A', false)()()() == testValue, false);
+    testCase(f_this_branches.call({value : testValue}, 'A', true)()()(), testValue);
+}
+
+function f_this_eval_branches (branch, returnThis) {
+    let value = 'value';
+    if (branch === 'A') {
+        let someValue = 'someValue';
+        if (true) {
+            let = anotherValue = 'value';
+            return () =&gt; () =&gt; () =&gt; {
+                if (returnThis)
+                    return eval('this.value');
+                  else
+                    return anotherValue;
+            }
+        }
+    }
+
+    return () =&gt; value;
+}
+
+for (let i = 0; i &lt; 10000; i++) {
+    testCase(f_this_eval_branches.call({value : testValue}, 'B')() == testValue, false);
+    testCase(f_this_eval_branches.call({value : testValue}, 'A', false)()()() == testValue, false);
+    testCase(f_this_eval_branches.call({value : testValue}, 'A', true)()()(), testValue);
+}
</ins></span></pre>
</div>
</div>

</body>
</html>