<!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>[202074] 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/202074">202074</a></dd>
<dt>Author</dt> <dd>commit-queue@webkit.org</dd>
<dt>Date</dt> <dd>2016-06-14 17:45:25 -0700 (Tue, 14 Jun 2016)</dd>
</dl>
<h3>Log Message</h3>
<pre>The parser doesn't properly parse "super" when default parameter is an
arrow function.
https://bugs.webkit.org/show_bug.cgi?id=157872.
Patch by Caio Lima <ticaiolima@gmail.com> on 2016-06-14
Reviewed by Saam Barati.
The "super" member or "super()" could not be used when default parameter is an
arrow function, resuling in sytax error. It happened because the
"closestOrdinaryFunctionScope" was not being initialized properly
before "parseFunctionParameters" step and the condition
"functionSuperBinding == SuperBinding::NotNeeded" or
"functionConstructorKind != ConstructorKind::Derived" on
"Parser<LexerType>::parseMemberExpression" step were being true
resulting in SyntaxError.
* parser/Parser.cpp:
(JSC::Parser<LexerType>::parseFunctionInfo): setting
"functionScope->setExpectedSuperBinding(expectedSuperBinding)" and
"functionScope->setConstructorKind(constructorKind)" before
"parseFunctionParameters" step.</pre>
<h3>Modified Paths</h3>
<ul>
<li><a href="#trunkLayoutTestsjsparsersyntaxcheckexpectedtxt">trunk/LayoutTests/js/parser-syntax-check-expected.txt</a></li>
<li><a href="#trunkLayoutTestsjsscripttestsparsersyntaxcheckjs">trunk/LayoutTests/js/script-tests/parser-syntax-check.js</a></li>
<li><a href="#trunkSourceJavaScriptCoreChangeLog">trunk/Source/JavaScriptCore/ChangeLog</a></li>
<li><a href="#trunkSourceJavaScriptCoreparserParsercpp">trunk/Source/JavaScriptCore/parser/Parser.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoretestsstressarrowfunctionsasdefaultparametervaluesjs">trunk/Source/JavaScriptCore/tests/stress/arrow-functions-as-default-parameter-values.js</a></li>
</ul>
</div>
<div id="patch">
<h3>Diff</h3>
<a id="trunkLayoutTestsjsparsersyntaxcheckexpectedtxt"></a>
<div class="modfile"><h4>Modified: trunk/LayoutTests/js/parser-syntax-check-expected.txt (202073 => 202074)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/js/parser-syntax-check-expected.txt        2016-06-15 00:43:23 UTC (rev 202073)
+++ trunk/LayoutTests/js/parser-syntax-check-expected.txt        2016-06-15 00:45:25 UTC (rev 202074)
</span><span class="lines">@@ -1259,6 +1259,18 @@
</span><span class="cx"> PASS Invalid: "function f() { var f = cond ? x=>{x.foo :} : x=>x + x + x + x + x + x + x }"
</span><span class="cx"> PASS Invalid: "var f = cond ? x=>{x.foo } => : x=>x + x + x + x + x + x + x"
</span><span class="cx"> PASS Invalid: "function f() { var f = cond ? x=>{x.foo } => : x=>x + x + x + x + x + x + x }"
</span><ins>+PASS Valid: "class C { constructor() { this._x = 45; } get foo() { return this._x;} } class D extends C { x(y = () => super.foo) { return y(); } }"
+PASS Valid: "function f() { class C { constructor() { this._x = 45; } get foo() { return this._x;} } class D extends C { x(y = () => super.foo) { return y(); } } }"
+PASS Valid: "class C { constructor() { this._x = 45; } get foo() { return this._x;} } class D extends C { x(y = () => {return super.foo}) { return y(); } }"
+PASS Valid: "function f() { class C { constructor() { this._x = 45; } get foo() { return this._x;} } class D extends C { x(y = () => {return super.foo}) { return y(); } } }"
+PASS Valid: "class C { constructor() { this._x = 45; } get foo() { return this._x;} } class D extends C { x(y = () => {return () => super.foo}) { return y()(); } }"
+PASS Valid: "function f() { class C { constructor() { this._x = 45; } get foo() { return this._x;} } class D extends C { x(y = () => {return () => super.foo}) { return y()(); } } }"
+PASS Valid: "class C { constructor() { this._x = 45; } get foo() { return this._x;} } class D extends C { x(y = (y = () => super.foo) => {return y()}) { return y(); } }"
+PASS Valid: "function f() { class C { constructor() { this._x = 45; } get foo() { return this._x;} } class D extends C { x(y = (y = () => super.foo) => {return y()}) { return y(); } } }"
+PASS Valid: "class C { constructor() { this._x = 45; } get foo() { return this._x;} } class D extends C { constructor(x = () => super.foo) { super(); this._x_f = x; } x() { return this._x_f(); } }"
+PASS Valid: "function f() { class C { constructor() { this._x = 45; } get foo() { return this._x;} } class D extends C { constructor(x = () => super.foo) { super(); this._x_f = x; } x() { return this._x_f(); } } }"
+PASS Valid: "class C { constructor() { this._x = 45; } get foo() { return this._x;} } class D extends C { constructor(x = () => super()) { x(); } x() { return super.foo; } }"
+PASS Valid: "function f() { class C { constructor() { this._x = 45; } get foo() { return this._x;} } class D extends C { constructor(x = () => super()) { x(); } x() { return super.foo; } } }"
</ins><span class="cx"> PASS e.line is 1
</span><span class="cx"> PASS foo is 'PASS'
</span><span class="cx"> PASS bar is 'PASS'
</span></span></pre></div>
<a id="trunkLayoutTestsjsscripttestsparsersyntaxcheckjs"></a>
<div class="modfile"><h4>Modified: trunk/LayoutTests/js/script-tests/parser-syntax-check.js (202073 => 202074)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/js/script-tests/parser-syntax-check.js        2016-06-15 00:43:23 UTC (rev 202073)
+++ trunk/LayoutTests/js/script-tests/parser-syntax-check.js        2016-06-15 00:45:25 UTC (rev 202074)
</span><span class="lines">@@ -740,8 +740,13 @@
</span><span class="cx"> invalid("var f = cond ? x=>x.foo : : x=>x + x + x + x + x + x + x");
</span><span class="cx"> invalid("var f = cond ? x=>{x.foo :} : x=>x + x + x + x + x + x + x");
</span><span class="cx"> invalid("var f = cond ? x=>{x.foo } => : x=>x + x + x + x + x + x + x");
</span><ins>+valid("class C { constructor() { this._x = 45; } get foo() { return this._x;} } class D extends C { x(y = () => super.foo) { return y(); } }");
+valid("class C { constructor() { this._x = 45; } get foo() { return this._x;} } class D extends C { x(y = () => {return super.foo}) { return y(); } }");
+valid("class C { constructor() { this._x = 45; } get foo() { return this._x;} } class D extends C { x(y = () => {return () => super.foo}) { return y()(); } }");
+valid("class C { constructor() { this._x = 45; } get foo() { return this._x;} } class D extends C { x(y = (y = () => super.foo) => {return y()}) { return y(); } }");
+valid("class C { constructor() { this._x = 45; } get foo() { return this._x;} } class D extends C { constructor(x = () => super.foo) { super(); this._x_f = x; } x() { return this._x_f(); } }");
+valid("class C { constructor() { this._x = 45; } get foo() { return this._x;} } class D extends C { constructor(x = () => super()) { x(); } x() { return super.foo; } }");
</ins><span class="cx">
</span><del>-
</del><span class="cx"> try { eval("a.b.c = {};"); } catch(e1) { e=e1; shouldBe("e.line", "1") }
</span><span class="cx"> foo = 'FAIL';
</span><span class="cx"> bar = 'PASS';
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/ChangeLog (202073 => 202074)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/ChangeLog        2016-06-15 00:43:23 UTC (rev 202073)
+++ trunk/Source/JavaScriptCore/ChangeLog        2016-06-15 00:45:25 UTC (rev 202074)
</span><span class="lines">@@ -1,3 +1,26 @@
</span><ins>+2016-06-14 Caio Lima <ticaiolima@gmail.com>
+
+ The parser doesn't properly parse "super" when default parameter is an
+ arrow function.
+ https://bugs.webkit.org/show_bug.cgi?id=157872.
+
+ Reviewed by Saam Barati.
+
+ The "super" member or "super()" could not be used when default parameter is an
+ arrow function, resuling in sytax error. It happened because the
+ "closestOrdinaryFunctionScope" was not being initialized properly
+ before "parseFunctionParameters" step and the condition
+ "functionSuperBinding == SuperBinding::NotNeeded" or
+ "functionConstructorKind != ConstructorKind::Derived" on
+ "Parser<LexerType>::parseMemberExpression" step were being true
+ resulting in SyntaxError.
+
+ * parser/Parser.cpp:
+ (JSC::Parser<LexerType>::parseFunctionInfo): setting
+ "functionScope->setExpectedSuperBinding(expectedSuperBinding)" and
+ "functionScope->setConstructorKind(constructorKind)" before
+ "parseFunctionParameters" step.
+
</ins><span class="cx"> 2016-06-14 Joseph Pecoraro <pecoraro@apple.com>
</span><span class="cx">
</span><span class="cx"> Web Inspector: Rename Timeline.setAutoCaptureInstruments to Timeline.setInstruments
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreparserParsercpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/parser/Parser.cpp (202073 => 202074)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/parser/Parser.cpp        2016-06-15 00:43:23 UTC (rev 202073)
+++ trunk/Source/JavaScriptCore/parser/Parser.cpp        2016-06-15 00:45:25 UTC (rev 202074)
</span><span class="lines">@@ -1927,6 +1927,8 @@
</span><span class="cx"> bool upperScopeIsGenerator = currentScope()->isGenerator();
</span><span class="cx"> AutoPopScopeRef functionScope(this, pushScope());
</span><span class="cx"> functionScope->setSourceParseMode(mode);
</span><ins>+ functionScope->setExpectedSuperBinding(expectedSuperBinding);
+ functionScope->setConstructorKind(constructorKind);
</ins><span class="cx"> SetForScope<FunctionParsePhase> functionParsePhasePoisoner(m_parserState.functionParsePhase, FunctionParsePhase::Body);
</span><span class="cx"> int functionNameStart = m_token.m_location.startOffset;
</span><span class="cx"> const Identifier* lastFunctionName = m_parserState.lastFunctionName;
</span><span class="lines">@@ -1948,8 +1950,6 @@
</span><span class="cx">
</span><span class="cx"> ConstructorKind constructorKind = static_cast<ConstructorKind>(cachedInfo->constructorKind);
</span><span class="cx"> SuperBinding expectedSuperBinding = static_cast<SuperBinding>(cachedInfo->expectedSuperBinding);
</span><del>- functionScope->setConstructorKind(constructorKind);
- functionScope->setExpectedSuperBinding(expectedSuperBinding);
</del><span class="cx">
</span><span class="cx"> endLocation.line = cachedInfo->lastTokenLine;
</span><span class="cx"> endLocation.startOffset = cachedInfo->lastTokenStartOffset;
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoretestsstressarrowfunctionsasdefaultparametervaluesjs"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/tests/stress/arrow-functions-as-default-parameter-values.js (202073 => 202074)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/tests/stress/arrow-functions-as-default-parameter-values.js        2016-06-15 00:43:23 UTC (rev 202073)
+++ trunk/Source/JavaScriptCore/tests/stress/arrow-functions-as-default-parameter-values.js        2016-06-15 00:45:25 UTC (rev 202074)
</span><span class="lines">@@ -106,23 +106,98 @@
</span><span class="cx"> foo();
</span><span class="cx"> });
</span><span class="cx">
</span><del>-// FIXME: Our parser throws a syntax error here but it should not.
-// https://bugs.webkit.org/show_bug.cgi?id=157872
-/*
</del><span class="cx"> test(function() {
</span><span class="cx"> class C {
</span><span class="cx"> constructor() { this._x = 45; }
</span><span class="cx"> get foo() { return this._x;}
</span><span class="cx"> }
</span><span class="cx"> class D extends C {
</span><del>- //constructor(x = ()=>super.foo) {
- // super();
- // assert(x() === 45);
- //}
</del><ins>+ constructor(x = () => super.foo) {
+ super();
+ assert(x() === 45);
+ }
</ins><span class="cx"> x(x = ()=>super.foo) {
</span><span class="cx"> return x();
</span><span class="cx"> }
</span><span class="cx"> }
</span><del>- //(new D).x();
</del><ins>+ assert((new D).x() === 45);
</ins><span class="cx"> });
</span><del>-*/
</del><ins>+
+test(function() {
+ class C {
+ constructor() { this._x = 45; }
+ get foo() { return this._x;}
+ }
+ class D extends C {
+ x(x = () => {return super.foo}) {
+ return x();
+ }
+ }
+ assert((new D).x() === 45);
+});
+
+test(function() {
+ class C {
+ constructor() { this._x = 45; }
+ get foo() { return this._x;}
+ }
+ class D extends C {
+ x(x = () => {return () => super.foo}) {
+ return x()();
+ }
+ }
+ assert((new D).x() === 45);
+});
+
+test(function() {
+ class C {
+ constructor() { this._x = 45; }
+ get foo() { return this._x;}
+ }
+
+ class D extends C {
+ x(y = (y = () => super.foo) => {return y()}) {
+ return y();
+ }
+ }
+ assert((new D).x() === 45);
+});
+
+test(function() {
+ class C {
+ constructor() { this._x = 45; }
+ get foo() { return this._x;}
+ }
+
+ class D extends C {
+ constructor(x = () => super.foo) {
+ super();
+ this._x_f = x;
+ }
+
+ x() {
+ return this._x_f();
+ }
+ }
+ assert((new D).x() === 45);
+});
+
+test(function() {
+ class C {
+ constructor() { this._x = 45; }
+ get foo() { return this._x;}
+ }
+
+ class D extends C {
+
+ constructor(x = () => super()) {
+ x();
+ }
+
+ x() {
+ return super.foo;
+ }
+ }
+ assert((new D).x() === 45);
+});
+
</ins></span></pre>
</div>
</div>
</body>
</html>