<!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&lt;LexerType&gt;::parseDeconstructionPattern):
(JSC::Parser&lt;LexerType&gt;::parseDefaultValueForDeconstructionPattern):
(JSC::Parser&lt;LexerType&gt;::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  &lt;saambarati1@gmail.com&gt;
+
+        [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 &lt;youenn.fablet@crf.canon.fr&gt; and Xabier Rodriguez Calvar  &lt;calvaris@igalia.com&gt;
</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 &quot;PASS&quot; messages, followed by &quot;TEST COMPLETE&quot;.
+
+
+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>+&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;script-tests/destructuring-assignment-default-values.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="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(&quot;Test default values in destructuring patterns: https://people.mozilla.org/~jorendorff/es6-draft.html#sec-destructuring-binding-patterns&quot;);
+function assert(a, b) {
+    if (b === a)
+        testPassed(a + &quot;,&quot; + b);
+    else
+        testFailed(a + &quot;,&quot; + 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 = &quot;Hello&quot;, y = 40, z = 30] = [undefined, 20, undefined];
+    assert(x, &quot;Hello&quot;);
+    assert(y, 20);
+    assert(z, 30);
+    var [x = &quot;Hello&quot;, y = 40, z = 30] = arr();
+    assert(x, &quot;Hello&quot;);
+    assert(y, 20);
+    assert(z, 30);
+}
+test2();
+
+
+function test3() {
+    var z = &quot;z&quot;;
+    var [x = z] = [];
+    assert(x, &quot;z&quot;);
+    z = &quot;zz&quot;;
+    var [x = eval(&quot;z&quot;)] = [];
+    assert(x, &quot;zz&quot;);
+
+    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 &lt;= 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(&quot;(function({x = 40}) {})&quot;);
+shouldThrow(&quot;(function({y}, {x = 40}) {}&quot;);
+shouldThrow(&quot;(function([y], [x = 40]) {})&quot;);
+shouldThrow(&quot;(function({y}, {x: {z = 50}}) {})&quot;);
+shouldThrow(&quot;(function({y}, {x: [z = 50]}) {})&quot;);
</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  &lt;saambarati1@gmail.com&gt;
+
+        [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&lt;LexerType&gt;::parseDeconstructionPattern):
+        (JSC::Parser&lt;LexerType&gt;::parseDefaultValueForDeconstructionPattern):
+        (JSC::Parser&lt;LexerType&gt;::parseConstDeclarationList):
+        * parser/Parser.h:
+        * parser/SyntaxChecker.h:
+        (JSC::SyntaxChecker::operatorStackPop):
+
</ins><span class="cx"> 2015-06-17  Joseph Pecoraro  &lt;pecoraro@apple.com&gt;
</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&amp; generator, RegisterID* maybeUndefined, ExpressionNode* defaultValue)
+{
+    ASSERT(defaultValue);
+    RefPtr&lt;Label&gt; 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&amp; generator, RegisterID* rhs) const
</span><span class="cx"> {
</span><span class="cx">     for (size_t i = 0; i &lt; 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&lt;RegisterID&gt; 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-&gt;bindValue(generator, temp.get());
</del><ins>+        if (target.defaultValue)
+            assignDefaultValueIfUndefined(generator, temp.get(), target.defaultValue);
+        target.pattern-&gt;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 &lt; 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 &lt; m_targetPatterns.size(); i++) {
</span><del>-        if (m_targetPatterns[i])
-            m_targetPatterns[i]-&gt;bindValue(generator, registers[i].get());
</del><ins>+        if (m_targetPatterns[i].pattern)
+            m_targetPatterns[i].pattern-&gt;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 &lt; 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]-&gt;toString(builder);
</del><ins>+        m_targetPatterns[i].pattern-&gt;toString(builder);
</ins><span class="cx">         if (i &lt; 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&lt;Identifier&gt;&amp; identifiers) const
</span><span class="cx"> {
</span><span class="cx">     for (size_t i = 0; i &lt; 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-&gt;collectBoundIdentifiers(identifiers);
</span><span class="cx">     }
</span><span class="cx"> }
</span><span class="lines">@@ -3210,6 +3223,8 @@
</span><span class="cx">         auto&amp; target = m_targetPatterns[i];
</span><span class="cx">         RefPtr&lt;RegisterID&gt; 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-&gt;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&amp; location)
</span><span class="cx">     {
</span><del>-        node-&gt;appendIndex(location, 0);
</del><ins>+        node-&gt;appendIndex(location, 0, nullptr);
</ins><span class="cx">     }
</span><span class="cx"> 
</span><del>-    void appendArrayPatternEntry(ArrayPattern node, const JSTokenLocation&amp; location, DeconstructionPattern pattern)
</del><ins>+    void appendArrayPatternEntry(ArrayPattern node, const JSTokenLocation&amp; location, DeconstructionPattern pattern, ExpressionNode* defaultValue)
</ins><span class="cx">     {
</span><del>-        node-&gt;appendIndex(location, pattern.get());
</del><ins>+        node-&gt;appendIndex(location, pattern.get(), defaultValue);
</ins><span class="cx">     }
</span><span class="cx">     
</span><span class="cx">     ObjectPattern createObjectPattern(const JSTokenLocation&amp;)
</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&amp; location, bool wasString, const Identifier&amp; identifier, DeconstructionPattern pattern)
</del><ins>+    void appendObjectPatternEntry(ObjectPattern node, const JSTokenLocation&amp; location, bool wasString, const Identifier&amp; identifier, DeconstructionPattern pattern, ExpressionNode* defaultValue)
</ins><span class="cx">     {
</span><del>-        node-&gt;appendEntry(location, identifier, wasString, pattern.get());
</del><ins>+        node-&gt;appendEntry(location, identifier, wasString, pattern.get(), defaultValue);
</ins><span class="cx">     }
</span><span class="cx">     
</span><span class="cx">     BindingPattern createBindingLocation(const JSTokenLocation&amp;, const Identifier&amp; boundProperty, const JSTextPosition&amp; start, const JSTextPosition&amp; 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&lt;ArrayPatternNode&gt; create();
</span><del>-        void appendIndex(const JSTokenLocation&amp;, DeconstructionPatternNode* node)
</del><ins>+        void appendIndex(const JSTokenLocation&amp;, 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&lt;DeconstructionPatternNode&gt; pattern;
+            ExpressionNode* defaultValue;
+        };
</ins><span class="cx">         ArrayPatternNode();
</span><span class="cx">         virtual void collectBoundIdentifiers(Vector&lt;Identifier&gt;&amp;) const override;
</span><span class="cx">         virtual void bindValue(BytecodeGenerator&amp;, RegisterID*) const override;
</span><span class="cx">         virtual RegisterID* emitDirectBinding(BytecodeGenerator&amp;, RegisterID* dst, ExpressionNode*) override;
</span><span class="cx">         virtual void toString(StringBuilder&amp;) const override;
</span><span class="cx"> 
</span><del>-        Vector&lt;RefPtr&lt;DeconstructionPatternNode&gt;&gt; m_targetPatterns;
</del><ins>+        Vector&lt;Entry&gt; 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&lt;ObjectPatternNode&gt; create();
</span><del>-        void appendEntry(const JSTokenLocation&amp;, const Identifier&amp; identifier, bool wasString, DeconstructionPatternNode* pattern)
</del><ins>+        void appendEntry(const JSTokenLocation&amp;, const Identifier&amp; 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&amp;, RegisterID*) const override;
</span><span class="cx">         virtual void toString(StringBuilder&amp;) const override;
</span><span class="cx">         struct Entry {
</span><del>-            Entry(const Identifier&amp; 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&lt;DeconstructionPatternNode&gt; pattern;
</span><ins>+            ExpressionNode* defaultValue;
</ins><span class="cx">         };
</span><span class="cx">         Vector&lt;Entry&gt; 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 &amp;&amp; !innerPattern)
</span><span class="cx">                 return 0;
</span><span class="cx">             failIfFalse(innerPattern, &quot;Cannot parse this deconstruction pattern&quot;);
</span><del>-            context.appendArrayPatternEntry(arrayPattern, location, innerPattern);
</del><ins>+            TreeExpression defaultValue = parseDefaultValueForDeconstructionPattern(context);
+            failIfTrue(kind == DeconstructToParameters &amp;&amp; defaultValue,  &quot;Default values in destructuring parameters are currently not supported&quot;);
+            context.appendArrayPatternEntry(arrayPattern, location, innerPattern, defaultValue);
</ins><span class="cx">         } while (consume(COMMA));
</span><span class="cx">         
</span><span class="cx">         if (kind == DeconstructToExpressions &amp;&amp; !match(CLOSEBRACKET))
</span><span class="lines">@@ -679,7 +681,9 @@
</span><span class="cx">             if (kind == DeconstructToExpressions &amp;&amp; !innerPattern)
</span><span class="cx">                 return 0;
</span><span class="cx">             failIfFalse(innerPattern, &quot;Cannot parse this deconstruction pattern&quot;);
</span><del>-            context.appendObjectPatternEntry(objectPattern, location, wasString, propertyName, innerPattern);
</del><ins>+            TreeExpression defaultValue = parseDefaultValueForDeconstructionPattern(context);
+            failIfTrue(kind == DeconstructToParameters &amp;&amp; defaultValue, &quot;Default values in destructuring parameters are currently not supported&quot;);
+            context.appendObjectPatternEntry(objectPattern, location, wasString, propertyName, innerPattern, defaultValue);
</ins><span class="cx">         } while (consume(COMMA));
</span><span class="cx">         if (kind == DeconstructToExpressions &amp;&amp; !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 &lt;typename LexerType&gt;
</span><ins>+template &lt;class TreeBuilder&gt; TreeExpression Parser&lt;LexerType&gt;::parseDefaultValueForDeconstructionPattern(TreeBuilder&amp; context)
+{
+    if (!match(EQUAL))
+        return 0;
+
+    next(TreeBuilder::DontBuildStrings); // consume '='
+    return parseAssignmentExpression(context);
+}
+
+template &lt;typename LexerType&gt;
</ins><span class="cx"> template &lt;class TreeBuilder&gt; TreeConstDeclList Parser&lt;LexerType&gt;::parseConstDeclarationList(TreeBuilder&amp; context)
</span><span class="cx"> {
</span><span class="cx">     failIfTrue(strictMode(), &quot;Const declarations are not supported in strict mode&quot;);
</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 &lt;class TreeBuilder&gt; NEVER_INLINE TreeDeconstructionPattern createBindingPattern(TreeBuilder&amp;, DeconstructionKind, const Identifier&amp;, int depth, JSToken);
</span><span class="cx">     template &lt;class TreeBuilder&gt; NEVER_INLINE TreeDeconstructionPattern parseDeconstructionPattern(TreeBuilder&amp;, DeconstructionKind, int depth = 0);
</span><span class="cx">     template &lt;class TreeBuilder&gt; NEVER_INLINE TreeDeconstructionPattern tryParseDeconstructionPatternExpression(TreeBuilder&amp;);
</span><ins>+    template &lt;class TreeBuilder&gt; NEVER_INLINE TreeExpression parseDefaultValueForDeconstructionPattern(TreeBuilder&amp;);
</ins><span class="cx"> 
</span><span class="cx">     template &lt;class TreeBuilder&gt; NEVER_INLINE bool parseFunctionInfo(TreeBuilder&amp;, FunctionRequirements, FunctionParseMode, bool nameIsInContainingScope, ConstructorKind, SuperBinding, int functionKeywordStart, ParserFunctionInfo&lt;TreeBuilder&gt;&amp;);
</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&amp;)
</span><span class="cx">     {
</span><span class="cx">     }
</span><del>-    void appendArrayPatternEntry(ArrayPattern, const JSTokenLocation&amp;, DeconstructionPattern)
</del><ins>+    void appendArrayPatternEntry(ArrayPattern, const JSTokenLocation&amp;, DeconstructionPattern, int)
</ins><span class="cx">     {
</span><span class="cx">     }
</span><span class="cx">     ObjectPattern createObjectPattern(const JSTokenLocation&amp;)
</span><span class="cx">     {
</span><span class="cx">         return ObjectDeconstruction;
</span><span class="cx">     }
</span><del>-    void appendObjectPatternEntry(ArrayPattern, const JSTokenLocation&amp;, bool, const Identifier&amp;, DeconstructionPattern)
</del><ins>+    void appendObjectPatternEntry(ArrayPattern, const JSTokenLocation&amp;, bool, const Identifier&amp;, DeconstructionPattern, int)
</ins><span class="cx">     {
</span><span class="cx">     }
</span><span class="cx">     DeconstructionPattern createBindingLocation(const JSTokenLocation&amp;, const Identifier&amp;, const JSTextPosition&amp;, const JSTextPosition&amp;)
</span></span></pre>
</div>
</div>

</body>
</html>