<!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>[185699] 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/185699">185699</a></dd>
<dt>Author</dt> <dd>saambarati1@gmail.com</dd>
<dt>Date</dt> <dd>2015-06-18 05:35:32 -0700 (Thu, 18 Jun 2015)</dd>
</dl>
<h3>Log Message</h3>
<pre>[ES6] support default values in deconstruction parameter nodes
https://bugs.webkit.org/show_bug.cgi?id=142679
Reviewed by Darin Adler.
Source/JavaScriptCore:
ES6 destructuring allows destructuring properties to assign
default values. A link to the spec:
https://people.mozilla.org/~jorendorff/es6-draft.html#sec-destructuring-binding-patterns
This patch implements default values for all places where deconstruction
is allowed besides function parameters. This is because function
parameters are parsed in a separate parser arena than the function
body itself and ExpresionNode's which are default values for
deconstruction parameters will be deallocated by the time we parse the body
of the function. I have opened a bug to address this problem:
https://bugs.webkit.org/show_bug.cgi?id=145995
* bytecompiler/NodesCodegen.cpp:
(JSC::DeconstructionPatternNode::~DeconstructionPatternNode):
(JSC::assignDefaultValueIfUndefined):
(JSC::ArrayPatternNode::bindValue):
(JSC::ArrayPatternNode::emitDirectBinding):
(JSC::ArrayPatternNode::toString):
(JSC::ArrayPatternNode::collectBoundIdentifiers):
(JSC::ObjectPatternNode::bindValue):
* parser/ASTBuilder.h:
(JSC::ASTBuilder::appendArrayPatternSkipEntry):
(JSC::ASTBuilder::appendArrayPatternEntry):
(JSC::ASTBuilder::createObjectPattern):
(JSC::ASTBuilder::appendObjectPatternEntry):
(JSC::ASTBuilder::createBindingLocation):
* parser/Nodes.h:
(JSC::ArrayPatternNode::appendIndex):
(JSC::ObjectPatternNode::appendEntry):
(JSC::ObjectPatternNode::Entry::Entry): Deleted.
* parser/Parser.cpp:
(JSC::Parser<LexerType>::parseDeconstructionPattern):
(JSC::Parser<LexerType>::parseDefaultValueForDeconstructionPattern):
(JSC::Parser<LexerType>::parseConstDeclarationList):
* parser/Parser.h:
* parser/SyntaxChecker.h:
(JSC::SyntaxChecker::operatorStackPop):
LayoutTests:
* js/destructuring-assignment-default-values-expected.txt: Added.
* js/destructuring-assignment-default-values.html: Added.
* js/script-tests/destructuring-assignment-default-values.js: Added.
(assert):
(test1):
(arr):
(test2):
(test3):
(test4):
(test5):
(test6):
(test7):
(test8):
(shouldThrow):</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="#trunkSourceJavaScriptCorebytecompilerNodesCodegencpp">trunk/Source/JavaScriptCore/bytecompiler/NodesCodegen.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoreparserASTBuilderh">trunk/Source/JavaScriptCore/parser/ASTBuilder.h</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="#trunkSourceJavaScriptCoreparserSyntaxCheckerh">trunk/Source/JavaScriptCore/parser/SyntaxChecker.h</a></li>
</ul>
<h3>Added Paths</h3>
<ul>
<li><a href="#trunkLayoutTestsjsdestructuringassignmentdefaultvaluesexpectedtxt">trunk/LayoutTests/js/destructuring-assignment-default-values-expected.txt</a></li>
<li><a href="#trunkLayoutTestsjsdestructuringassignmentdefaultvalueshtml">trunk/LayoutTests/js/destructuring-assignment-default-values.html</a></li>
<li><a href="#trunkLayoutTestsjsscripttestsdestructuringassignmentdefaultvaluesjs">trunk/LayoutTests/js/script-tests/destructuring-assignment-default-values.js</a></li>
</ul>
</div>
<div id="patch">
<h3>Diff</h3>
<a id="trunkLayoutTestsChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/LayoutTests/ChangeLog (185698 => 185699)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/ChangeLog        2015-06-18 09:22:48 UTC (rev 185698)
+++ trunk/LayoutTests/ChangeLog        2015-06-18 12:35:32 UTC (rev 185699)
</span><span class="lines">@@ -1,3 +1,25 @@
</span><ins>+2015-06-18 Saam Barati <saambarati1@gmail.com>
+
+ [ES6] support default values in deconstruction parameter nodes
+ https://bugs.webkit.org/show_bug.cgi?id=142679
+
+ Reviewed by Darin Adler.
+
+ * js/destructuring-assignment-default-values-expected.txt: Added.
+ * js/destructuring-assignment-default-values.html: Added.
+ * js/script-tests/destructuring-assignment-default-values.js: Added.
+ (assert):
+ (test1):
+ (arr):
+ (test2):
+ (test3):
+ (test4):
+ (test5):
+ (test6):
+ (test7):
+ (test8):
+ (shouldThrow):
+
</ins><span class="cx"> 2015-06-18 Youenn Fablet <youenn.fablet@crf.canon.fr> and Xabier Rodriguez Calvar <calvaris@igalia.com>
</span><span class="cx">
</span><span class="cx"> [Streams API] Implement ReadableStreamReader.releaseLock
</span></span></pre></div>
<a id="trunkLayoutTestsjsdestructuringassignmentdefaultvaluesexpectedtxt"></a>
<div class="addfile"><h4>Added: trunk/LayoutTests/js/destructuring-assignment-default-values-expected.txt (0 => 185699)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/js/destructuring-assignment-default-values-expected.txt         (rev 0)
+++ trunk/LayoutTests/js/destructuring-assignment-default-values-expected.txt        2015-06-18 12:35:32 UTC (rev 185699)
</span><span class="lines">@@ -0,0 +1,44 @@
</span><ins>+Test default values in destructuring patterns: https://people.mozilla.org/~jorendorff/es6-draft.html#sec-destructuring-binding-patterns
+
+On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
+
+
+PASS 40,40
+PASS 40,40
+PASS 100,100
+PASS Hello,Hello
+PASS 20,20
+PASS 30,30
+PASS Hello,Hello
+PASS 20,20
+PASS 30,30
+PASS z,z
+PASS zz,zz
+PASS 40,40
+PASS 50,50
+PASS 40,40
+PASS 50,50
+PASS 100,100
+PASS null,null
+PASS false,false
+PASS 0,0
+PASS 50,50
+PASS 51,51
+PASS 51,51
+PASS 52,52
+PASS undefined,undefined
+PASS undefined,undefined
+PASS 10,10
+PASS 30,30
+PASS 120,120
+PASS 3628800,3628800
+PASS 1,1
+PASS true,true
+PASS true,true
+PASS true,true
+PASS true,true
+PASS true,true
+PASS successfullyParsed is true
+
+TEST COMPLETE
+
</ins></span></pre></div>
<a id="trunkLayoutTestsjsdestructuringassignmentdefaultvalueshtml"></a>
<div class="addfile"><h4>Added: trunk/LayoutTests/js/destructuring-assignment-default-values.html (0 => 185699)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/js/destructuring-assignment-default-values.html         (rev 0)
+++ trunk/LayoutTests/js/destructuring-assignment-default-values.html        2015-06-18 12:35:32 UTC (rev 185699)
</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/destructuring-assignment-default-values.js"></script>
+<script src="../resources/js-test-post.js"></script>
+</body>
+</html>
</ins></span></pre></div>
<a id="trunkLayoutTestsjsscripttestsdestructuringassignmentdefaultvaluesjs"></a>
<div class="addfile"><h4>Added: trunk/LayoutTests/js/script-tests/destructuring-assignment-default-values.js (0 => 185699)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/js/script-tests/destructuring-assignment-default-values.js         (rev 0)
+++ trunk/LayoutTests/js/script-tests/destructuring-assignment-default-values.js        2015-06-18 12:35:32 UTC (rev 185699)
</span><span class="lines">@@ -0,0 +1,125 @@
</span><ins>+description("Test default values in destructuring patterns: https://people.mozilla.org/~jorendorff/es6-draft.html#sec-destructuring-binding-patterns");
+function assert(a, b) {
+ if (b === a)
+ testPassed(a + "," + b);
+ else
+ testFailed(a + "," + b);
+}
+
+function test1() {
+ var {x = 40} = {};
+ var {prop: y = 40} = {};
+ var {prop: {z} = {z: 100}} = {};
+ assert(x, 40);
+ assert(y, 40);
+ assert(z, 100);
+}
+test1();
+
+function arr() { return [undefined, 20, undefined]; }
+
+function test2() {
+ var [x = "Hello", y = 40, z = 30] = [undefined, 20, undefined];
+ assert(x, "Hello");
+ assert(y, 20);
+ assert(z, 30);
+ var [x = "Hello", y = 40, z = 30] = arr();
+ assert(x, "Hello");
+ assert(y, 20);
+ assert(z, 30);
+}
+test2();
+
+
+function test3() {
+ var z = "z";
+ var [x = z] = [];
+ assert(x, "z");
+ z = "zz";
+ var [x = eval("z")] = [];
+ assert(x, "zz");
+
+ var [{a} = {a: 40}] = [undefined];
+ assert(a, 40);
+ var [{a = 50}] = [{a: undefined}];
+ assert(a, 50);
+}
+test3();
+
+
+function test4() {
+ var [{prop: {b = 40}}] = [{prop: {b: undefined}}];
+ var [{prop: [c = 50]}] = [{prop: []}];
+ var [{prop: [d = 60]} = {prop: [100]}] = [];
+ assert(b, 40);
+ assert(c, 50);
+ assert(d, 100)
+}
+test4();
+
+
+function test5() {
+ var {x = undefined} = {x: null};
+ assert(x, null);
+ var {x = undefined} = {x: false};
+ assert(x, false);
+ var {x = undefined} = {x: 0};
+ assert(x, 0);
+}
+test5();
+
+
+function test6() {
+ var [x = 50, y = x + 1] = [];
+ assert(x, 50);
+ assert(y, 51);
+
+ var [x = y, y = x + 1] = [];
+ assert(x, 51);
+ assert(y, 52);
+
+ // FIXME: make tests for TDZ failures when we land block scoping 'let' and 'const'.
+ var [a = b, b = a] = [];
+ assert(a, undefined);
+ assert(b, undefined);
+}
+test6();
+
+
+function test7(a, b) {
+ var {c = a, d = c + b} = {};
+ assert(c, 10);
+ assert(d, 30);
+}
+test7(10, 20);
+
+
+function test8(x) {
+ // How much uglier can we make a factorial function?
+ if (x <= 0)
+ return {p: 1};
+
+ var {p = {p: x * test8(x - 1).p}} = {};
+ return p;
+}
+assert(test8(5).p, 120);
+assert(test8(10).p, 3628800);
+assert(test8(0).p, 1);
+
+// FIXME: When we support default values in function parameters, we should remove this test.
+function shouldThrow(str) {
+ var thrown = false;
+ try {
+ eval(str);
+ } catch(e) {
+ thrown = true;
+ }
+
+ assert(true, thrown);
+}
+
+shouldThrow("(function({x = 40}) {})");
+shouldThrow("(function({y}, {x = 40}) {}");
+shouldThrow("(function([y], [x = 40]) {})");
+shouldThrow("(function({y}, {x: {z = 50}}) {})");
+shouldThrow("(function({y}, {x: [z = 50]}) {})");
</ins></span></pre></div>
<a id="trunkSourceJavaScriptCoreChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/ChangeLog (185698 => 185699)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/ChangeLog        2015-06-18 09:22:48 UTC (rev 185698)
+++ trunk/Source/JavaScriptCore/ChangeLog        2015-06-18 12:35:32 UTC (rev 185699)
</span><span class="lines">@@ -1,3 +1,48 @@
</span><ins>+2015-06-18 Saam Barati <saambarati1@gmail.com>
+
+ [ES6] support default values in deconstruction parameter nodes
+ https://bugs.webkit.org/show_bug.cgi?id=142679
+
+ Reviewed by Darin Adler.
+
+ ES6 destructuring allows destructuring properties to assign
+ default values. A link to the spec:
+ https://people.mozilla.org/~jorendorff/es6-draft.html#sec-destructuring-binding-patterns
+
+ This patch implements default values for all places where deconstruction
+ is allowed besides function parameters. This is because function
+ parameters are parsed in a separate parser arena than the function
+ body itself and ExpresionNode's which are default values for
+ deconstruction parameters will be deallocated by the time we parse the body
+ of the function. I have opened a bug to address this problem:
+ https://bugs.webkit.org/show_bug.cgi?id=145995
+
+ * bytecompiler/NodesCodegen.cpp:
+ (JSC::DeconstructionPatternNode::~DeconstructionPatternNode):
+ (JSC::assignDefaultValueIfUndefined):
+ (JSC::ArrayPatternNode::bindValue):
+ (JSC::ArrayPatternNode::emitDirectBinding):
+ (JSC::ArrayPatternNode::toString):
+ (JSC::ArrayPatternNode::collectBoundIdentifiers):
+ (JSC::ObjectPatternNode::bindValue):
+ * parser/ASTBuilder.h:
+ (JSC::ASTBuilder::appendArrayPatternSkipEntry):
+ (JSC::ASTBuilder::appendArrayPatternEntry):
+ (JSC::ASTBuilder::createObjectPattern):
+ (JSC::ASTBuilder::appendObjectPatternEntry):
+ (JSC::ASTBuilder::createBindingLocation):
+ * parser/Nodes.h:
+ (JSC::ArrayPatternNode::appendIndex):
+ (JSC::ObjectPatternNode::appendEntry):
+ (JSC::ObjectPatternNode::Entry::Entry): Deleted.
+ * parser/Parser.cpp:
+ (JSC::Parser<LexerType>::parseDeconstructionPattern):
+ (JSC::Parser<LexerType>::parseDefaultValueForDeconstructionPattern):
+ (JSC::Parser<LexerType>::parseConstDeclarationList):
+ * parser/Parser.h:
+ * parser/SyntaxChecker.h:
+ (JSC::SyntaxChecker::operatorStackPop):
+
</ins><span class="cx"> 2015-06-17 Joseph Pecoraro <pecoraro@apple.com>
</span><span class="cx">
</span><span class="cx"> Web Inspector: Do not show JavaScriptCore builtins in inspector
</span></span></pre></div>
<a id="trunkSourceJavaScriptCorebytecompilerNodesCodegencpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/bytecompiler/NodesCodegen.cpp (185698 => 185699)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/bytecompiler/NodesCodegen.cpp        2015-06-18 09:22:48 UTC (rev 185698)
+++ trunk/Source/JavaScriptCore/bytecompiler/NodesCodegen.cpp        2015-06-18 12:35:32 UTC (rev 185699)
</span><span class="lines">@@ -3119,17 +3119,28 @@
</span><span class="cx"> DeconstructionPatternNode::~DeconstructionPatternNode()
</span><span class="cx"> {
</span><span class="cx"> }
</span><ins>+
+static void assignDefaultValueIfUndefined(BytecodeGenerator& generator, RegisterID* maybeUndefined, ExpressionNode* defaultValue)
+{
+ ASSERT(defaultValue);
+ RefPtr<Label> isNotUndefined = generator.newLabel();
+ generator.emitJumpIfFalse(generator.emitIsUndefined(generator.newTemporary(), maybeUndefined), isNotUndefined.get());
+ generator.emitNode(maybeUndefined, defaultValue);
+ generator.emitLabel(isNotUndefined.get());
+}
</ins><span class="cx">
</span><span class="cx"> void ArrayPatternNode::bindValue(BytecodeGenerator& generator, RegisterID* rhs) const
</span><span class="cx"> {
</span><span class="cx"> for (size_t i = 0; i < m_targetPatterns.size(); i++) {
</span><span class="cx"> auto target = m_targetPatterns[i];
</span><del>- if (!target)
</del><ins>+ if (!target.pattern)
</ins><span class="cx"> continue;
</span><span class="cx"> RefPtr<RegisterID> temp = generator.newTemporary();
</span><span class="cx"> generator.emitLoad(temp.get(), jsNumber(i));
</span><span class="cx"> generator.emitGetByVal(temp.get(), rhs, temp.get());
</span><del>- target->bindValue(generator, temp.get());
</del><ins>+ if (target.defaultValue)
+ assignDefaultValueIfUndefined(generator, temp.get(), target.defaultValue);
+ target.pattern->bindValue(generator, temp.get());
</ins><span class="cx"> }
</span><span class="cx"> }
</span><span class="cx">
</span><span class="lines">@@ -3152,13 +3163,15 @@
</span><span class="cx"> for (size_t i = 0; i < m_targetPatterns.size(); i++) {
</span><span class="cx"> registers.uncheckedAppend(generator.newTemporary());
</span><span class="cx"> generator.emitNode(registers.last().get(), elements[i]);
</span><ins>+ if (m_targetPatterns[i].defaultValue)
+ assignDefaultValueIfUndefined(generator, registers.last().get(), m_targetPatterns[i].defaultValue);
</ins><span class="cx"> if (resultRegister)
</span><span class="cx"> generator.emitPutByIndex(resultRegister.get(), i, registers.last().get());
</span><span class="cx"> }
</span><span class="cx">
</span><span class="cx"> for (size_t i = 0; i < m_targetPatterns.size(); i++) {
</span><del>- if (m_targetPatterns[i])
- m_targetPatterns[i]->bindValue(generator, registers[i].get());
</del><ins>+ if (m_targetPatterns[i].pattern)
+ m_targetPatterns[i].pattern->bindValue(generator, registers[i].get());
</ins><span class="cx"> }
</span><span class="cx"> if (resultRegister)
</span><span class="cx"> return generator.moveToDestinationIfNeeded(dst, resultRegister.get());
</span><span class="lines">@@ -3169,11 +3182,11 @@
</span><span class="cx"> {
</span><span class="cx"> builder.append('[');
</span><span class="cx"> for (size_t i = 0; i < m_targetPatterns.size(); i++) {
</span><del>- if (!m_targetPatterns[i]) {
</del><ins>+ if (!m_targetPatterns[i].pattern) {
</ins><span class="cx"> builder.append(',');
</span><span class="cx"> continue;
</span><span class="cx"> }
</span><del>- m_targetPatterns[i]->toString(builder);
</del><ins>+ m_targetPatterns[i].pattern->toString(builder);
</ins><span class="cx"> if (i < m_targetPatterns.size() - 1)
</span><span class="cx"> builder.append(',');
</span><span class="cx"> }
</span><span class="lines">@@ -3183,7 +3196,7 @@
</span><span class="cx"> void ArrayPatternNode::collectBoundIdentifiers(Vector<Identifier>& identifiers) const
</span><span class="cx"> {
</span><span class="cx"> for (size_t i = 0; i < m_targetPatterns.size(); i++) {
</span><del>- if (DeconstructionPatternNode* node = m_targetPatterns[i].get())
</del><ins>+ if (DeconstructionPatternNode* node = m_targetPatterns[i].pattern.get())
</ins><span class="cx"> node->collectBoundIdentifiers(identifiers);
</span><span class="cx"> }
</span><span class="cx"> }
</span><span class="lines">@@ -3210,6 +3223,8 @@
</span><span class="cx"> auto& target = m_targetPatterns[i];
</span><span class="cx"> RefPtr<RegisterID> temp = generator.newTemporary();
</span><span class="cx"> generator.emitGetById(temp.get(), rhs, target.propertyName);
</span><ins>+ if (target.defaultValue)
+ assignDefaultValueIfUndefined(generator, temp.get(), target.defaultValue);
</ins><span class="cx"> target.pattern->bindValue(generator, temp.get());
</span><span class="cx"> }
</span><span class="cx"> }
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreparserASTBuilderh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/parser/ASTBuilder.h (185698 => 185699)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/parser/ASTBuilder.h        2015-06-18 09:22:48 UTC (rev 185698)
+++ trunk/Source/JavaScriptCore/parser/ASTBuilder.h        2015-06-18 12:35:32 UTC (rev 185699)
</span><span class="lines">@@ -737,12 +737,12 @@
</span><span class="cx">
</span><span class="cx"> void appendArrayPatternSkipEntry(ArrayPattern node, const JSTokenLocation& location)
</span><span class="cx"> {
</span><del>- node->appendIndex(location, 0);
</del><ins>+ node->appendIndex(location, 0, nullptr);
</ins><span class="cx"> }
</span><span class="cx">
</span><del>- void appendArrayPatternEntry(ArrayPattern node, const JSTokenLocation& location, DeconstructionPattern pattern)
</del><ins>+ void appendArrayPatternEntry(ArrayPattern node, const JSTokenLocation& location, DeconstructionPattern pattern, ExpressionNode* defaultValue)
</ins><span class="cx"> {
</span><del>- node->appendIndex(location, pattern.get());
</del><ins>+ node->appendIndex(location, pattern.get(), defaultValue);
</ins><span class="cx"> }
</span><span class="cx">
</span><span class="cx"> ObjectPattern createObjectPattern(const JSTokenLocation&)
</span><span class="lines">@@ -750,9 +750,9 @@
</span><span class="cx"> return ObjectPatternNode::create();
</span><span class="cx"> }
</span><span class="cx">
</span><del>- void appendObjectPatternEntry(ObjectPattern node, const JSTokenLocation& location, bool wasString, const Identifier& identifier, DeconstructionPattern pattern)
</del><ins>+ void appendObjectPatternEntry(ObjectPattern node, const JSTokenLocation& location, bool wasString, const Identifier& identifier, DeconstructionPattern pattern, ExpressionNode* defaultValue)
</ins><span class="cx"> {
</span><del>- node->appendEntry(location, identifier, wasString, pattern.get());
</del><ins>+ node->appendEntry(location, identifier, wasString, pattern.get(), defaultValue);
</ins><span class="cx"> }
</span><span class="cx">
</span><span class="cx"> BindingPattern createBindingLocation(const JSTokenLocation&, const Identifier& boundProperty, const JSTextPosition& start, const JSTextPosition& end)
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreparserNodesh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/parser/Nodes.h (185698 => 185699)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/parser/Nodes.h        2015-06-18 09:22:48 UTC (rev 185698)
+++ trunk/Source/JavaScriptCore/parser/Nodes.h        2015-06-18 12:35:32 UTC (rev 185699)
</span><span class="lines">@@ -1783,27 +1783,31 @@
</span><span class="cx"> class ArrayPatternNode : public DeconstructionPatternNode {
</span><span class="cx"> public:
</span><span class="cx"> static Ref<ArrayPatternNode> create();
</span><del>- void appendIndex(const JSTokenLocation&, DeconstructionPatternNode* node)
</del><ins>+ void appendIndex(const JSTokenLocation&, DeconstructionPatternNode* node, ExpressionNode* defaultValue)
</ins><span class="cx"> {
</span><del>- m_targetPatterns.append(node);
</del><ins>+ m_targetPatterns.append(Entry{ node, defaultValue });
</ins><span class="cx"> }
</span><span class="cx">
</span><span class="cx"> private:
</span><ins>+ struct Entry {
+ RefPtr<DeconstructionPatternNode> pattern;
+ ExpressionNode* defaultValue;
+ };
</ins><span class="cx"> ArrayPatternNode();
</span><span class="cx"> virtual void collectBoundIdentifiers(Vector<Identifier>&) const override;
</span><span class="cx"> virtual void bindValue(BytecodeGenerator&, RegisterID*) const override;
</span><span class="cx"> virtual RegisterID* emitDirectBinding(BytecodeGenerator&, RegisterID* dst, ExpressionNode*) override;
</span><span class="cx"> virtual void toString(StringBuilder&) const override;
</span><span class="cx">
</span><del>- Vector<RefPtr<DeconstructionPatternNode>> m_targetPatterns;
</del><ins>+ Vector<Entry> m_targetPatterns;
</ins><span class="cx"> };
</span><span class="cx">
</span><span class="cx"> class ObjectPatternNode : public DeconstructionPatternNode {
</span><span class="cx"> public:
</span><span class="cx"> static Ref<ObjectPatternNode> create();
</span><del>- void appendEntry(const JSTokenLocation&, const Identifier& identifier, bool wasString, DeconstructionPatternNode* pattern)
</del><ins>+ void appendEntry(const JSTokenLocation&, const Identifier& identifier, bool wasString, DeconstructionPatternNode* pattern, ExpressionNode* defaultValue)
</ins><span class="cx"> {
</span><del>- m_targetPatterns.append(Entry(identifier, wasString, pattern));
</del><ins>+ m_targetPatterns.append(Entry{ identifier, wasString, pattern, defaultValue });
</ins><span class="cx"> }
</span><span class="cx">
</span><span class="cx"> private:
</span><span class="lines">@@ -1812,15 +1816,10 @@
</span><span class="cx"> virtual void bindValue(BytecodeGenerator&, RegisterID*) const override;
</span><span class="cx"> virtual void toString(StringBuilder&) const override;
</span><span class="cx"> struct Entry {
</span><del>- Entry(const Identifier& propertyName, bool wasString, DeconstructionPatternNode* pattern)
- : propertyName(propertyName)
- , wasString(wasString)
- , pattern(pattern)
- {
- }
</del><span class="cx"> Identifier propertyName;
</span><span class="cx"> bool wasString;
</span><span class="cx"> RefPtr<DeconstructionPatternNode> pattern;
</span><ins>+ ExpressionNode* defaultValue;
</ins><span class="cx"> };
</span><span class="cx"> Vector<Entry> m_targetPatterns;
</span><span class="cx"> };
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreparserParsercpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/parser/Parser.cpp (185698 => 185699)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/parser/Parser.cpp        2015-06-18 09:22:48 UTC (rev 185698)
+++ trunk/Source/JavaScriptCore/parser/Parser.cpp        2015-06-18 12:35:32 UTC (rev 185699)
</span><span class="lines">@@ -613,7 +613,9 @@
</span><span class="cx"> if (kind == DeconstructToExpressions && !innerPattern)
</span><span class="cx"> return 0;
</span><span class="cx"> failIfFalse(innerPattern, "Cannot parse this deconstruction pattern");
</span><del>- context.appendArrayPatternEntry(arrayPattern, location, innerPattern);
</del><ins>+ TreeExpression defaultValue = parseDefaultValueForDeconstructionPattern(context);
+ failIfTrue(kind == DeconstructToParameters && defaultValue, "Default values in destructuring parameters are currently not supported");
+ context.appendArrayPatternEntry(arrayPattern, location, innerPattern, defaultValue);
</ins><span class="cx"> } while (consume(COMMA));
</span><span class="cx">
</span><span class="cx"> if (kind == DeconstructToExpressions && !match(CLOSEBRACKET))
</span><span class="lines">@@ -679,7 +681,9 @@
</span><span class="cx"> if (kind == DeconstructToExpressions && !innerPattern)
</span><span class="cx"> return 0;
</span><span class="cx"> failIfFalse(innerPattern, "Cannot parse this deconstruction pattern");
</span><del>- context.appendObjectPatternEntry(objectPattern, location, wasString, propertyName, innerPattern);
</del><ins>+ TreeExpression defaultValue = parseDefaultValueForDeconstructionPattern(context);
+ failIfTrue(kind == DeconstructToParameters && defaultValue, "Default values in destructuring parameters are currently not supported");
+ context.appendObjectPatternEntry(objectPattern, location, wasString, propertyName, innerPattern, defaultValue);
</ins><span class="cx"> } while (consume(COMMA));
</span><span class="cx"> if (kind == DeconstructToExpressions && !match(CLOSEBRACE))
</span><span class="cx"> return 0;
</span><span class="lines">@@ -705,6 +709,16 @@
</span><span class="cx"> }
</span><span class="cx">
</span><span class="cx"> template <typename LexerType>
</span><ins>+template <class TreeBuilder> TreeExpression Parser<LexerType>::parseDefaultValueForDeconstructionPattern(TreeBuilder& context)
+{
+ if (!match(EQUAL))
+ return 0;
+
+ next(TreeBuilder::DontBuildStrings); // consume '='
+ return parseAssignmentExpression(context);
+}
+
+template <typename LexerType>
</ins><span class="cx"> template <class TreeBuilder> TreeConstDeclList Parser<LexerType>::parseConstDeclarationList(TreeBuilder& context)
</span><span class="cx"> {
</span><span class="cx"> failIfTrue(strictMode(), "Const declarations are not supported in strict mode");
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreparserParserh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/parser/Parser.h (185698 => 185699)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/parser/Parser.h        2015-06-18 09:22:48 UTC (rev 185698)
+++ trunk/Source/JavaScriptCore/parser/Parser.h        2015-06-18 12:35:32 UTC (rev 185699)
</span><span class="lines">@@ -765,6 +765,7 @@
</span><span class="cx"> template <class TreeBuilder> NEVER_INLINE TreeDeconstructionPattern createBindingPattern(TreeBuilder&, DeconstructionKind, const Identifier&, int depth, JSToken);
</span><span class="cx"> template <class TreeBuilder> NEVER_INLINE TreeDeconstructionPattern parseDeconstructionPattern(TreeBuilder&, DeconstructionKind, int depth = 0);
</span><span class="cx"> template <class TreeBuilder> NEVER_INLINE TreeDeconstructionPattern tryParseDeconstructionPatternExpression(TreeBuilder&);
</span><ins>+ template <class TreeBuilder> NEVER_INLINE TreeExpression parseDefaultValueForDeconstructionPattern(TreeBuilder&);
</ins><span class="cx">
</span><span class="cx"> template <class TreeBuilder> NEVER_INLINE bool parseFunctionInfo(TreeBuilder&, FunctionRequirements, FunctionParseMode, bool nameIsInContainingScope, ConstructorKind, SuperBinding, int functionKeywordStart, ParserFunctionInfo<TreeBuilder>&);
</span><span class="cx">
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreparserSyntaxCheckerh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/parser/SyntaxChecker.h (185698 => 185699)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/parser/SyntaxChecker.h        2015-06-18 09:22:48 UTC (rev 185698)
+++ trunk/Source/JavaScriptCore/parser/SyntaxChecker.h        2015-06-18 12:35:32 UTC (rev 185699)
</span><span class="lines">@@ -308,14 +308,14 @@
</span><span class="cx"> void appendArrayPatternSkipEntry(ArrayPattern, const JSTokenLocation&)
</span><span class="cx"> {
</span><span class="cx"> }
</span><del>- void appendArrayPatternEntry(ArrayPattern, const JSTokenLocation&, DeconstructionPattern)
</del><ins>+ void appendArrayPatternEntry(ArrayPattern, const JSTokenLocation&, DeconstructionPattern, int)
</ins><span class="cx"> {
</span><span class="cx"> }
</span><span class="cx"> ObjectPattern createObjectPattern(const JSTokenLocation&)
</span><span class="cx"> {
</span><span class="cx"> return ObjectDeconstruction;
</span><span class="cx"> }
</span><del>- void appendObjectPatternEntry(ArrayPattern, const JSTokenLocation&, bool, const Identifier&, DeconstructionPattern)
</del><ins>+ void appendObjectPatternEntry(ArrayPattern, const JSTokenLocation&, bool, const Identifier&, DeconstructionPattern, int)
</ins><span class="cx"> {
</span><span class="cx"> }
</span><span class="cx"> DeconstructionPattern createBindingLocation(const JSTokenLocation&, const Identifier&, const JSTextPosition&, const JSTextPosition&)
</span></span></pre>
</div>
</div>
</body>
</html>