<!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>[188928] 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/188928">188928</a></dd>
<dt>Author</dt> <dd>commit-queue@webkit.org</dd>
<dt>Date</dt> <dd>2015-08-25 12:10:29 -0700 (Tue, 25 Aug 2015)</dd>
</dl>
<h3>Log Message</h3>
<pre>Function.prototype.toString is incorrect for ArrowFunction
https://bugs.webkit.org/show_bug.cgi?id=148148
Source/JavaScriptCore:
Patch by Aleksandr Skachkov <gskachkov@gmail.com> on 2015-08-25
Reviewed by Saam Barati.
Added correct support of toString() method for arrow function.
* parser/ASTBuilder.h:
(JSC::ASTBuilder::createFunctionMetadata):
(JSC::ASTBuilder::createArrowFunctionExpr):
* parser/Nodes.cpp:
(JSC::FunctionMetadataNode::FunctionMetadataNode):
* parser/Nodes.h:
* parser/Parser.cpp:
(JSC::Parser<LexerType>::parseFunctionBody):
(JSC::Parser<LexerType>::parseFunctionInfo):
* parser/SyntaxChecker.h:
(JSC::SyntaxChecker::createFunctionMetadata):
* runtime/FunctionPrototype.cpp:
(JSC::functionProtoFuncToString):
* tests/stress/arrowfunction-tostring.js: Added.
LayoutTests:
Patch by Skachkov Oleksandr <gskachkov@gmail.com> on 2015-08-25
Reviewed by Saam Barati.
Added test of toString() method.
* js/arrowfunction-tostring-expected.txt: Added.
* js/arrowfunction-tostring.html: Added.
* js/script-tests/arrowfunction-tostring.js: Added.</pre>
<h3>Modified Paths</h3>
<ul>
<li><a href="#trunkLayoutTestsChangeLog">trunk/LayoutTests/ChangeLog</a></li>
<li><a href="#trunkSourceJavaScriptCoreChangeLog">trunk/Source/JavaScriptCore/ChangeLog</a></li>
<li><a href="#trunkSourceJavaScriptCoreparserASTBuilderh">trunk/Source/JavaScriptCore/parser/ASTBuilder.h</a></li>
<li><a href="#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="#trunkSourceJavaScriptCoreparserSyntaxCheckerh">trunk/Source/JavaScriptCore/parser/SyntaxChecker.h</a></li>
<li><a href="#trunkSourceJavaScriptCoreruntimeFunctionPrototypecpp">trunk/Source/JavaScriptCore/runtime/FunctionPrototype.cpp</a></li>
</ul>
<h3>Added Paths</h3>
<ul>
<li><a href="#trunkLayoutTestsjsarrowfunctiontostringexpectedtxt">trunk/LayoutTests/js/arrowfunction-tostring-expected.txt</a></li>
<li><a href="#trunkLayoutTestsjsarrowfunctiontostringhtml">trunk/LayoutTests/js/arrowfunction-tostring.html</a></li>
<li><a href="#trunkLayoutTestsjsscripttestsarrowfunctiontostringjs">trunk/LayoutTests/js/script-tests/arrowfunction-tostring.js</a></li>
<li><a href="#trunkSourceJavaScriptCoretestsstressarrowfunctiontostringjs">trunk/Source/JavaScriptCore/tests/stress/arrowfunction-tostring.js</a></li>
</ul>
</div>
<div id="patch">
<h3>Diff</h3>
<a id="trunkLayoutTestsChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/LayoutTests/ChangeLog (188927 => 188928)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/ChangeLog        2015-08-25 19:07:54 UTC (rev 188927)
+++ trunk/LayoutTests/ChangeLog        2015-08-25 19:10:29 UTC (rev 188928)
</span><span class="lines">@@ -1,3 +1,16 @@
</span><ins>+2015-08-25 Skachkov Oleksandr <gskachkov@gmail.com>
+
+ Function.prototype.toString is incorrect for ArrowFunction
+ https://bugs.webkit.org/show_bug.cgi?id=148148
+
+ Reviewed by Saam Barati.
+
+ Added test of toString() method.
+
+ * js/arrowfunction-tostring-expected.txt: Added.
+ * js/arrowfunction-tostring.html: Added.
+ * js/script-tests/arrowfunction-tostring.js: Added.
+
</ins><span class="cx"> 2015-08-25 Myles C. Maxfield <mmaxfield@apple.com>
</span><span class="cx">
</span><span class="cx"> Test gardening
</span></span></pre></div>
<a id="trunkLayoutTestsjsarrowfunctiontostringexpectedtxt"></a>
<div class="addfile"><h4>Added: trunk/LayoutTests/js/arrowfunction-tostring-expected.txt (0 => 188928)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/js/arrowfunction-tostring-expected.txt         (rev 0)
+++ trunk/LayoutTests/js/arrowfunction-tostring-expected.txt        2015-08-25 19:10:29 UTC (rev 188928)
</span><span class="lines">@@ -0,0 +1,32 @@
</span><ins>+Tests for ES6 arrow function toString() method
+
+On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
+
+
+var simpleArrowFunction = () => {}
+PASS simpleArrowFunction.toString() is '() => {}'
+PASS ((x) => { x + 1 }).toString() is '(x) => { x + 1 }'
+PASS (x => x + 1).toString() is 'x => x + 1'
+var f0 = x => x
+PASS f0.toString() is 'x => x'
+var f1 = () => this
+PASS f1.toString() is '() => this'
+var f2 = x => { return x; };
+PASS f2.toString() is '(x) => { return x; }'
+var f3 = (x, y) => { return x + y; };
+PASS f3.toString() is '(x, y) => { return x + y; }'
+function foo(x) { return x.toString()};
+PASS foo((x)=>x) is '(x)=>x'
+var a = z => z*2, b = () => ({});
+PASS a.toString() is 'z => z*2'
+PASS b.toString() is '() => ({})'
+var arrExpr = [y=>y + 1, x=>x];
+PASS arrExpr[0].toString() is 'y=>y + 1'
+PASS arrExpr[1].toString() is 'x=>x'
+var arrBody = [y=>{ y + 1 }, x=>{ x }];
+PASS arrBody[0].toString() is 'y=>{ y + 1 }'
+PASS arrBody[1].toString() is 'x=>{ x }'
+PASS successfullyParsed is true
+
+TEST COMPLETE
+
</ins></span></pre></div>
<a id="trunkLayoutTestsjsarrowfunctiontostringhtml"></a>
<div class="addfile"><h4>Added: trunk/LayoutTests/js/arrowfunction-tostring.html (0 => 188928)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/js/arrowfunction-tostring.html         (rev 0)
+++ trunk/LayoutTests/js/arrowfunction-tostring.html        2015-08-25 19:10:29 UTC (rev 188928)
</span><span class="lines">@@ -0,0 +1,10 @@
</span><ins>+<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML//EN">
+<html>
+<head>
+<script src="../resources/js-test-pre.js"></script>
+</head>
+<body>
+<script src="script-tests/arrowfunction-tostring.js"></script>
+<script src="../resources/js-test-post.js"></script>
+</body>
+</html>
</ins></span></pre></div>
<a id="trunkLayoutTestsjsscripttestsarrowfunctiontostringjs"></a>
<div class="addfile"><h4>Added: trunk/LayoutTests/js/script-tests/arrowfunction-tostring.js (0 => 188928)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/js/script-tests/arrowfunction-tostring.js         (rev 0)
+++ trunk/LayoutTests/js/script-tests/arrowfunction-tostring.js        2015-08-25 19:10:29 UTC (rev 188928)
</span><span class="lines">@@ -0,0 +1,45 @@
</span><ins>+// Inspired by mozilla tests
+description('Tests for ES6 arrow function toString() method');
+
+debug('var simpleArrowFunction = () => {}');
+var simpleArrowFunction = () => {};
+shouldBe("simpleArrowFunction.toString()", "'() => {}'");
+shouldBe("((x) => { x + 1 }).toString()", "'(x) => { x + 1 }'");
+shouldBe("(x => x + 1).toString()", "'x => x + 1'");
+
+debug('var f0 = x => x');
+var f0 = x => x;
+shouldBe("f0.toString()", "'x => x'");
+
+debug('var f1 = () => this');
+var f1 = () => this;
+shouldBe("f1.toString()", "'() => this'");
+
+debug('var f2 = x => { return x; };');
+var f2 = (x) => { return x; };
+shouldBe("f2.toString()", "'(x) => { return x; }'");
+
+debug('var f3 = (x, y) => { return x + y; };');
+var f3 = (x, y) => { return x + y; };
+shouldBe("f3.toString()", "'(x, y) => { return x + y; }'");
+
+function foo(x) { return x.toString()};
+debug('function foo(x) { return x.toString()};');
+shouldBe("foo((x)=>x)", "'(x)=>x'");
+
+var a = z => z*2, b = () => ({});
+debug('var a = z => z*2, b = () => ({});');
+shouldBe("a.toString()", "'z => z*2'");
+shouldBe("b.toString()", "'() => ({})'");
+
+var arrExpr = [y=>y + 1, x=>x];
+debug('var arrExpr = [y=>y + 1, x=>x];');
+shouldBe("arrExpr[0].toString()", "'y=>y + 1'");
+shouldBe("arrExpr[1].toString()", "'x=>x'");
+
+var arrBody = [y=>{ y + 1 }, x=>{ x }];
+debug('var arrBody = [y=>{ y + 1 }, x=>{ x }];');
+shouldBe("arrBody[0].toString()", "'y=>{ y + 1 }'");
+shouldBe("arrBody[1].toString()", "'x=>{ x }'");
+
+var successfullyParsed = true;
</ins></span></pre></div>
<a id="trunkSourceJavaScriptCoreChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/ChangeLog (188927 => 188928)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/ChangeLog        2015-08-25 19:07:54 UTC (rev 188927)
+++ trunk/Source/JavaScriptCore/ChangeLog        2015-08-25 19:10:29 UTC (rev 188928)
</span><span class="lines">@@ -1,3 +1,27 @@
</span><ins>+2015-08-25 Aleksandr Skachkov <gskachkov@gmail.com>
+
+ Function.prototype.toString is incorrect for ArrowFunction
+ https://bugs.webkit.org/show_bug.cgi?id=148148
+
+ Reviewed by Saam Barati.
+
+ Added correct support of toString() method for arrow function.
+
+ * parser/ASTBuilder.h:
+ (JSC::ASTBuilder::createFunctionMetadata):
+ (JSC::ASTBuilder::createArrowFunctionExpr):
+ * parser/Nodes.cpp:
+ (JSC::FunctionMetadataNode::FunctionMetadataNode):
+ * parser/Nodes.h:
+ * parser/Parser.cpp:
+ (JSC::Parser<LexerType>::parseFunctionBody):
+ (JSC::Parser<LexerType>::parseFunctionInfo):
+ * parser/SyntaxChecker.h:
+ (JSC::SyntaxChecker::createFunctionMetadata):
+ * runtime/FunctionPrototype.cpp:
+ (JSC::functionProtoFuncToString):
+ * tests/stress/arrowfunction-tostring.js: Added.
+
</ins><span class="cx"> 2015-08-25 Saam barati <sbarati@apple.com>
</span><span class="cx">
</span><span class="cx"> Callee can be incorrectly overridden when it's captured
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreparserASTBuilderh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/parser/ASTBuilder.h (188927 => 188928)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/parser/ASTBuilder.h        2015-08-25 19:07:54 UTC (rev 188927)
+++ trunk/Source/JavaScriptCore/parser/ASTBuilder.h        2015-08-25 19:10:29 UTC (rev 188928)
</span><span class="lines">@@ -361,18 +361,18 @@
</span><span class="cx"> const JSTokenLocation& startLocation, const JSTokenLocation& 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, unsigned parameterCount, SourceParseMode mode, bool isArrowFunction)
</del><ins>+ ConstructorKind constructorKind, unsigned parameterCount, SourceParseMode mode, bool isArrowFunction, bool isArrowFunctionBodyExpression)
</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, parameterCount, mode, isArrowFunction);
</del><ins>+ inStrictContext, constructorKind, parameterCount, mode, isArrowFunction, isArrowFunctionBodyExpression);
</ins><span class="cx"> }
</span><span class="cx">
</span><span class="cx"> ExpressionNode* createArrowFunctionExpr(const JSTokenLocation& location, const ParserFunctionInfo<ASTBuilder>& functionInfo)
</span><span class="cx"> {
</span><span class="cx"> usesThis();
</span><del>- SourceCode source = m_sourceCode->subExpression(functionInfo.startOffset, functionInfo.endOffset, functionInfo.startLine, functionInfo.bodyStartColumn);
</del><ins>+ SourceCode source = m_sourceCode->subExpression(functionInfo.startOffset, functionInfo.body->isArrowFunctionBodyExpression() ? functionInfo.endOffset - 1 : functionInfo.endOffset, functionInfo.startLine, functionInfo.bodyStartColumn);
</ins><span class="cx"> ArrowFuncExprNode* result = new (m_parserArena) ArrowFuncExprNode(location, *functionInfo.name, functionInfo.body, source);
</span><span class="cx"> functionInfo.body->setLoc(functionInfo.startLine, functionInfo.endLine, location.startOffset, location.lineStartOffset);
</span><span class="cx"> return result;
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreparserNodescpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/parser/Nodes.cpp (188927 => 188928)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/parser/Nodes.cpp        2015-08-25 19:07:54 UTC (rev 188927)
+++ trunk/Source/JavaScriptCore/parser/Nodes.cpp        2015-08-25 19:10:29 UTC (rev 188928)
</span><span class="lines">@@ -151,7 +151,7 @@
</span><span class="cx"> ParserArena&, const JSTokenLocation& startLocation,
</span><span class="cx"> const JSTokenLocation& endLocation, unsigned startColumn, unsigned endColumn,
</span><span class="cx"> int functionKeywordStart, int functionNameStart, int parametersStart, bool isInStrictContext,
</span><del>- ConstructorKind constructorKind, unsigned parameterCount, SourceParseMode mode, bool isArrowFunction)
</del><ins>+ ConstructorKind constructorKind, unsigned parameterCount, SourceParseMode mode, bool isArrowFunction, bool isArrowFunctionBodyExpression)
</ins><span class="cx"> : Node(endLocation)
</span><span class="cx"> , m_startColumn(startColumn)
</span><span class="cx"> , m_endColumn(endColumn)
</span><span class="lines">@@ -164,6 +164,7 @@
</span><span class="cx"> , m_isInStrictContext(isInStrictContext)
</span><span class="cx"> , m_constructorKind(static_cast<unsigned>(constructorKind))
</span><span class="cx"> , m_isArrowFunction(isArrowFunction)
</span><ins>+ , m_isArrowFunctionBodyExpression(isArrowFunctionBodyExpression)
</ins><span class="cx"> {
</span><span class="cx"> ASSERT(m_constructorKind == static_cast<unsigned>(constructorKind));
</span><span class="cx"> }
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreparserNodesh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/parser/Nodes.h (188927 => 188928)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/parser/Nodes.h        2015-08-25 19:07:54 UTC (rev 188927)
+++ trunk/Source/JavaScriptCore/parser/Nodes.h        2015-08-25 19:10:29 UTC (rev 188928)
</span><span class="lines">@@ -1808,7 +1808,7 @@
</span><span class="cx"> ParserArena&, const JSTokenLocation& start, const JSTokenLocation& end,
</span><span class="cx"> unsigned startColumn, unsigned endColumn, int functionKeywordStart,
</span><span class="cx"> int functionNameStart, int parametersStart, bool isInStrictContext,
</span><del>- ConstructorKind, unsigned, SourceParseMode, bool isArrowFunction);
</del><ins>+ ConstructorKind, unsigned, SourceParseMode, bool isArrowFunction, bool isArrowFunctionBodyExpression);
</ins><span class="cx">
</span><span class="cx"> void finishParsing(const SourceCode&, const Identifier&, FunctionMode);
</span><span class="cx">
</span><span class="lines">@@ -1835,6 +1835,7 @@
</span><span class="cx"> bool isInStrictContext() const { return m_isInStrictContext; }
</span><span class="cx"> ConstructorKind constructorKind() { return static_cast<ConstructorKind>(m_constructorKind); }
</span><span class="cx"> bool isArrowFunction() const { return m_isArrowFunction; }
</span><ins>+ bool isArrowFunctionBodyExpression() const { return m_isArrowFunctionBodyExpression; }
</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">@@ -1861,6 +1862,7 @@
</span><span class="cx"> unsigned m_isInStrictContext : 1;
</span><span class="cx"> unsigned m_constructorKind : 2;
</span><span class="cx"> unsigned m_isArrowFunction : 1;
</span><ins>+ unsigned m_isArrowFunctionBodyExpression : 1;
</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 (188927 => 188928)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/parser/Parser.cpp        2015-08-25 19:07:54 UTC (rev 188927)
+++ trunk/Source/JavaScriptCore/parser/Parser.cpp        2015-08-25 19:10:29 UTC (rev 188928)
</span><span class="lines">@@ -1547,11 +1547,12 @@
</span><span class="cx"> ConstructorKind constructorKind, FunctionBodyType bodyType, unsigned parameterCount, SourceParseMode parseMode)
</span><span class="cx"> {
</span><span class="cx"> bool isArrowFunction = FunctionBodyType::StandardFunctionBodyBlock != bodyType;
</span><del>- if (bodyType == StandardFunctionBodyBlock || bodyType == ArrowFunctionBodyBlock) {
</del><ins>+ bool isArrowFunctionBodyExpression = bodyType == ArrowFunctionBodyExpression;
+ if (!isArrowFunctionBodyExpression) {
</ins><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, parameterCount, parseMode, isArrowFunction);
</del><ins>+ return context.createFunctionMetadata(startLocation, tokenLocation(), startColumn, endColumn, functionKeywordStart, functionNameStart, parametersStart, strictMode(), constructorKind, parameterCount, parseMode, isArrowFunction, isArrowFunctionBodyExpression);
</ins><span class="cx"> }
</span><span class="cx"> }
</span><span class="cx">
</span><span class="lines">@@ -1563,7 +1564,7 @@
</span><span class="cx"> else
</span><span class="cx"> failIfFalse(parseSourceElements(syntaxChecker, CheckForStrictMode), bodyType == StandardFunctionBodyBlock ? "Cannot parse body of this function" : "Cannot parse body of this arrow function");
</span><span class="cx"> unsigned endColumn = tokenColumn();
</span><del>- return context.createFunctionMetadata(startLocation, tokenLocation(), startColumn, endColumn, functionKeywordStart, functionNameStart, parametersStart, strictMode(), constructorKind, parameterCount, parseMode, isArrowFunction);
</del><ins>+ return context.createFunctionMetadata(startLocation, tokenLocation(), startColumn, endColumn, functionKeywordStart, functionNameStart, parametersStart, strictMode(), constructorKind, parameterCount, parseMode, isArrowFunction, isArrowFunctionBodyExpression);
</ins><span class="cx"> }
</span><span class="cx">
</span><span class="cx"> static const char* stringForFunctionMode(SourceParseMode mode)
</span><span class="lines">@@ -1763,7 +1764,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->strictMode, constructorKind, cachedInfo->parameterCount, mode, isArrowFunction);
</del><ins>+ cachedInfo->strictMode, constructorKind, cachedInfo->parameterCount, mode, isArrowFunction, functionBodyType == ArrowFunctionBodyExpression);
</ins><span class="cx">
</span><span class="cx"> functionScope->restoreFromSourceProviderCache(cachedInfo);
</span><span class="cx"> popScope(functionScope, TreeBuilder::NeedsFreeVariableInfo);
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreparserSyntaxCheckerh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/parser/SyntaxChecker.h (188927 => 188928)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/parser/SyntaxChecker.h        2015-08-25 19:07:54 UTC (rev 188927)
+++ trunk/Source/JavaScriptCore/parser/SyntaxChecker.h        2015-08-25 19:10:29 UTC (rev 188928)
</span><span class="lines">@@ -186,7 +186,7 @@
</span><span class="cx"> ClassExpression createClassExpr(const JSTokenLocation&, const Identifier&, ExpressionType, ExpressionType, PropertyList, PropertyList) { return ClassExpr; }
</span><span class="cx"> #endif
</span><span class="cx"> ExpressionType createFunctionExpr(const JSTokenLocation&, const ParserFunctionInfo<SyntaxChecker>&) { return FunctionExpr; }
</span><del>- int createFunctionMetadata(const JSTokenLocation&, const JSTokenLocation&, int, int, bool, int, int, int, ConstructorKind, unsigned, SourceParseMode, bool) { return FunctionBodyResult; }
</del><ins>+ int createFunctionMetadata(const JSTokenLocation&, const JSTokenLocation&, int, int, bool, int, int, int, ConstructorKind, unsigned, SourceParseMode, bool, bool) { return FunctionBodyResult; }
</ins><span class="cx"> ExpressionType createArrowFunctionExpr(const JSTokenLocation&, const ParserFunctionInfo<SyntaxChecker>&) { return FunctionExpr; }
</span><span class="cx"> void setFunctionNameStart(int, int) { }
</span><span class="cx"> int createArguments() { return ArgumentsResult; }
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreruntimeFunctionPrototypecpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/runtime/FunctionPrototype.cpp (188927 => 188928)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/runtime/FunctionPrototype.cpp        2015-08-25 19:07:54 UTC (rev 188927)
+++ trunk/Source/JavaScriptCore/runtime/FunctionPrototype.cpp        2015-08-25 19:10:29 UTC (rev 188928)
</span><span class="lines">@@ -88,10 +88,13 @@
</span><span class="cx"> return JSValue::encode(jsMakeNontrivialString(exec, "function ", function->name(exec), "() {\n [native code]\n}"));
</span><span class="cx">
</span><span class="cx"> FunctionExecutable* executable = function->jsExecutable();
</span><ins>+
+ String functionHeader = executable->isArrowFunction() ? "" : "function ";
+
</ins><span class="cx"> String source = executable->source().provider()->getRange(
</span><span class="cx"> executable->parametersStartOffset(),
</span><span class="cx"> executable->typeProfilingEndOffset() + 1); // Type profiling end offset is the character before the '}'.
</span><del>- return JSValue::encode(jsMakeNontrivialString(exec, "function ", function->name(exec), source));
</del><ins>+ return JSValue::encode(jsMakeNontrivialString(exec, functionHeader, function->name(exec), source));
</ins><span class="cx"> }
</span><span class="cx">
</span><span class="cx"> if (thisValue.inherits(InternalFunction::info())) {
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoretestsstressarrowfunctiontostringjs"></a>
<div class="addfile"><h4>Added: trunk/Source/JavaScriptCore/tests/stress/arrowfunction-tostring.js (0 => 188928)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/tests/stress/arrowfunction-tostring.js         (rev 0)
+++ trunk/Source/JavaScriptCore/tests/stress/arrowfunction-tostring.js        2015-08-25 19:10:29 UTC (rev 188928)
</span><span class="lines">@@ -0,0 +1,20 @@
</span><ins>+var testCase = function (actual, expected, message) {
+ if (actual !== expected) {
+ throw message + ". Expected '" + expected + "', but was '" + actual + "'";
+ }
+};
+
+var af1 = () => {};
+var af2 = (a) => { a + 1 };
+var af3 = x => x + 1;
+var af4 = (x, y) => x + y;
+
+noInline(af1);
+noInline(af2);
+
+for (var i = 0; i < 10000; ++i) {
+ testCase(af1.toString(), '() => {}', "Error: Not correct toString in arrow function #1");
+ testCase(af2.toString(), '(a) => { a + 1 }', "Error: Not correct toString in arrow function #2");
+ testCase(af3.toString(), 'x => x + 1', "Error: Not correct toString in arrow function #3");
+ testCase(af4.toString(), '(x, y) => x + y', "Error: Not correct toString in arrow function #4");
+}
</ins></span></pre>
</div>
</div>
</body>
</html>