<!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>[192671] 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/192671">192671</a></dd>
<dt>Author</dt> <dd>sbarati@apple.com</dd>
<dt>Date</dt> <dd>2015-11-19 18:37:47 -0800 (Thu, 19 Nov 2015)</dd>
</dl>

<h3>Log Message</h3>
<pre>[ES6] Add support for rest parameters
https://bugs.webkit.org/show_bug.cgi?id=38408

Reviewed by Geoffrey Garen.

Source/JavaScriptCore:

This patch implements rest parameters from the ES6 spec.
http://www.ecma-international.org/ecma-262/6.0/index.html#sec-function-definitions

We implement the rest parameter as a new AST node. This AST node
lowers to &quot;op_new_array X, op_copy_rest X&quot;. Note
that the op_copy_rest opcode does not have a result.
The bulk of this patch is implementing op_copy_rest.
This patch implements this in all four tiers in a straight forward way.
The opcode is implemented as a C call that will read the pertinent
arguments from the call frame and fill them into the array.

* bytecode/BytecodeList.json:
* bytecode/BytecodeUseDef.h:
(JSC::computeUsesForBytecodeOffset):
(JSC::computeDefsForBytecodeOffset):
* bytecode/CodeBlock.cpp:
(JSC::CodeBlock::dumpBytecode):
* bytecode/Instruction.h:
(JSC::Instruction::Instruction):
* bytecompiler/BytecodeGenerator.cpp:
(JSC::BytecodeGenerator::generate):
(JSC::BytecodeGenerator::BytecodeGenerator):
(JSC::BytecodeGenerator::initializeDefaultParameterValuesAndSetupFunctionScopeStack):
(JSC::BytecodeGenerator::invalidateForInContextForLocal):
(JSC::BytecodeGenerator::emitRestParameter):
* bytecompiler/BytecodeGenerator.h:
* bytecompiler/NodesCodegen.cpp:
(JSC::AssignmentElementNode::toString):
(JSC::RestParameterNode::collectBoundIdentifiers):
(JSC::RestParameterNode::toString):
(JSC::RestParameterNode::bindValue):
(JSC::RestParameterNode::emit):
(JSC::SpreadExpressionNode::emitBytecode):
* dfg/DFGAbstractInterpreterInlines.h:
(JSC::DFG::AbstractInterpreter&lt;AbstractStateType&gt;::executeEffects):
* dfg/DFGByteCodeParser.cpp:
(JSC::DFG::ByteCodeParser::parseBlock):
* dfg/DFGCapabilities.cpp:
(JSC::DFG::capabilityLevel):
* dfg/DFGClobberize.h:
(JSC::DFG::clobberize):
* dfg/DFGDoesGC.cpp:
(JSC::DFG::doesGC):
* dfg/DFGFixupPhase.cpp:
(JSC::DFG::FixupPhase::fixupNode):
* dfg/DFGNode.h:
(JSC::DFG::Node::setEpoch):
(JSC::DFG::Node::numberOfArgumentsToSkip):
(JSC::DFG::Node::dumpChildren):
* dfg/DFGNodeType.h:
* dfg/DFGOperations.cpp:
* dfg/DFGOperations.h:
* dfg/DFGPredictionPropagationPhase.cpp:
(JSC::DFG::PredictionPropagationPhase::propagate):
* dfg/DFGSafeToExecute.h:
(JSC::DFG::safeToExecute):
* dfg/DFGSpeculativeJIT.cpp:
(JSC::DFG::SpeculativeJIT::compileCreateClonedArguments):
(JSC::DFG::SpeculativeJIT::compileCopyRest):
(JSC::DFG::SpeculativeJIT::compileNotifyWrite):
* dfg/DFGSpeculativeJIT.h:
(JSC::DFG::SpeculativeJIT::callOperation):
* dfg/DFGSpeculativeJIT32_64.cpp:
(JSC::DFG::SpeculativeJIT::compile):
* dfg/DFGSpeculativeJIT64.cpp:
(JSC::DFG::SpeculativeJIT::compile):
* ftl/FTLCapabilities.cpp:
(JSC::FTL::canCompile):
* ftl/FTLIntrinsicRepository.h:
* ftl/FTLLowerDFGToLLVM.cpp:
(JSC::FTL::DFG::LowerDFGToLLVM::compileNode):
(JSC::FTL::DFG::LowerDFGToLLVM::compileCreateClonedArguments):
(JSC::FTL::DFG::LowerDFGToLLVM::compileCopyRest):
(JSC::FTL::DFG::LowerDFGToLLVM::compileNewObject):
* jit/JIT.cpp:
(JSC::JIT::privateCompileMainPass):
* jit/JIT.h:
* jit/JITOpcodes.cpp:
(JSC::JIT::emit_op_create_out_of_band_arguments):
(JSC::JIT::emit_op_copy_rest):
* jit/JITOperations.h:
* llint/LowLevelInterpreter.asm:
* parser/ASTBuilder.h:
(JSC::ASTBuilder::createBindingLocation):
(JSC::ASTBuilder::createRestParameter):
(JSC::ASTBuilder::createAssignmentElement):
* parser/NodeConstructors.h:
(JSC::AssignmentElementNode::AssignmentElementNode):
(JSC::RestParameterNode::RestParameterNode):
(JSC::DestructuringAssignmentNode::DestructuringAssignmentNode):
* parser/Nodes.h:
(JSC::DestructuringPatternNode::isBindingNode):
(JSC::DestructuringPatternNode::isRestParameter):
(JSC::DestructuringPatternNode::emitDirectBinding):
(JSC::RestParameterNode::name):
* parser/Parser.cpp:
(JSC::Parser&lt;LexerType&gt;::parseVariableDeclarationList):
(JSC::Parser&lt;LexerType&gt;::declareRestOrNormalParameter):
(JSC::Parser&lt;LexerType&gt;::createBindingPattern):
(JSC::Parser&lt;LexerType&gt;::parseFormalParameters):
* parser/Parser.h:
(JSC::Parser::strictMode):
(JSC::Parser::isValidStrictMode):
(JSC::Parser::declareParameter):
(JSC::Parser::breakIsValid):
* parser/SyntaxChecker.h:
(JSC::SyntaxChecker::operatorStackPop):
* runtime/CommonSlowPaths.cpp:
(JSC::SLOW_PATH_DECL):
* runtime/CommonSlowPaths.h:
* tests/es6.yaml:
* tests/stress/rest-parameter-and-default-arguments.js: Added.
(assert):
(shouldThrowTDZ):
(foo):
(baz):
(i.shouldThrowTDZ):
* tests/stress/rest-parameter-basics.js: Added.
(assert):
(foo):
(bar):
(capture):
(baz):
(jaz):
(kaz):
(raz):
(restLength):
(testArgumentsObject):
(strictModeLikeArgumentsObject):
* tests/stress/rest-parameter-inlined.js: Added.
(assert):
(bar):
(foo):
(baz):
(jaz):

LayoutTests:

* js/parser-syntax-check-expected.txt:
* js/script-tests/parser-syntax-check.js:
(catch):</pre>

<h3>Modified Paths</h3>
<ul>
<li><a href="#trunkLayoutTestsChangeLog">trunk/LayoutTests/ChangeLog</a></li>
<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="#trunkSourceJavaScriptCorebytecodeBytecodeListjson">trunk/Source/JavaScriptCore/bytecode/BytecodeList.json</a></li>
<li><a href="#trunkSourceJavaScriptCorebytecodeBytecodeUseDefh">trunk/Source/JavaScriptCore/bytecode/BytecodeUseDef.h</a></li>
<li><a href="#trunkSourceJavaScriptCorebytecodeCodeBlockcpp">trunk/Source/JavaScriptCore/bytecode/CodeBlock.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCorebytecodeInstructionh">trunk/Source/JavaScriptCore/bytecode/Instruction.h</a></li>
<li><a href="#trunkSourceJavaScriptCorebytecompilerBytecodeGeneratorcpp">trunk/Source/JavaScriptCore/bytecompiler/BytecodeGenerator.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCorebytecompilerBytecodeGeneratorh">trunk/Source/JavaScriptCore/bytecompiler/BytecodeGenerator.h</a></li>
<li><a href="#trunkSourceJavaScriptCorebytecompilerNodesCodegencpp">trunk/Source/JavaScriptCore/bytecompiler/NodesCodegen.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoredfgDFGAbstractInterpreterInlinesh">trunk/Source/JavaScriptCore/dfg/DFGAbstractInterpreterInlines.h</a></li>
<li><a href="#trunkSourceJavaScriptCoredfgDFGByteCodeParsercpp">trunk/Source/JavaScriptCore/dfg/DFGByteCodeParser.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoredfgDFGCapabilitiescpp">trunk/Source/JavaScriptCore/dfg/DFGCapabilities.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoredfgDFGClobberizeh">trunk/Source/JavaScriptCore/dfg/DFGClobberize.h</a></li>
<li><a href="#trunkSourceJavaScriptCoredfgDFGDoesGCcpp">trunk/Source/JavaScriptCore/dfg/DFGDoesGC.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoredfgDFGFixupPhasecpp">trunk/Source/JavaScriptCore/dfg/DFGFixupPhase.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoredfgDFGNodeh">trunk/Source/JavaScriptCore/dfg/DFGNode.h</a></li>
<li><a href="#trunkSourceJavaScriptCoredfgDFGNodeTypeh">trunk/Source/JavaScriptCore/dfg/DFGNodeType.h</a></li>
<li><a href="#trunkSourceJavaScriptCoredfgDFGOperationscpp">trunk/Source/JavaScriptCore/dfg/DFGOperations.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoredfgDFGOperationsh">trunk/Source/JavaScriptCore/dfg/DFGOperations.h</a></li>
<li><a href="#trunkSourceJavaScriptCoredfgDFGPredictionPropagationPhasecpp">trunk/Source/JavaScriptCore/dfg/DFGPredictionPropagationPhase.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoredfgDFGSafeToExecuteh">trunk/Source/JavaScriptCore/dfg/DFGSafeToExecute.h</a></li>
<li><a href="#trunkSourceJavaScriptCoredfgDFGSpeculativeJITcpp">trunk/Source/JavaScriptCore/dfg/DFGSpeculativeJIT.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoredfgDFGSpeculativeJITh">trunk/Source/JavaScriptCore/dfg/DFGSpeculativeJIT.h</a></li>
<li><a href="#trunkSourceJavaScriptCoredfgDFGSpeculativeJIT32_64cpp">trunk/Source/JavaScriptCore/dfg/DFGSpeculativeJIT32_64.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoredfgDFGSpeculativeJIT64cpp">trunk/Source/JavaScriptCore/dfg/DFGSpeculativeJIT64.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoreftlFTLCapabilitiescpp">trunk/Source/JavaScriptCore/ftl/FTLCapabilities.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoreftlFTLIntrinsicRepositoryh">trunk/Source/JavaScriptCore/ftl/FTLIntrinsicRepository.h</a></li>
<li><a href="#trunkSourceJavaScriptCoreftlFTLLowerDFGToLLVMcpp">trunk/Source/JavaScriptCore/ftl/FTLLowerDFGToLLVM.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCorejitJITcpp">trunk/Source/JavaScriptCore/jit/JIT.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCorejitJITh">trunk/Source/JavaScriptCore/jit/JIT.h</a></li>
<li><a href="#trunkSourceJavaScriptCorejitJITOpcodescpp">trunk/Source/JavaScriptCore/jit/JITOpcodes.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCorejitJITOperationsh">trunk/Source/JavaScriptCore/jit/JITOperations.h</a></li>
<li><a href="#trunkSourceJavaScriptCorellintLowLevelInterpreterasm">trunk/Source/JavaScriptCore/llint/LowLevelInterpreter.asm</a></li>
<li><a href="#trunkSourceJavaScriptCoreparserASTBuilderh">trunk/Source/JavaScriptCore/parser/ASTBuilder.h</a></li>
<li><a href="#trunkSourceJavaScriptCoreparserNodeConstructorsh">trunk/Source/JavaScriptCore/parser/NodeConstructors.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>
<li><a href="#trunkSourceJavaScriptCoreruntimeCommonSlowPathscpp">trunk/Source/JavaScriptCore/runtime/CommonSlowPaths.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoreruntimeCommonSlowPathsh">trunk/Source/JavaScriptCore/runtime/CommonSlowPaths.h</a></li>
<li><a href="#trunkSourceJavaScriptCoretestses6yaml">trunk/Source/JavaScriptCore/tests/es6.yaml</a></li>
</ul>

<h3>Added Paths</h3>
<ul>
<li><a href="#trunkSourceJavaScriptCoretestsstressrestparameteranddefaultargumentsjs">trunk/Source/JavaScriptCore/tests/stress/rest-parameter-and-default-arguments.js</a></li>
<li><a href="#trunkSourceJavaScriptCoretestsstressrestparameterbasicsjs">trunk/Source/JavaScriptCore/tests/stress/rest-parameter-basics.js</a></li>
<li><a href="#trunkSourceJavaScriptCoretestsstressrestparameterinlinedjs">trunk/Source/JavaScriptCore/tests/stress/rest-parameter-inlined.js</a></li>
</ul>

</div>
<div id="patch">
<h3>Diff</h3>
<a id="trunkLayoutTestsChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/LayoutTests/ChangeLog (192670 => 192671)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/ChangeLog        2015-11-20 01:28:30 UTC (rev 192670)
+++ trunk/LayoutTests/ChangeLog        2015-11-20 02:37:47 UTC (rev 192671)
</span><span class="lines">@@ -1,3 +1,14 @@
</span><ins>+2015-11-19  Saam barati  &lt;sbarati@apple.com&gt;
+
+        [ES6] Add support for rest parameters
+        https://bugs.webkit.org/show_bug.cgi?id=38408
+
+        Reviewed by Geoffrey Garen.
+
+        * js/parser-syntax-check-expected.txt:
+        * js/script-tests/parser-syntax-check.js:
+        (catch):
+
</ins><span class="cx"> 2015-11-19  Ryan Haddad  &lt;ryanhaddad@apple.com&gt;
</span><span class="cx"> 
</span><span class="cx">         Marking imported/w3c/html-templates/parsing-html-templates/creating-an-element-for-the-token/template-owner-document.html as flaky crasher
</span></span></pre></div>
<a id="trunkLayoutTestsjsparsersyntaxcheckexpectedtxt"></a>
<div class="modfile"><h4>Modified: trunk/LayoutTests/js/parser-syntax-check-expected.txt (192670 => 192671)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/js/parser-syntax-check-expected.txt        2015-11-20 01:28:30 UTC (rev 192670)
+++ trunk/LayoutTests/js/parser-syntax-check-expected.txt        2015-11-20 02:37:47 UTC (rev 192671)
</span><span class="lines">@@ -929,6 +929,49 @@
</span><span class="cx"> --&quot;
</span><span class="cx"> PASS Invalid: &quot;function f() { 1 % 
</span><span class="cx"> -- }&quot;
</span><ins>+Rest parameter
+PASS Valid:   &quot;function foo(...a) { }&quot;
+PASS Valid:   &quot;function f() { function foo(...a) { } }&quot;
+PASS Valid:   &quot;function foo(a, ...b) { }&quot;
+PASS Valid:   &quot;function f() { function foo(a, ...b) { } }&quot;
+PASS Valid:   &quot;function foo(a = 20, ...b) { }&quot;
+PASS Valid:   &quot;function f() { function foo(a = 20, ...b) { } }&quot;
+PASS Valid:   &quot;function foo(a, b, c, d, e, f, g, ...h) { }&quot;
+PASS Valid:   &quot;function f() { function foo(a, b, c, d, e, f, g, ...h) { } }&quot;
+PASS Invalid: &quot;function foo(a, ...b, c) { }&quot;
+PASS Invalid: &quot;function f() { function foo(a, ...b, c) { } }&quot;
+PASS Invalid: &quot;function foo(a, ...b, ) { }&quot;
+PASS Invalid: &quot;function f() { function foo(a, ...b, ) { } }&quot;
+PASS Invalid: &quot;function foo(a, ...a) { }&quot;
+PASS Invalid: &quot;function f() { function foo(a, ...a) { } }&quot;
+PASS Invalid: &quot;function foo(...a, ...b) { }&quot;
+PASS Invalid: &quot;function f() { function foo(...a, ...b) { } }&quot;
+PASS Invalid: &quot;function foo(...b, ...b) { }&quot;
+PASS Invalid: &quot;function f() { function foo(...b, ...b) { } }&quot;
+PASS Invalid: &quot;function foo(...b  ...b) { }&quot;
+PASS Invalid: &quot;function f() { function foo(...b  ...b) { } }&quot;
+PASS Invalid: &quot;function foo(a, a, ...b) { }&quot;
+PASS Invalid: &quot;function f() { function foo(a, a, ...b) { } }&quot;
+PASS Invalid: &quot;function foo(...{b}) { }&quot;
+PASS Invalid: &quot;function f() { function foo(...{b}) { } }&quot;
+PASS Invalid: &quot;function foo(...[b]) { }&quot;
+PASS Invalid: &quot;function f() { function foo(...[b]) { } }&quot;
+PASS Invalid: &quot;function foo(...123) { }&quot;
+PASS Invalid: &quot;function f() { function foo(...123) { } }&quot;
+PASS Invalid: &quot;function foo(...123abc) { }&quot;
+PASS Invalid: &quot;function f() { function foo(...123abc) { } }&quot;
+PASS Valid:   &quot;function foo(...abc123) { }&quot;
+PASS Valid:   &quot;function f() { function foo(...abc123) { } }&quot;
+PASS Valid:   &quot;function foo(...let) { }&quot;
+PASS Valid:   &quot;function f() { function foo(...let) { } }&quot;
+PASS Invalid: &quot;'use strict'; function foo(...let) { }&quot;
+PASS Invalid: &quot;function f() { 'use strict'; function foo(...let) { } }&quot;
+PASS Valid:   &quot;function foo(...yield) { }&quot;
+PASS Valid:   &quot;function f() { function foo(...yield) { } }&quot;
+PASS Invalid: &quot;'use strict'; function foo(...yield) { }&quot;
+PASS Invalid: &quot;function f() { 'use strict'; function foo(...yield) { } }&quot;
+PASS Invalid: &quot;function foo(...if) { }&quot;
+PASS Invalid: &quot;function f() { function foo(...if) { } }&quot;
</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 (192670 => 192671)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/js/script-tests/parser-syntax-check.js        2015-11-20 01:28:30 UTC (rev 192670)
+++ trunk/LayoutTests/js/script-tests/parser-syntax-check.js        2015-11-20 02:37:47 UTC (rev 192671)
</span><span class="lines">@@ -556,8 +556,31 @@
</span><span class="cx"> invalid(&quot;1 % \n++&quot;);
</span><span class="cx"> invalid(&quot;1 % \n--&quot;);
</span><span class="cx"> 
</span><ins>+debug(&quot;Rest parameter&quot;);
+valid(&quot;function foo(...a) { }&quot;);
+valid(&quot;function foo(a, ...b) { }&quot;);
+valid(&quot;function foo(a = 20, ...b) { }&quot;);
+valid(&quot;function foo(a, b, c, d, e, f, g, ...h) { }&quot;);
+invalid(&quot;function foo(a, ...b, c) { }&quot;)
+invalid(&quot;function foo(a, ...b, ) { }&quot;)
+invalid(&quot;function foo(a, ...a) { }&quot;);
+invalid(&quot;function foo(...a, ...b) { }&quot;);
+invalid(&quot;function foo(...b, ...b) { }&quot;);
+invalid(&quot;function foo(...b  ...b) { }&quot;);
+invalid(&quot;function foo(a, a, ...b) { }&quot;);
+invalid(&quot;function foo(...{b}) { }&quot;);
+invalid(&quot;function foo(...[b]) { }&quot;);
+invalid(&quot;function foo(...123) { }&quot;);
+invalid(&quot;function foo(...123abc) { }&quot;);
+valid(&quot;function foo(...abc123) { }&quot;);
+valid(&quot;function foo(...let) { }&quot;);
+invalid(&quot;'use strict'; function foo(...let) { }&quot;);
+valid(&quot;function foo(...yield) { }&quot;);
+invalid(&quot;'use strict'; function foo(...yield) { }&quot;);
+invalid(&quot;function foo(...if) { }&quot;);
</ins><span class="cx"> 
</span><span class="cx"> 
</span><ins>+
</ins><span class="cx"> try { eval(&quot;a.b.c = {};&quot;); } catch(e1) { e=e1; shouldBe(&quot;e.line&quot;, &quot;1&quot;) }
</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 (192670 => 192671)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/ChangeLog        2015-11-20 01:28:30 UTC (rev 192670)
+++ trunk/Source/JavaScriptCore/ChangeLog        2015-11-20 02:37:47 UTC (rev 192671)
</span><span class="lines">@@ -1,3 +1,146 @@
</span><ins>+2015-11-19  Saam barati  &lt;sbarati@apple.com&gt;
+
+        [ES6] Add support for rest parameters
+        https://bugs.webkit.org/show_bug.cgi?id=38408
+
+        Reviewed by Geoffrey Garen.
+
+        This patch implements rest parameters from the ES6 spec.
+        http://www.ecma-international.org/ecma-262/6.0/index.html#sec-function-definitions
+
+        We implement the rest parameter as a new AST node. This AST node
+        lowers to &quot;op_new_array X, op_copy_rest X&quot;. Note
+        that the op_copy_rest opcode does not have a result.
+        The bulk of this patch is implementing op_copy_rest.
+        This patch implements this in all four tiers in a straight forward way.
+        The opcode is implemented as a C call that will read the pertinent
+        arguments from the call frame and fill them into the array.
+
+        * bytecode/BytecodeList.json:
+        * bytecode/BytecodeUseDef.h:
+        (JSC::computeUsesForBytecodeOffset):
+        (JSC::computeDefsForBytecodeOffset):
+        * bytecode/CodeBlock.cpp:
+        (JSC::CodeBlock::dumpBytecode):
+        * bytecode/Instruction.h:
+        (JSC::Instruction::Instruction):
+        * bytecompiler/BytecodeGenerator.cpp:
+        (JSC::BytecodeGenerator::generate):
+        (JSC::BytecodeGenerator::BytecodeGenerator):
+        (JSC::BytecodeGenerator::initializeDefaultParameterValuesAndSetupFunctionScopeStack):
+        (JSC::BytecodeGenerator::invalidateForInContextForLocal):
+        (JSC::BytecodeGenerator::emitRestParameter):
+        * bytecompiler/BytecodeGenerator.h:
+        * bytecompiler/NodesCodegen.cpp:
+        (JSC::AssignmentElementNode::toString):
+        (JSC::RestParameterNode::collectBoundIdentifiers):
+        (JSC::RestParameterNode::toString):
+        (JSC::RestParameterNode::bindValue):
+        (JSC::RestParameterNode::emit):
+        (JSC::SpreadExpressionNode::emitBytecode):
+        * dfg/DFGAbstractInterpreterInlines.h:
+        (JSC::DFG::AbstractInterpreter&lt;AbstractStateType&gt;::executeEffects):
+        * dfg/DFGByteCodeParser.cpp:
+        (JSC::DFG::ByteCodeParser::parseBlock):
+        * dfg/DFGCapabilities.cpp:
+        (JSC::DFG::capabilityLevel):
+        * dfg/DFGClobberize.h:
+        (JSC::DFG::clobberize):
+        * dfg/DFGDoesGC.cpp:
+        (JSC::DFG::doesGC):
+        * dfg/DFGFixupPhase.cpp:
+        (JSC::DFG::FixupPhase::fixupNode):
+        * dfg/DFGNode.h:
+        (JSC::DFG::Node::setEpoch):
+        (JSC::DFG::Node::numberOfArgumentsToSkip):
+        (JSC::DFG::Node::dumpChildren):
+        * dfg/DFGNodeType.h:
+        * dfg/DFGOperations.cpp:
+        * dfg/DFGOperations.h:
+        * dfg/DFGPredictionPropagationPhase.cpp:
+        (JSC::DFG::PredictionPropagationPhase::propagate):
+        * dfg/DFGSafeToExecute.h:
+        (JSC::DFG::safeToExecute):
+        * dfg/DFGSpeculativeJIT.cpp:
+        (JSC::DFG::SpeculativeJIT::compileCreateClonedArguments):
+        (JSC::DFG::SpeculativeJIT::compileCopyRest):
+        (JSC::DFG::SpeculativeJIT::compileNotifyWrite):
+        * dfg/DFGSpeculativeJIT.h:
+        (JSC::DFG::SpeculativeJIT::callOperation):
+        * dfg/DFGSpeculativeJIT32_64.cpp:
+        (JSC::DFG::SpeculativeJIT::compile):
+        * dfg/DFGSpeculativeJIT64.cpp:
+        (JSC::DFG::SpeculativeJIT::compile):
+        * ftl/FTLCapabilities.cpp:
+        (JSC::FTL::canCompile):
+        * ftl/FTLIntrinsicRepository.h:
+        * ftl/FTLLowerDFGToLLVM.cpp:
+        (JSC::FTL::DFG::LowerDFGToLLVM::compileNode):
+        (JSC::FTL::DFG::LowerDFGToLLVM::compileCreateClonedArguments):
+        (JSC::FTL::DFG::LowerDFGToLLVM::compileCopyRest):
+        (JSC::FTL::DFG::LowerDFGToLLVM::compileNewObject):
+        * jit/JIT.cpp:
+        (JSC::JIT::privateCompileMainPass):
+        * jit/JIT.h:
+        * jit/JITOpcodes.cpp:
+        (JSC::JIT::emit_op_create_out_of_band_arguments):
+        (JSC::JIT::emit_op_copy_rest):
+        * jit/JITOperations.h:
+        * llint/LowLevelInterpreter.asm:
+        * parser/ASTBuilder.h:
+        (JSC::ASTBuilder::createBindingLocation):
+        (JSC::ASTBuilder::createRestParameter):
+        (JSC::ASTBuilder::createAssignmentElement):
+        * parser/NodeConstructors.h:
+        (JSC::AssignmentElementNode::AssignmentElementNode):
+        (JSC::RestParameterNode::RestParameterNode):
+        (JSC::DestructuringAssignmentNode::DestructuringAssignmentNode):
+        * parser/Nodes.h:
+        (JSC::DestructuringPatternNode::isBindingNode):
+        (JSC::DestructuringPatternNode::isRestParameter):
+        (JSC::DestructuringPatternNode::emitDirectBinding):
+        (JSC::RestParameterNode::name):
+        * parser/Parser.cpp:
+        (JSC::Parser&lt;LexerType&gt;::parseVariableDeclarationList):
+        (JSC::Parser&lt;LexerType&gt;::declareRestOrNormalParameter):
+        (JSC::Parser&lt;LexerType&gt;::createBindingPattern):
+        (JSC::Parser&lt;LexerType&gt;::parseFormalParameters):
+        * parser/Parser.h:
+        (JSC::Parser::strictMode):
+        (JSC::Parser::isValidStrictMode):
+        (JSC::Parser::declareParameter):
+        (JSC::Parser::breakIsValid):
+        * parser/SyntaxChecker.h:
+        (JSC::SyntaxChecker::operatorStackPop):
+        * runtime/CommonSlowPaths.cpp:
+        (JSC::SLOW_PATH_DECL):
+        * runtime/CommonSlowPaths.h:
+        * tests/es6.yaml:
+        * tests/stress/rest-parameter-and-default-arguments.js: Added.
+        (assert):
+        (shouldThrowTDZ):
+        (foo):
+        (baz):
+        (i.shouldThrowTDZ):
+        * tests/stress/rest-parameter-basics.js: Added.
+        (assert):
+        (foo):
+        (bar):
+        (capture):
+        (baz):
+        (jaz):
+        (kaz):
+        (raz):
+        (restLength):
+        (testArgumentsObject):
+        (strictModeLikeArgumentsObject):
+        * tests/stress/rest-parameter-inlined.js: Added.
+        (assert):
+        (bar):
+        (foo):
+        (baz):
+        (jaz):
+
</ins><span class="cx"> 2015-11-19  Filip Pizlo  &lt;fpizlo@apple.com&gt;
</span><span class="cx"> 
</span><span class="cx">         B3 should have a story for Ext/Trunc strength reduction
</span></span></pre></div>
<a id="trunkSourceJavaScriptCorebytecodeBytecodeListjson"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/bytecode/BytecodeList.json (192670 => 192671)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/bytecode/BytecodeList.json        2015-11-20 01:28:30 UTC (rev 192670)
+++ trunk/Source/JavaScriptCore/bytecode/BytecodeList.json        2015-11-20 02:37:47 UTC (rev 192671)
</span><span class="lines">@@ -128,7 +128,8 @@
</span><span class="cx">             { &quot;name&quot; : &quot;op_enumerator_generic_pname&quot;, &quot;length&quot; : 4 },
</span><span class="cx">             { &quot;name&quot; : &quot;op_to_index_string&quot;, &quot;length&quot; : 3 },
</span><span class="cx">             { &quot;name&quot; : &quot;op_load_arrowfunction_this&quot;, &quot;length&quot; : 2 },
</span><del>-            { &quot;name&quot; : &quot;op_assert&quot;, &quot;length&quot; : 3 }
</del><ins>+            { &quot;name&quot; : &quot;op_assert&quot;, &quot;length&quot; : 3 },
+            { &quot;name&quot; : &quot;op_copy_rest&quot;, &quot;length&quot;: 3 }
</ins><span class="cx">         ]
</span><span class="cx">     },
</span><span class="cx">     {
</span></span></pre></div>
<a id="trunkSourceJavaScriptCorebytecodeBytecodeUseDefh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/bytecode/BytecodeUseDef.h (192670 => 192671)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/bytecode/BytecodeUseDef.h        2015-11-20 01:28:30 UTC (rev 192670)
+++ trunk/Source/JavaScriptCore/bytecode/BytecodeUseDef.h        2015-11-20 02:37:47 UTC (rev 192671)
</span><span class="lines">@@ -70,7 +70,8 @@
</span><span class="cx">     case op_jeq_null:
</span><span class="cx">     case op_jneq_null:
</span><span class="cx">     case op_dec:
</span><del>-    case op_inc: {
</del><ins>+    case op_inc: 
+    case op_copy_rest: {
</ins><span class="cx">         functor(codeBlock, instruction, opcodeID, instruction[1].u.operand);
</span><span class="cx">         return;
</span><span class="cx">     }
</span><span class="lines">@@ -247,6 +248,7 @@
</span><span class="cx">     OpcodeID opcodeID = interpreter-&gt;getOpcodeID(instruction-&gt;u.opcode);
</span><span class="cx">     switch (opcodeID) {
</span><span class="cx">     // These don't define anything.
</span><ins>+    case op_copy_rest:
</ins><span class="cx">     case op_put_to_scope:
</span><span class="cx">     case op_end:
</span><span class="cx">     case op_profile_will_call:
</span></span></pre></div>
<a id="trunkSourceJavaScriptCorebytecodeCodeBlockcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/bytecode/CodeBlock.cpp (192670 => 192671)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/bytecode/CodeBlock.cpp        2015-11-20 01:28:30 UTC (rev 192670)
+++ trunk/Source/JavaScriptCore/bytecode/CodeBlock.cpp        2015-11-20 02:37:47 UTC (rev 192671)
</span><span class="lines">@@ -781,6 +781,14 @@
</span><span class="cx">             out.printf(&quot;%s&quot;, registerName(r0).data());
</span><span class="cx">             break;
</span><span class="cx">         }
</span><ins>+        case op_copy_rest: {
+            int r0 = (++it)-&gt;u.operand;
+            printLocationAndOp(out, exec, location, it, &quot;copy_rest&quot;);
+            out.printf(&quot;%s, &quot;, registerName(r0).data());
+            unsigned argumentOffset = (++it)-&gt;u.unsignedValue;
+            out.printf(&quot;ArgumentsOffset: %u&quot;, argumentOffset);
+            break;
+        }
</ins><span class="cx">         case op_create_this: {
</span><span class="cx">             int r0 = (++it)-&gt;u.operand;
</span><span class="cx">             int r1 = (++it)-&gt;u.operand;
</span></span></pre></div>
<a id="trunkSourceJavaScriptCorebytecodeInstructionh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/bytecode/Instruction.h (192670 => 192671)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/bytecode/Instruction.h        2015-11-20 01:28:30 UTC (rev 192670)
+++ trunk/Source/JavaScriptCore/bytecode/Instruction.h        2015-11-20 02:37:47 UTC (rev 192671)
</span><span class="lines">@@ -75,6 +75,13 @@
</span><span class="cx">         u.jsCell.clear();
</span><span class="cx">         u.operand = operand;
</span><span class="cx">     }
</span><ins>+    Instruction(unsigned unsignedValue)
+    {
+        // We have to initialize one of the pointer members to ensure that
+        // the entire struct is initialized in 64-bit.
+        u.jsCell.clear();
+        u.unsignedValue = unsignedValue;
+    }
</ins><span class="cx"> 
</span><span class="cx">     Instruction(PutByIdFlags flags)
</span><span class="cx">     {
</span><span class="lines">@@ -112,6 +119,7 @@
</span><span class="cx">     union {
</span><span class="cx">         Opcode opcode;
</span><span class="cx">         int operand;
</span><ins>+        unsigned unsignedValue;
</ins><span class="cx">         WriteBarrierBase&lt;Structure&gt; structure;
</span><span class="cx">         StructureID structureID;
</span><span class="cx">         WriteBarrierBase&lt;SymbolTable&gt; symbolTable;
</span></span></pre></div>
<a id="trunkSourceJavaScriptCorebytecompilerBytecodeGeneratorcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/bytecompiler/BytecodeGenerator.cpp (192670 => 192671)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/bytecompiler/BytecodeGenerator.cpp        2015-11-20 01:28:30 UTC (rev 192670)
+++ trunk/Source/JavaScriptCore/bytecompiler/BytecodeGenerator.cpp        2015-11-20 02:37:47 UTC (rev 192671)
</span><span class="lines">@@ -70,6 +70,9 @@
</span><span class="cx">     if (m_needToInitializeArguments)
</span><span class="cx">         initializeVariable(variable(propertyNames().arguments), m_argumentsRegister);
</span><span class="cx"> 
</span><ins>+    if (m_restParameter)
+        m_restParameter-&gt;emit(*this);
+
</ins><span class="cx">     {
</span><span class="cx">         RefPtr&lt;RegisterID&gt; temp = newTemporary();
</span><span class="cx">         RefPtr&lt;RegisterID&gt; globalScope;
</span><span class="lines">@@ -272,8 +275,14 @@
</span><span class="cx">     // needing destructuring are noted.
</span><span class="cx">     m_parameters.grow(parameters.size() + 1); // reserve space for &quot;this&quot;
</span><span class="cx">     m_thisRegister.setIndex(initializeNextParameter()-&gt;index()); // this
</span><del>-    for (unsigned i = 0; i &lt; parameters.size(); ++i)
-        initializeNextParameter();
</del><ins>+    for (unsigned i = 0; i &lt; parameters.size(); ++i) {
+        auto pattern = parameters.at(i).first;
+        if (pattern-&gt;isRestParameter()) {
+            RELEASE_ASSERT(!m_restParameter);
+            m_restParameter = static_cast&lt;RestParameterNode*&gt;(pattern);
+        } else
+            initializeNextParameter();
+    }
</ins><span class="cx">     
</span><span class="cx">     // Figure out some interesting facts about our arguments.
</span><span class="cx">     bool capturesAnyArgumentByName = false;
</span><span class="lines">@@ -307,7 +316,14 @@
</span><span class="cx">         m_argumentsRegister-&gt;ref();
</span><span class="cx">     }
</span><span class="cx">     
</span><del>-    if (needsArguments &amp;&amp; !codeBlock-&gt;isStrictMode() &amp;&amp; !parameters.hasDefaultParameterValues()) {
</del><ins>+    // http://www.ecma-international.org/ecma-262/6.0/index.html#sec-functiondeclarationinstantiation
+    // This implements IsSimpleParameterList in the Ecma 2015 spec.
+    // If IsSimpleParameterList is false, we will create a strict-mode like arguments object.
+    // IsSimpleParameterList is false if the argument list contains any default parameter values,
+    // a rest parameter, or any destructuring patterns.
+    // FIXME: Take into account destructuring to make isSimpleParameterList false. https://bugs.webkit.org/show_bug.cgi?id=151450
+    bool isSimpleParameterList = !parameters.hasDefaultParameterValues() &amp;&amp; !m_restParameter;
+    if (needsArguments &amp;&amp; !codeBlock-&gt;isStrictMode() &amp;&amp; isSimpleParameterList) {
</ins><span class="cx">         // If we captured any formal parameter by name, then we use ScopedArguments. Otherwise we
</span><span class="cx">         // use DirectArguments. With ScopedArguments, we lift all of our arguments into the
</span><span class="cx">         // activation.
</span><span class="lines">@@ -389,7 +405,7 @@
</span><span class="cx">         }
</span><span class="cx">     }
</span><span class="cx">     
</span><del>-    if (needsArguments &amp;&amp; (codeBlock-&gt;isStrictMode() || parameters.hasDefaultParameterValues())) {
</del><ins>+    if (needsArguments &amp;&amp; (codeBlock-&gt;isStrictMode() || !isSimpleParameterList)) {
</ins><span class="cx">         // Allocate an out-of-bands arguments object.
</span><span class="cx">         emitOpcode(op_create_out_of_band_arguments);
</span><span class="cx">         instructions().append(m_argumentsRegister-&gt;index());
</span><span class="lines">@@ -707,6 +723,8 @@
</span><span class="cx">         RefPtr&lt;RegisterID&gt; temp = newTemporary();
</span><span class="cx">         for (unsigned i = 0; i &lt; parameters.size(); i++) {
</span><span class="cx">             std::pair&lt;DestructuringPatternNode*, ExpressionNode*&gt; parameter = parameters.at(i);
</span><ins>+            if (parameter.first-&gt;isRestParameter())
+                continue;
</ins><span class="cx">             RefPtr&lt;RegisterID&gt; parameterValue = &amp;registerFor(virtualRegisterForArgument(1 + i));
</span><span class="cx">             emitMove(temp.get(), parameterValue.get());
</span><span class="cx">             if (parameter.second) {
</span><span class="lines">@@ -764,7 +782,7 @@
</span><span class="cx">         // If we have default parameter values, we handle this case above.
</span><span class="cx">         for (unsigned i = 0; i &lt; parameters.size(); i++) {
</span><span class="cx">             DestructuringPatternNode* pattern = parameters.at(i).first;
</span><del>-            if (!pattern-&gt;isBindingNode()) {
</del><ins>+            if (!pattern-&gt;isBindingNode() &amp;&amp; !pattern-&gt;isRestParameter()) {
</ins><span class="cx">                 RefPtr&lt;RegisterID&gt; parameterValue = &amp;registerFor(virtualRegisterForArgument(1 + i));
</span><span class="cx">                 pattern-&gt;bindValue(*this, parameterValue.get());
</span><span class="cx">             }
</span><span class="lines">@@ -3813,4 +3831,15 @@
</span><span class="cx">     }
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+RegisterID* BytecodeGenerator::emitRestParameter(RegisterID* result, unsigned numParametersToSkip)
+{
+    emitNewArray(result, nullptr, 0);
+
+    emitOpcode(op_copy_rest);
+    instructions().append(result-&gt;index());
+    instructions().append(numParametersToSkip);
+
+    return result;
+}
+
</ins><span class="cx"> } // namespace JSC
</span></span></pre></div>
<a id="trunkSourceJavaScriptCorebytecompilerBytecodeGeneratorh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/bytecompiler/BytecodeGenerator.h (192670 => 192671)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/bytecompiler/BytecodeGenerator.h        2015-11-20 01:28:30 UTC (rev 192670)
+++ trunk/Source/JavaScriptCore/bytecompiler/BytecodeGenerator.h        2015-11-20 02:37:47 UTC (rev 192671)
</span><span class="lines">@@ -598,6 +598,8 @@
</span><span class="cx">         RegisterID* emitIteratorNext(RegisterID* dst, RegisterID* iterator, const ThrowableExpressionData* node);
</span><span class="cx">         void emitIteratorClose(RegisterID* iterator, const ThrowableExpressionData* node);
</span><span class="cx"> 
</span><ins>+        RegisterID* emitRestParameter(RegisterID* result, unsigned numParametersToSkip);
+
</ins><span class="cx">         bool emitReadOnlyExceptionIfNeeded(const Variable&amp;);
</span><span class="cx"> 
</span><span class="cx">         // Start a try block. 'start' must have been emitted.
</span><span class="lines">@@ -828,6 +830,7 @@
</span><span class="cx">         enum FunctionVariableType : uint8_t { NormalFunctionVariable, GlobalFunctionVariable };
</span><span class="cx">         Vector&lt;std::pair&lt;FunctionMetadataNode*, FunctionVariableType&gt;&gt; m_functionsToInitialize;
</span><span class="cx">         bool m_needToInitializeArguments { false };
</span><ins>+        RestParameterNode* m_restParameter { nullptr };
</ins><span class="cx">         
</span><span class="cx">         Vector&lt;TryRange&gt; m_tryRanges;
</span><span class="cx">         SegmentedVector&lt;TryData, 8&gt; m_tryData;
</span></span></pre></div>
<a id="trunkSourceJavaScriptCorebytecompilerNodesCodegencpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/bytecompiler/NodesCodegen.cpp (192670 => 192671)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/bytecompiler/NodesCodegen.cpp        2015-11-20 01:28:30 UTC (rev 192670)
+++ trunk/Source/JavaScriptCore/bytecompiler/NodesCodegen.cpp        2015-11-20 02:37:47 UTC (rev 192671)
</span><span class="lines">@@ -3456,6 +3456,35 @@
</span><span class="cx">         builder.append(static_cast&lt;ResolveNode*&gt;(m_assignmentTarget)-&gt;identifier().string());
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+void RestParameterNode::collectBoundIdentifiers(Vector&lt;Identifier&gt;&amp; identifiers) const
+{
+    identifiers.append(m_name);
+}
+void RestParameterNode::toString(StringBuilder&amp; builder) const
+{
+    builder.append(m_name.string());
+}
+void RestParameterNode::bindValue(BytecodeGenerator&amp;, RegisterID*) const
+{
+    RELEASE_ASSERT_NOT_REACHED();
+}
+void RestParameterNode::emit(BytecodeGenerator&amp; generator)
+{
+    Variable var = generator.variable(m_name);
+    if (RegisterID* local = var.local()) {
+        generator.emitRestParameter(local, m_numParametersToSkip);
+        generator.emitProfileType(local, var, m_divotStart, m_divotEnd);
+        return;
+    }
+
+    RefPtr&lt;RegisterID&gt; restParameterArray = generator.emitRestParameter(generator.newTemporary(), m_numParametersToSkip);
+    generator.emitProfileType(restParameterArray.get(), var, m_divotStart, m_divotEnd);
+    RefPtr&lt;RegisterID&gt; scope = generator.emitResolveScope(nullptr, var);
+    generator.emitExpressionInfo(m_divotEnd, m_divotStart, m_divotEnd);
+    generator.emitPutToScope(scope.get(), var, restParameterArray.get(), generator.isStrictMode() ? ThrowIfNotFound : DoNotThrowIfNotFound, Initialization);
+}
+
+
</ins><span class="cx"> RegisterID* SpreadExpressionNode::emitBytecode(BytecodeGenerator&amp;, RegisterID*)
</span><span class="cx"> {
</span><span class="cx">     RELEASE_ASSERT_NOT_REACHED();
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoredfgDFGAbstractInterpreterInlinesh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/dfg/DFGAbstractInterpreterInlines.h (192670 => 192671)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/dfg/DFGAbstractInterpreterInlines.h        2015-11-20 01:28:30 UTC (rev 192670)
+++ trunk/Source/JavaScriptCore/dfg/DFGAbstractInterpreterInlines.h        2015-11-20 02:37:47 UTC (rev 192671)
</span><span class="lines">@@ -2508,6 +2508,9 @@
</span><span class="cx">     case CheckTierUpAtReturn:
</span><span class="cx">         break;
</span><span class="cx"> 
</span><ins>+    case CopyRest:
+        break;
+            
</ins><span class="cx">     case Check: {
</span><span class="cx">         // Simplify out checks that don't actually do checking.
</span><span class="cx">         for (unsigned i = 0; i &lt; AdjacencyList::Size; ++i) {
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoredfgDFGByteCodeParsercpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/dfg/DFGByteCodeParser.cpp (192670 => 192671)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/dfg/DFGByteCodeParser.cpp        2015-11-20 01:28:30 UTC (rev 192670)
+++ trunk/Source/JavaScriptCore/dfg/DFGByteCodeParser.cpp        2015-11-20 02:37:47 UTC (rev 192671)
</span><span class="lines">@@ -3330,6 +3330,13 @@
</span><span class="cx">             set(VirtualRegister(currentInstruction[1].u.operand), addToGraph(NewRegexp, OpInfo(currentInstruction[2].u.operand)));
</span><span class="cx">             NEXT_OPCODE(op_new_regexp);
</span><span class="cx">         }
</span><ins>+
+        case op_copy_rest: {
+            noticeArgumentsUse();
+            addToGraph(CopyRest,
+                OpInfo(currentInstruction[2].u.unsignedValue), get(VirtualRegister(currentInstruction[1].u.operand)));
+            NEXT_OPCODE(op_copy_rest);
+        }
</ins><span class="cx">             
</span><span class="cx">         // === Bitwise operations ===
</span><span class="cx"> 
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoredfgDFGCapabilitiescpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/dfg/DFGCapabilities.cpp (192670 => 192671)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/dfg/DFGCapabilities.cpp        2015-11-20 01:28:30 UTC (rev 192670)
+++ trunk/Source/JavaScriptCore/dfg/DFGCapabilities.cpp        2015-11-20 02:37:47 UTC (rev 192671)
</span><span class="lines">@@ -219,6 +219,7 @@
</span><span class="cx">     case op_create_lexical_environment:
</span><span class="cx">     case op_get_parent_scope:
</span><span class="cx">     case op_catch:
</span><ins>+    case op_copy_rest:
</ins><span class="cx">         return CanCompileAndInline;
</span><span class="cx"> 
</span><span class="cx">     case op_put_to_scope: {
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoredfgDFGClobberizeh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/dfg/DFGClobberize.h (192670 => 192671)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/dfg/DFGClobberize.h        2015-11-20 01:28:30 UTC (rev 192670)
+++ trunk/Source/JavaScriptCore/dfg/DFGClobberize.h        2015-11-20 02:37:47 UTC (rev 192671)
</span><span class="lines">@@ -983,6 +983,12 @@
</span><span class="cx">         return;
</span><span class="cx">     }
</span><span class="cx"> 
</span><ins>+    case CopyRest: {
+        read(Stack);
+        write(Heap);
+        return;
+    }
+
</ins><span class="cx">     case NewObject:
</span><span class="cx">     case NewRegexp:
</span><span class="cx">     case NewStringObject:
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoredfgDFGDoesGCcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/dfg/DFGDoesGC.cpp (192670 => 192671)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/dfg/DFGDoesGC.cpp        2015-11-20 01:28:30 UTC (rev 192670)
+++ trunk/Source/JavaScriptCore/dfg/DFGDoesGC.cpp        2015-11-20 02:37:47 UTC (rev 192671)
</span><span class="lines">@@ -224,6 +224,7 @@
</span><span class="cx">     case GetStack:
</span><span class="cx">     case GetFromArguments:
</span><span class="cx">     case PutToArguments:
</span><ins>+    case CopyRest:
</ins><span class="cx">         return false;
</span><span class="cx"> 
</span><span class="cx">     case CreateActivation:
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoredfgDFGFixupPhasecpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/dfg/DFGFixupPhase.cpp (192670 => 192671)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/dfg/DFGFixupPhase.cpp        2015-11-20 01:28:30 UTC (rev 192670)
+++ trunk/Source/JavaScriptCore/dfg/DFGFixupPhase.cpp        2015-11-20 02:37:47 UTC (rev 192671)
</span><span class="lines">@@ -1368,6 +1368,11 @@
</span><span class="cx">             break;
</span><span class="cx">         }
</span><span class="cx"> 
</span><ins>+        case CopyRest: {
+            fixEdge&lt;KnownCellUse&gt;(node-&gt;child1());
+            break;
+        }
+
</ins><span class="cx"> #if !ASSERT_DISABLED
</span><span class="cx">         // Have these no-op cases here to ensure that nobody forgets to add handlers for new opcodes.
</span><span class="cx">         case SetArgument:
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoredfgDFGNodeh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/dfg/DFGNode.h (192670 => 192671)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/dfg/DFGNode.h        2015-11-20 01:28:30 UTC (rev 192670)
+++ trunk/Source/JavaScriptCore/dfg/DFGNode.h        2015-11-20 02:37:47 UTC (rev 192671)
</span><span class="lines">@@ -2158,7 +2158,13 @@
</span><span class="cx">     {
</span><span class="cx">         m_misc.epoch = epoch.toUnsigned();
</span><span class="cx">     }
</span><del>-    
</del><ins>+
+    unsigned numberOfArgumentsToSkip()
+    {
+        ASSERT(op() == CopyRest);
+        return static_cast&lt;unsigned&gt;(m_opInfo);
+    }
+
</ins><span class="cx">     void dumpChildren(PrintStream&amp; out)
</span><span class="cx">     {
</span><span class="cx">         if (!child1())
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoredfgDFGNodeTypeh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/dfg/DFGNodeType.h (192670 => 192671)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/dfg/DFGNodeType.h        2015-11-20 01:28:30 UTC (rev 192670)
+++ trunk/Source/JavaScriptCore/dfg/DFGNodeType.h        2015-11-20 02:37:47 UTC (rev 192671)
</span><span class="lines">@@ -262,6 +262,7 @@
</span><span class="cx">     macro(NewArrayBuffer, NodeResultJS) \
</span><span class="cx">     macro(NewTypedArray, NodeResultJS | NodeMustGenerate) \
</span><span class="cx">     macro(NewRegexp, NodeResultJS) \
</span><ins>+    macro(CopyRest, NodeMustGenerate) \
</ins><span class="cx">     \
</span><span class="cx">     /* Support for allocation sinking. */\
</span><span class="cx">     macro(PhantomNewObject, NodeResultJS | NodeMustGenerate) \
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoredfgDFGOperationscpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/dfg/DFGOperations.cpp (192670 => 192671)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/dfg/DFGOperations.cpp        2015-11-20 01:28:30 UTC (rev 192670)
+++ trunk/Source/JavaScriptCore/dfg/DFGOperations.cpp        2015-11-20 02:37:47 UTC (rev 192671)
</span><span class="lines">@@ -818,6 +818,16 @@
</span><span class="cx">     return result;
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+void JIT_OPERATION operationCopyRest(ExecState* exec, JSCell* arrayAsCell, Register* argumentStart, unsigned numberOfParamsToSkip, unsigned numberOfArguments)
+{
+    RELEASE_ASSERT(numberOfArguments &gt; numberOfParamsToSkip); // We should only call this from JIT code when this condition is true.
+    JSArray* array = jsCast&lt;JSArray*&gt;(arrayAsCell);
+    unsigned arraySize = numberOfArguments - numberOfParamsToSkip;
+    array-&gt;setLength(exec, arraySize);
+    for (unsigned i = 0; i &lt; arraySize; i++)
+        array-&gt;putDirectIndex(exec, i, argumentStart[i + numberOfParamsToSkip].jsValue());
+}
+
</ins><span class="cx"> size_t JIT_OPERATION operationObjectIsObject(ExecState* exec, JSGlobalObject* globalObject, JSCell* object)
</span><span class="cx"> {
</span><span class="cx">     VM&amp; vm = exec-&gt;vm();
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoredfgDFGOperationsh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/dfg/DFGOperations.h (192670 => 192671)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/dfg/DFGOperations.h        2015-11-20 01:28:30 UTC (rev 192670)
+++ trunk/Source/JavaScriptCore/dfg/DFGOperations.h        2015-11-20 02:37:47 UTC (rev 192671)
</span><span class="lines">@@ -103,6 +103,7 @@
</span><span class="cx"> JSCell* JIT_OPERATION operationCreateScopedArguments(ExecState*, Structure*, Register* argumentStart, int32_t length, JSFunction* callee, JSLexicalEnvironment*);
</span><span class="cx"> JSCell* JIT_OPERATION operationCreateClonedArgumentsDuringExit(ExecState*, InlineCallFrame*, JSFunction*, int32_t argumentCount);
</span><span class="cx"> JSCell* JIT_OPERATION operationCreateClonedArguments(ExecState*, Structure*, Register* argumentStart, int32_t length, JSFunction* callee);
</span><ins>+void JIT_OPERATION operationCopyRest(ExecState*, JSCell*, Register* argumentStart, unsigned numberOfParamsToSkip, unsigned argumentsCount);
</ins><span class="cx"> double JIT_OPERATION operationFModOnInts(int32_t, int32_t) WTF_INTERNAL;
</span><span class="cx"> size_t JIT_OPERATION operationObjectIsObject(ExecState*, JSGlobalObject*, JSCell*) WTF_INTERNAL;
</span><span class="cx"> size_t JIT_OPERATION operationObjectIsFunction(ExecState*, JSGlobalObject*, JSCell*) WTF_INTERNAL;
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoredfgDFGPredictionPropagationPhasecpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/dfg/DFGPredictionPropagationPhase.cpp (192670 => 192671)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/dfg/DFGPredictionPropagationPhase.cpp        2015-11-20 01:28:30 UTC (rev 192670)
+++ trunk/Source/JavaScriptCore/dfg/DFGPredictionPropagationPhase.cpp        2015-11-20 02:37:47 UTC (rev 192671)
</span><span class="lines">@@ -676,6 +676,7 @@
</span><span class="cx">         case ZombieHint:
</span><span class="cx">         case ExitOK:
</span><span class="cx">         case LoadVarargs:
</span><ins>+        case CopyRest:
</ins><span class="cx">             break;
</span><span class="cx">             
</span><span class="cx">         // This gets ignored because it only pretends to produce a value.
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoredfgDFGSafeToExecuteh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/dfg/DFGSafeToExecute.h (192670 => 192671)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/dfg/DFGSafeToExecute.h        2015-11-20 01:28:30 UTC (rev 192670)
+++ trunk/Source/JavaScriptCore/dfg/DFGSafeToExecute.h        2015-11-20 02:37:47 UTC (rev 192671)
</span><span class="lines">@@ -322,6 +322,7 @@
</span><span class="cx">     case PhantomClonedArguments:
</span><span class="cx">     case GetMyArgumentByVal:
</span><span class="cx">     case ForwardVarargs:
</span><ins>+    case CopyRest:
</ins><span class="cx">         return true;
</span><span class="cx"> 
</span><span class="cx">     case BottomValue:
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoredfgDFGSpeculativeJITcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/dfg/DFGSpeculativeJIT.cpp (192670 => 192671)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/dfg/DFGSpeculativeJIT.cpp        2015-11-20 01:28:30 UTC (rev 192670)
+++ trunk/Source/JavaScriptCore/dfg/DFGSpeculativeJIT.cpp        2015-11-20 02:37:47 UTC (rev 192671)
</span><span class="lines">@@ -5344,6 +5344,34 @@
</span><span class="cx">     cellResult(resultGPR, node);
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+void SpeculativeJIT::compileCopyRest(Node* node)
+{
+    ASSERT(node-&gt;op() == CopyRest);
+
+    SpeculateCellOperand array(this, node-&gt;child1());
+    GPRReg arrayGPR = array.gpr();
+
+    GPRTemporary argumentsLength(this);
+    GPRReg argumentsLengthGPR = argumentsLength.gpr();
+
+    GPRTemporary argumentsStart(this);
+    GPRReg argumentsStartGPR = argumentsStart.gpr();
+
+    emitGetLength(node-&gt;origin.semantic, argumentsLengthGPR);
+    CCallHelpers::Jump done = m_jit.branch32(MacroAssembler::LessThanOrEqual, argumentsLengthGPR, TrustedImm32(node-&gt;numberOfArgumentsToSkip()));
+
+    emitGetArgumentStart(node-&gt;origin.semantic, argumentsStartGPR);
+    silentSpillAllRegisters(argumentsLengthGPR, argumentsStartGPR);
+    // Arguments: 0:exec, 1:JSCell* array, 2:arguments start, 3:number of arguments to skip, 4:number of arguments
+    callOperation(operationCopyRest, arrayGPR, argumentsStartGPR, TrustedImm32(node-&gt;numberOfArgumentsToSkip()), argumentsLengthGPR);
+    silentFillAllRegisters(argumentsLengthGPR);
+    m_jit.exceptionCheck();
+
+    done.link(&amp;m_jit);
+
+    noResult(node);
+}
+
</ins><span class="cx"> void SpeculativeJIT::compileNotifyWrite(Node* node)
</span><span class="cx"> {
</span><span class="cx">     WatchpointSet* set = node-&gt;watchpointSet();
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoredfgDFGSpeculativeJITh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/dfg/DFGSpeculativeJIT.h (192670 => 192671)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/dfg/DFGSpeculativeJIT.h        2015-11-20 01:28:30 UTC (rev 192670)
+++ trunk/Source/JavaScriptCore/dfg/DFGSpeculativeJIT.h        2015-11-20 02:37:47 UTC (rev 192671)
</span><span class="lines">@@ -1221,6 +1221,12 @@
</span><span class="cx">         return appendCall(operation);
</span><span class="cx">     }
</span><span class="cx"> 
</span><ins>+    JITCompiler::Call callOperation(V_JITOperation_ECRUiUi operation, GPRReg arg1, GPRReg arg2, TrustedImm32 arg3, GPRReg arg4)
+    {
+        m_jit.setupArgumentsWithExecState(arg1, arg2, arg3, arg4);
+        return appendCall(operation);
+    }
+
</ins><span class="cx"> #if USE(JSVALUE64)
</span><span class="cx">     JITCompiler::Call callOperation(J_JITOperation_E operation, GPRReg result)
</span><span class="cx">     {
</span><span class="lines">@@ -2238,6 +2244,7 @@
</span><span class="cx">     void compilePutToArguments(Node*);
</span><span class="cx">     void compileCreateScopedArguments(Node*);
</span><span class="cx">     void compileCreateClonedArguments(Node*);
</span><ins>+    void compileCopyRest(Node*);
</ins><span class="cx">     void compileNotifyWrite(Node*);
</span><span class="cx">     bool compileRegExpExec(Node*);
</span><span class="cx">     void compileIsObjectOrNull(Node*);
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoredfgDFGSpeculativeJIT32_64cpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/dfg/DFGSpeculativeJIT32_64.cpp (192670 => 192671)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/dfg/DFGSpeculativeJIT32_64.cpp        2015-11-20 01:28:30 UTC (rev 192670)
+++ trunk/Source/JavaScriptCore/dfg/DFGSpeculativeJIT32_64.cpp        2015-11-20 02:37:47 UTC (rev 192671)
</span><span class="lines">@@ -4438,6 +4438,11 @@
</span><span class="cx">         break;
</span><span class="cx">     }
</span><span class="cx"> 
</span><ins>+    case CopyRest: {
+        compileCopyRest(node);
+        break;
+    }
+
</ins><span class="cx">     case NewFunction:
</span><span class="cx">     case NewArrowFunction:
</span><span class="cx">         compileNewFunction(node);
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoredfgDFGSpeculativeJIT64cpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/dfg/DFGSpeculativeJIT64.cpp (192670 => 192671)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/dfg/DFGSpeculativeJIT64.cpp        2015-11-20 01:28:30 UTC (rev 192670)
+++ trunk/Source/JavaScriptCore/dfg/DFGSpeculativeJIT64.cpp        2015-11-20 02:37:47 UTC (rev 192671)
</span><span class="lines">@@ -4427,6 +4427,10 @@
</span><span class="cx">         compileCreateClonedArguments(node);
</span><span class="cx">         break;
</span><span class="cx">     }
</span><ins>+    case CopyRest: {
+        compileCopyRest(node);
+        break;
+    }
</ins><span class="cx"> 
</span><span class="cx">     case NewFunction:
</span><span class="cx">     case NewArrowFunction:
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreftlFTLCapabilitiescpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/ftl/FTLCapabilities.cpp (192670 => 192671)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/ftl/FTLCapabilities.cpp        2015-11-20 01:28:30 UTC (rev 192670)
+++ trunk/Source/JavaScriptCore/ftl/FTLCapabilities.cpp        2015-11-20 02:37:47 UTC (rev 192671)
</span><span class="lines">@@ -210,6 +210,7 @@
</span><span class="cx">     case PutGetterSetterById:
</span><span class="cx">     case PutGetterByVal:
</span><span class="cx">     case PutSetterByVal:
</span><ins>+    case CopyRest:
</ins><span class="cx">         // These are OK.
</span><span class="cx">         break;
</span><span class="cx"> 
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreftlFTLIntrinsicRepositoryh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/ftl/FTLIntrinsicRepository.h (192670 => 192671)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/ftl/FTLIntrinsicRepository.h        2015-11-20 01:28:30 UTC (rev 192670)
+++ trunk/Source/JavaScriptCore/ftl/FTLIntrinsicRepository.h        2015-11-20 02:37:47 UTC (rev 192671)
</span><span class="lines">@@ -130,6 +130,7 @@
</span><span class="cx">     macro(Z_JITOperation_EGC, functionType(int32, intPtr, intPtr, intPtr)) \
</span><span class="cx">     macro(Z_JITOperation_EJZ, functionType(int32, intPtr, int64, int32)) \
</span><span class="cx">     macro(Z_JITOperation_ESJss, functionType(int32, intPtr, intPtr, int64)) \
</span><ins>+    macro(V_JITOperation_ECRUiUi, functionType(voidType, intPtr, intPtr, intPtr, int32, int32))
</ins><span class="cx">     
</span><span class="cx"> class IntrinsicRepository : public CommonValues {
</span><span class="cx"> public:
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreftlFTLLowerDFGToLLVMcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/ftl/FTLLowerDFGToLLVM.cpp (192670 => 192671)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/ftl/FTLLowerDFGToLLVM.cpp        2015-11-20 01:28:30 UTC (rev 192670)
+++ trunk/Source/JavaScriptCore/ftl/FTLLowerDFGToLLVM.cpp        2015-11-20 02:37:47 UTC (rev 192671)
</span><span class="lines">@@ -967,6 +967,9 @@
</span><span class="cx">         case CheckWatchdogTimer:
</span><span class="cx">             compileCheckWatchdogTimer();
</span><span class="cx">             break;
</span><ins>+        case CopyRest:
+            compileCopyRest();
+            break;
</ins><span class="cx"> 
</span><span class="cx">         case PhantomLocal:
</span><span class="cx">         case LoopHint:
</span><span class="lines">@@ -3636,6 +3639,28 @@
</span><span class="cx">         
</span><span class="cx">         setJSValue(result);
</span><span class="cx">     }
</span><ins>+
+    void compileCopyRest()
+    {            
+        LBasicBlock doCopyRest = FTL_NEW_BLOCK(m_out, (&quot;CopyRest C call&quot;));
+        LBasicBlock continuation = FTL_NEW_BLOCK(m_out, (&quot;FillRestParameter continuation&quot;));
+
+        LValue numberOfArgumentsToSkip = m_out.constInt32(m_node-&gt;numberOfArgumentsToSkip());
+        LValue numberOfArguments = getArgumentsLength().value;
+
+        m_out.branch(
+            m_out.above(numberOfArguments, numberOfArgumentsToSkip),
+            unsure(doCopyRest), unsure(continuation));
+            
+        LBasicBlock lastNext = m_out.appendTo(doCopyRest, continuation);
+        // Arguments: 0:exec, 1:JSCell* array, 2:arguments start, 3:number of arguments to skip, 4:number of arguments
+        vmCall(
+            m_out.voidType,m_out.operation(operationCopyRest), m_callFrame, lowCell(m_node-&gt;child1()),
+            getArgumentsStart(), numberOfArgumentsToSkip, numberOfArguments);
+        m_out.jump(continuation);
+
+        m_out.appendTo(continuation, lastNext);
+    }
</ins><span class="cx">     
</span><span class="cx">     void compileNewObject()
</span><span class="cx">     {
</span></span></pre></div>
<a id="trunkSourceJavaScriptCorejitJITcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/jit/JIT.cpp (192670 => 192671)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/jit/JIT.cpp        2015-11-20 01:28:30 UTC (rev 192670)
+++ trunk/Source/JavaScriptCore/jit/JIT.cpp        2015-11-20 02:37:47 UTC (rev 192671)
</span><span class="lines">@@ -211,6 +211,7 @@
</span><span class="cx">         DEFINE_OP(op_create_direct_arguments)
</span><span class="cx">         DEFINE_OP(op_create_scoped_arguments)
</span><span class="cx">         DEFINE_OP(op_create_out_of_band_arguments)
</span><ins>+        DEFINE_OP(op_copy_rest)
</ins><span class="cx">         DEFINE_OP(op_check_tdz)
</span><span class="cx">         DEFINE_OP(op_assert)
</span><span class="cx">         DEFINE_OP(op_debug)
</span></span></pre></div>
<a id="trunkSourceJavaScriptCorejitJITh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/jit/JIT.h (192670 => 192671)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/jit/JIT.h        2015-11-20 01:28:30 UTC (rev 192670)
+++ trunk/Source/JavaScriptCore/jit/JIT.h        2015-11-20 02:37:47 UTC (rev 192671)
</span><span class="lines">@@ -490,6 +490,7 @@
</span><span class="cx">         void emit_op_create_direct_arguments(Instruction*);
</span><span class="cx">         void emit_op_create_scoped_arguments(Instruction*);
</span><span class="cx">         void emit_op_create_out_of_band_arguments(Instruction*);
</span><ins>+        void emit_op_copy_rest(Instruction*);
</ins><span class="cx">         void emit_op_check_tdz(Instruction*);
</span><span class="cx">         void emit_op_assert(Instruction*);
</span><span class="cx">         void emit_op_debug(Instruction*);
</span></span></pre></div>
<a id="trunkSourceJavaScriptCorejitJITOpcodescpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/jit/JITOpcodes.cpp (192670 => 192671)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/jit/JITOpcodes.cpp        2015-11-20 01:28:30 UTC (rev 192670)
+++ trunk/Source/JavaScriptCore/jit/JITOpcodes.cpp        2015-11-20 02:37:47 UTC (rev 192671)
</span><span class="lines">@@ -1399,6 +1399,12 @@
</span><span class="cx">     slowPathCall.call();
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+void JIT::emit_op_copy_rest(Instruction* currentInstruction)
+{
+    JITSlowPathCall slowPathCall(this, currentInstruction, slow_path_copy_rest);
+    slowPathCall.call();
+}
+
</ins><span class="cx"> } // namespace JSC
</span><span class="cx"> 
</span><span class="cx"> #endif // ENABLE(JIT)
</span></span></pre></div>
<a id="trunkSourceJavaScriptCorejitJITOperationsh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/jit/JITOperations.h (192670 => 192671)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/jit/JITOperations.h        2015-11-20 01:28:30 UTC (rev 192670)
+++ trunk/Source/JavaScriptCore/jit/JITOperations.h        2015-11-20 02:37:47 UTC (rev 192671)
</span><span class="lines">@@ -92,6 +92,7 @@
</span><span class="cx">     Vm: VM*
</span><span class="cx">     Ws: WatchpointSet*
</span><span class="cx">     Z: int32_t
</span><ins>+    Ui: uint32_t
</ins><span class="cx"> */
</span><span class="cx"> 
</span><span class="cx"> typedef CallFrame* JIT_OPERATION (*F_JITOperation_EFJZZ)(ExecState*, CallFrame*, EncodedJSValue, int32_t, int32_t);
</span><span class="lines">@@ -219,6 +220,7 @@
</span><span class="cx"> typedef void JIT_OPERATION (*V_JITOperation_EVm)(ExecState*, VM*);
</span><span class="cx"> typedef void JIT_OPERATION (*V_JITOperation_J)(EncodedJSValue);
</span><span class="cx"> typedef void JIT_OPERATION (*V_JITOperation_Z)(int32_t);
</span><ins>+typedef void JIT_OPERATION (*V_JITOperation_ECRUiUi)(ExecState*, JSCell*, Register*, uint32_t, uint32_t);
</ins><span class="cx"> typedef char* JIT_OPERATION (*P_JITOperation_E)(ExecState*);
</span><span class="cx"> typedef char* JIT_OPERATION (*P_JITOperation_EC)(ExecState*, JSCell*);
</span><span class="cx"> typedef char* JIT_OPERATION (*P_JITOperation_ECli)(ExecState*, CallLinkInfo*);
</span></span></pre></div>
<a id="trunkSourceJavaScriptCorellintLowLevelInterpreterasm"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/llint/LowLevelInterpreter.asm (192670 => 192671)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/llint/LowLevelInterpreter.asm        2015-11-20 01:28:30 UTC (rev 192670)
+++ trunk/Source/JavaScriptCore/llint/LowLevelInterpreter.asm        2015-11-20 02:37:47 UTC (rev 192671)
</span><span class="lines">@@ -1675,6 +1675,12 @@
</span><span class="cx">     callSlowPath(_slow_path_to_index_string)
</span><span class="cx">     dispatch(3)
</span><span class="cx"> 
</span><ins>+_llint_op_copy_rest:
+    traceExecution()
+    callSlowPath(_slow_path_copy_rest)
+    dispatch(3)
+
+
</ins><span class="cx"> # Lastly, make sure that we can link even though we don't support all opcodes.
</span><span class="cx"> # These opcodes should never arise when using LLInt or either JIT. We assert
</span><span class="cx"> # as much.
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreparserASTBuilderh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/parser/ASTBuilder.h (192670 => 192671)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/parser/ASTBuilder.h        2015-11-20 01:28:30 UTC (rev 192670)
+++ trunk/Source/JavaScriptCore/parser/ASTBuilder.h        2015-11-20 02:37:47 UTC (rev 192671)
</span><span class="lines">@@ -857,6 +857,11 @@
</span><span class="cx">         return new (m_parserArena) BindingNode(boundProperty, start, end, context);
</span><span class="cx">     }
</span><span class="cx"> 
</span><ins>+    RestParameterNode* createRestParameter(const Identifier&amp; name, size_t numParametersToSkip, const JSTextPosition&amp; start, const JSTextPosition&amp; end)
+    {
+        return new (m_parserArena) RestParameterNode(name, numParametersToSkip, start, end);
+    }
+
</ins><span class="cx">     AssignmentElement createAssignmentElement(const Expression&amp; assignmentTarget, const JSTextPosition&amp; start, const JSTextPosition&amp; end)
</span><span class="cx">     {
</span><span class="cx">         return new (m_parserArena) AssignmentElementNode(assignmentTarget, start, end);
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreparserNodeConstructorsh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/parser/NodeConstructors.h (192670 => 192671)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/parser/NodeConstructors.h        2015-11-20 01:28:30 UTC (rev 192670)
+++ trunk/Source/JavaScriptCore/parser/NodeConstructors.h        2015-11-20 02:37:47 UTC (rev 192671)
</span><span class="lines">@@ -1029,6 +1029,15 @@
</span><span class="cx">     {
</span><span class="cx">     }
</span><span class="cx"> 
</span><ins>+    inline RestParameterNode::RestParameterNode(const Identifier&amp; name, unsigned numParametersToSkip, const JSTextPosition&amp; start, const JSTextPosition&amp; end)
+        : DestructuringPatternNode()
+        , m_name(name)
+        , m_numParametersToSkip(numParametersToSkip)
+        , m_divotStart(start)
+        , m_divotEnd(end)
+    {
+    }
+
</ins><span class="cx">     inline DestructuringAssignmentNode::DestructuringAssignmentNode(const JSTokenLocation&amp; location, DestructuringPatternNode* bindings, ExpressionNode* initializer)
</span><span class="cx">         : ExpressionNode(location)
</span><span class="cx">         , m_bindings(bindings)
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreparserNodesh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/parser/Nodes.h (192670 => 192671)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/parser/Nodes.h        2015-11-20 01:28:30 UTC (rev 192670)
+++ trunk/Source/JavaScriptCore/parser/Nodes.h        2015-11-20 02:37:47 UTC (rev 192671)
</span><span class="lines">@@ -1973,6 +1973,7 @@
</span><span class="cx">         virtual void toString(StringBuilder&amp;) const = 0;
</span><span class="cx"> 
</span><span class="cx">         virtual bool isBindingNode() const { return false; }
</span><ins>+        virtual bool isRestParameter() const { return false; }
</ins><span class="cx">         virtual RegisterID* emitDirectBinding(BytecodeGenerator&amp;, RegisterID*, ExpressionNode*) { return 0; }
</span><span class="cx">         
</span><span class="cx">     protected:
</span><span class="lines">@@ -2053,6 +2054,27 @@
</span><span class="cx">         AssignmentContext m_bindingContext;
</span><span class="cx">     };
</span><span class="cx"> 
</span><ins>+    class RestParameterNode : public DestructuringPatternNode {
+    public:
+        RestParameterNode(const Identifier&amp; boundProperty, unsigned numParametersToSkip, const JSTextPosition&amp; start, const JSTextPosition&amp; end);
+
+        bool isRestParameter() const override { return true; }
+
+        void emit(BytecodeGenerator&amp;);
+
+        const Identifier&amp; name() const { return m_name; }
+
+    private:
+        virtual void collectBoundIdentifiers(Vector&lt;Identifier&gt;&amp;) const override;
+        virtual void bindValue(BytecodeGenerator&amp;, RegisterID*) const override;
+        virtual void toString(StringBuilder&amp;) const override;
+
+        const Identifier&amp; m_name;
+        unsigned m_numParametersToSkip;
+        JSTextPosition m_divotStart; // &quot;f&quot; in &quot;...foo&quot;
+        JSTextPosition m_divotEnd;
+    };
+
</ins><span class="cx">     class AssignmentElementNode : public DestructuringPatternNode {
</span><span class="cx">     public:
</span><span class="cx">         AssignmentElementNode(ExpressionNode* assignmentTarget, const JSTextPosition&amp; start, const JSTextPosition&amp; end);
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreparserParsercpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/parser/Parser.cpp (192670 => 192671)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/parser/Parser.cpp        2015-11-20 01:28:30 UTC (rev 192670)
+++ trunk/Source/JavaScriptCore/parser/Parser.cpp        2015-11-20 02:37:47 UTC (rev 192671)
</span><span class="lines">@@ -669,6 +669,30 @@
</span><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> template &lt;typename LexerType&gt;
</span><ins>+bool Parser&lt;LexerType&gt;::declareRestOrNormalParameter(const Identifier&amp; name, const Identifier** duplicateIdentifier)
+{
+    DeclarationResultMask declarationResult = declareParameter(&amp;name);
+    if ((declarationResult &amp; DeclarationResult::InvalidStrictMode) &amp;&amp; strictMode()) {
+        semanticFailIfTrue(isEvalOrArguments(&amp;name), &quot;Cannot destructure to a parameter name '&quot;, name.impl(), &quot;' in strict mode&quot;);
+        if (m_lastFunctionName &amp;&amp; name == *m_lastFunctionName)
+            semanticFail(&quot;Cannot declare a parameter named '&quot;, name.impl(), &quot;' as it shadows the name of a strict mode function&quot;);
+        semanticFailureDueToKeyword(&quot;parameter name&quot;);
+        if (hasDeclaredParameter(name))
+            semanticFail(&quot;Cannot declare a parameter named '&quot;, name.impl(), &quot;' in strict mode as it has already been declared&quot;);
+        semanticFail(&quot;Cannot declare a parameter named '&quot;, name.impl(), &quot;' in strict mode&quot;);
+    }
+    if (declarationResult &amp; DeclarationResult::InvalidDuplicateDeclaration) {
+        // It's not always an error to define a duplicate parameter.
+        // It's only an error when there are default parameter values or destructuring parameters.
+        // We note this value now so we can check it later.
+        if (duplicateIdentifier)
+            *duplicateIdentifier = &amp;name;
+    }
+
+    return true;
+}
+
+template &lt;typename LexerType&gt;
</ins><span class="cx"> template &lt;class TreeBuilder&gt; TreeDestructuringPattern Parser&lt;LexerType&gt;::createBindingPattern(TreeBuilder&amp; context, DestructuringKind kind, ExportType exportType, const Identifier&amp; name, JSToken token, AssignmentContext bindingContext, const Identifier** duplicateIdentifier)
</span><span class="cx"> {
</span><span class="cx">     ASSERT(!name.isNull());
</span><span class="lines">@@ -687,23 +711,8 @@
</span><span class="cx">             failIfTrue(declarationResult &amp; DeclarationResult::InvalidDuplicateDeclaration, &quot;Cannot declare a lexical variable twice: '&quot;, name.impl(), &quot;'&quot;);
</span><span class="cx">         }
</span><span class="cx">     } else if (kind == DestructureToParameters) {
</span><del>-        DeclarationResultMask declarationResult = declareParameter(&amp;name);
-        if ((declarationResult &amp; DeclarationResult::InvalidStrictMode) &amp;&amp; strictMode()) {
-            semanticFailIfTrue(isEvalOrArguments(&amp;name), &quot;Cannot destructure to a parameter name '&quot;, name.impl(), &quot;' in strict mode&quot;);
-            if (m_lastFunctionName &amp;&amp; name == *m_lastFunctionName)
-                semanticFail(&quot;Cannot declare a parameter named '&quot;, name.impl(), &quot;' as it shadows the name of a strict mode function&quot;);
-            semanticFailureDueToKeyword(&quot;parameter name&quot;);
-            if (hasDeclaredParameter(name))
-                semanticFail(&quot;Cannot declare a parameter named '&quot;, name.impl(), &quot;' in strict mode as it has already been declared&quot;);
-            semanticFail(&quot;Cannot declare a parameter named '&quot;, name.impl(), &quot;' in strict mode&quot;);
-        }
-        if (declarationResult &amp; DeclarationResult::InvalidDuplicateDeclaration) {
-            // It's not always an error to define a duplicate parameter.
-            // It's only an error when there are default parameter values or destructuring parameters.
-            // We note this value now so we can check it later.
-            if (duplicateIdentifier)
-                *duplicateIdentifier = &amp;name;
-        }
</del><ins>+        declareRestOrNormalParameter(name, duplicateIdentifier);
+        propagateError();
</ins><span class="cx">     }
</span><span class="cx"> 
</span><span class="cx">     if (exportType == ExportType::Exported) {
</span><span class="lines">@@ -1536,32 +1545,45 @@
</span><span class="cx"> template &lt;typename LexerType&gt;
</span><span class="cx"> template &lt;class TreeBuilder&gt; bool Parser&lt;LexerType&gt;::parseFormalParameters(TreeBuilder&amp; context, TreeFormalParameterList list, unsigned&amp; parameterCount)
</span><span class="cx"> {
</span><del>-#define failFromDuplicate() \
</del><ins>+#define failIfDuplicateIfViolation() \
</ins><span class="cx">     if (duplicateParameter) {\
</span><span class="cx">         semanticFailIfTrue(defaultValue, &quot;Duplicate parameter '&quot;, duplicateParameter-&gt;impl(), &quot;' not allowed in function with default parameter values&quot;);\
</span><span class="cx">         semanticFailIfTrue(hasDestructuringPattern, &quot;Duplicate parameter '&quot;, duplicateParameter-&gt;impl(), &quot;' not allowed in function with destructuring parameters&quot;);\
</span><ins>+        semanticFailIfTrue(isRestParameter, &quot;Duplicate parameter '&quot;, duplicateParameter-&gt;impl(), &quot;' not allowed in function with a rest parameter&quot;);\
</ins><span class="cx">     }
</span><span class="cx"> 
</span><ins>+    bool hasDestructuringPattern = false;
+    bool isRestParameter = false;
</ins><span class="cx">     const Identifier* duplicateParameter = nullptr;
</span><del>-    bool hasDestructuringPattern = false;
-    auto parameter = parseDestructuringPattern(context, DestructureToParameters, ExportType::NotExported, &amp;duplicateParameter, &amp;hasDestructuringPattern);
-    failIfFalse(parameter, &quot;Cannot parse parameter pattern&quot;);
-    auto defaultValue = parseDefaultValueForDestructuringPattern(context);
-    propagateError();
-    failFromDuplicate();
-    context.appendParameter(list, parameter, defaultValue);
-    parameterCount++;
-    while (consume(COMMA)) {
-        parameter = parseDestructuringPattern(context, DestructureToParameters, ExportType::NotExported, &amp;duplicateParameter, &amp;hasDestructuringPattern);
</del><ins>+    do {
+        TreeDestructuringPattern parameter = 0;
+        TreeExpression defaultValue = 0;
+
+        if (match(DOTDOTDOT)) {
+            next();
+            failIfFalse(matchSpecIdentifier(), &quot;Rest parameter '...' should be followed by a variable identifier&quot;);
+            declareRestOrNormalParameter(*m_token.m_data.ident, &amp;duplicateParameter);
+            propagateError();
+            JSTextPosition identifierStart = tokenStartPosition();
+            JSTextPosition identifierEnd = tokenEndPosition();
+            parameter = context.createRestParameter(*m_token.m_data.ident, parameterCount, identifierStart, identifierEnd);
+            next();
+            failIfTrue(match(COMMA), &quot;Rest parameter should be the last parameter in a function declaration&quot;); // Let's have a good error message for this common case.
+            isRestParameter = true;
+        } else
+            parameter = parseDestructuringPattern(context, DestructureToParameters, ExportType::NotExported, &amp;duplicateParameter, &amp;hasDestructuringPattern);
</ins><span class="cx">         failIfFalse(parameter, &quot;Cannot parse parameter pattern&quot;);
</span><del>-        defaultValue = parseDefaultValueForDestructuringPattern(context);
</del><ins>+        if (!isRestParameter)
+            defaultValue = parseDefaultValueForDestructuringPattern(context);
</ins><span class="cx">         propagateError();
</span><del>-        failFromDuplicate();
</del><ins>+        failIfDuplicateIfViolation();
</ins><span class="cx">         context.appendParameter(list, parameter, defaultValue);
</span><del>-        parameterCount++;
-    }
</del><ins>+        if (!isRestParameter)
+            parameterCount++;
+    } while (!isRestParameter &amp;&amp; consume(COMMA));
+
</ins><span class="cx">     return true;
</span><del>-#undef failFromDuplicate
</del><ins>+#undef failIfDuplicateIfViolation
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> template &lt;typename LexerType&gt;
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreparserParserh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/parser/Parser.h (192670 => 192671)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/parser/Parser.h        2015-11-20 01:28:30 UTC (rev 192670)
+++ trunk/Source/JavaScriptCore/parser/Parser.h        2015-11-20 02:37:47 UTC (rev 192671)
</span><span class="lines">@@ -1073,6 +1073,8 @@
</span><span class="cx">     bool strictMode() { return currentScope()-&gt;strictMode(); }
</span><span class="cx">     bool isValidStrictMode() { return currentScope()-&gt;isValidStrictMode(); }
</span><span class="cx">     DeclarationResultMask declareParameter(const Identifier* ident) { return currentScope()-&gt;declareParameter(ident); }
</span><ins>+    bool declareRestOrNormalParameter(const Identifier&amp;, const Identifier**);
+
</ins><span class="cx">     bool breakIsValid()
</span><span class="cx">     {
</span><span class="cx">         ScopeRef current = currentScope();
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreparserSyntaxCheckerh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/parser/SyntaxChecker.h (192670 => 192671)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/parser/SyntaxChecker.h        2015-11-20 01:28:30 UTC (rev 192670)
+++ trunk/Source/JavaScriptCore/parser/SyntaxChecker.h        2015-11-20 02:37:47 UTC (rev 192671)
</span><span class="lines">@@ -75,7 +75,7 @@
</span><span class="cx">         FunctionExpr, ClassExpr, SuperExpr, BracketExpr, DotExpr, CallExpr,
</span><span class="cx">         NewExpr, PreExpr, PostExpr, UnaryExpr, BinaryExpr,
</span><span class="cx">         ConditionalExpr, AssignmentExpr, TypeofExpr, NewTargetExpr,
</span><del>-        DeleteExpr, ArrayLiteralExpr, BindingDestructuring,
</del><ins>+        DeleteExpr, ArrayLiteralExpr, BindingDestructuring, RestParameter,
</ins><span class="cx">         ArrayDestructuring, ObjectDestructuring, SourceElementsResult,
</span><span class="cx">         FunctionBodyResult, SpreadExpr, ArgumentsResult,
</span><span class="cx">         PropertyListResult, ArgumentsListResult, ElementsListResult,
</span><span class="lines">@@ -135,6 +135,7 @@
</span><span class="cx">     typedef int DestructuringPattern;
</span><span class="cx">     typedef DestructuringPattern ArrayPattern;
</span><span class="cx">     typedef DestructuringPattern ObjectPattern;
</span><ins>+    typedef DestructuringPattern RestPattern;
</ins><span class="cx"> 
</span><span class="cx">     static const bool CreatesAST = false;
</span><span class="cx">     static const bool NeedsFreeVariableInfo = false;
</span><span class="lines">@@ -346,6 +347,10 @@
</span><span class="cx">     {
</span><span class="cx">         return BindingDestructuring;
</span><span class="cx">     }
</span><ins>+    RestPattern createRestParameter(const Identifier&amp;, size_t, const JSTextPosition&amp;, const JSTextPosition&amp;)
+    { 
+        return RestParameter;
+    }
</ins><span class="cx">     DestructuringPattern createAssignmentElement(const Expression&amp;, const JSTextPosition&amp;, const JSTextPosition&amp;)
</span><span class="cx">     {
</span><span class="cx">         return BindingDestructuring;
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreruntimeCommonSlowPathscpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/runtime/CommonSlowPaths.cpp (192670 => 192671)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/runtime/CommonSlowPaths.cpp        2015-11-20 01:28:30 UTC (rev 192670)
+++ trunk/Source/JavaScriptCore/runtime/CommonSlowPaths.cpp        2015-11-20 02:37:47 UTC (rev 192671)
</span><span class="lines">@@ -701,4 +701,20 @@
</span><span class="cx">     RETURN(resolvedScope);
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+SLOW_PATH_DECL(slow_path_copy_rest)
+{
+    BEGIN();
+    unsigned numParamsToSkip = pc[2].u.unsignedValue;
+    unsigned numArgumentsToFunction = exec-&gt;argumentCount();
+    if (numArgumentsToFunction &lt;= numParamsToSkip)
+        END();
+
+    JSArray* array = jsCast&lt;JSArray*&gt;(OP(1).jsValue());
+    unsigned arraySize = numArgumentsToFunction - numParamsToSkip;
+    array-&gt;setLength(exec, arraySize);
+    for (unsigned i = 0; i &lt; arraySize; i++)
+        array-&gt;putDirectIndex(exec, i, exec-&gt;uncheckedArgument(i + numParamsToSkip));
+    END();
+}
+
</ins><span class="cx"> } // namespace JSC
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreruntimeCommonSlowPathsh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/runtime/CommonSlowPaths.h (192670 => 192671)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/runtime/CommonSlowPaths.h        2015-11-20 01:28:30 UTC (rev 192670)
+++ trunk/Source/JavaScriptCore/runtime/CommonSlowPaths.h        2015-11-20 02:37:47 UTC (rev 192671)
</span><span class="lines">@@ -293,6 +293,7 @@
</span><span class="cx"> SLOW_PATH_HIDDEN_DECL(slow_path_create_lexical_environment);
</span><span class="cx"> SLOW_PATH_HIDDEN_DECL(slow_path_push_with_scope);
</span><span class="cx"> SLOW_PATH_HIDDEN_DECL(slow_path_resolve_scope);
</span><ins>+SLOW_PATH_HIDDEN_DECL(slow_path_copy_rest);
</ins><span class="cx"> 
</span><span class="cx"> } // namespace JSC
</span><span class="cx"> 
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoretestses6yaml"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/tests/es6.yaml (192670 => 192671)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/tests/es6.yaml        2015-11-20 01:28:30 UTC (rev 192670)
+++ trunk/Source/JavaScriptCore/tests/es6.yaml        2015-11-20 02:37:47 UTC (rev 192671)
</span><span class="lines">@@ -1089,15 +1089,15 @@
</span><span class="cx"> - path: es6/RegExp_y_and_u_flags_y_flag_lastIndex.js
</span><span class="cx">   cmd: runES6 :fail
</span><span class="cx"> - path: es6/rest_parameters_arguments_object_interaction.js
</span><del>-  cmd: runES6 :fail
</del><ins>+  cmd: runES6 :normal
</ins><span class="cx"> - path: es6/rest_parameters_basic_functionality.js
</span><del>-  cmd: runES6 :fail
</del><ins>+  cmd: runES6 :normal
</ins><span class="cx"> - path: es6/rest_parameters_cant_be_used_in_setters.js
</span><del>-  cmd: runES6 :fail
</del><ins>+  cmd: runES6 :normal
</ins><span class="cx"> - path: es6/rest_parameters_function_length_property.js
</span><del>-  cmd: runES6 :fail
</del><ins>+  cmd: runES6 :normal
</ins><span class="cx"> - path: es6/rest_parameters_new_Function_support.js
</span><del>-  cmd: runES6 :fail
</del><ins>+  cmd: runES6 :normal
</ins><span class="cx"> - path: es6/Set_iterator_closing.js
</span><span class="cx">   cmd: runES6 :fail
</span><span class="cx"> - path: es6/Set_Set[Symbol.species].js
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoretestsstressrestparameteranddefaultargumentsjs"></a>
<div class="addfile"><h4>Added: trunk/Source/JavaScriptCore/tests/stress/rest-parameter-and-default-arguments.js (0 => 192671)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/tests/stress/rest-parameter-and-default-arguments.js                                (rev 0)
+++ trunk/Source/JavaScriptCore/tests/stress/rest-parameter-and-default-arguments.js        2015-11-20 02:37:47 UTC (rev 192671)
</span><span class="lines">@@ -0,0 +1,36 @@
</span><ins>+function assert(b) {
+    if (!b)
+        throw new Error(&quot;Bad assertion&quot;)
+}
+noInline(assert);
+
+function shouldThrowTDZ(func) {
+    var hasThrown = false;
+    try {
+        func();
+    } catch(e) {
+        if (e.name.indexOf(&quot;ReferenceError&quot;) !== -1)
+            hasThrown = true;
+    }
+    assert(hasThrown);
+}
+noInline(shouldThrowTDZ);
+
+function foo(a = function() { return c; }, b = a(), ...c) {
+    return a();
+}
+noInline(foo);
+
+function baz(a = function() { return b; }, ...b) {
+    return a();
+}
+
+for (let i = 0; i &lt; 1000; i++) {
+    shouldThrowTDZ(function() { foo(undefined, undefined, 10, 20); });
+    let o = {x: 20};
+    let result = baz(undefined, 10, o, &quot;baz&quot;);
+    assert(result.length === 3);
+    assert(result[0] === 10);
+    assert(result[1] === o);
+    assert(result[2] === &quot;baz&quot;);
+}
</ins></span></pre></div>
<a id="trunkSourceJavaScriptCoretestsstressrestparameterbasicsjs"></a>
<div class="addfile"><h4>Added: trunk/Source/JavaScriptCore/tests/stress/rest-parameter-basics.js (0 => 192671)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/tests/stress/rest-parameter-basics.js                                (rev 0)
+++ trunk/Source/JavaScriptCore/tests/stress/rest-parameter-basics.js        2015-11-20 02:37:47 UTC (rev 192671)
</span><span class="lines">@@ -0,0 +1,103 @@
</span><ins>+function assert(b) {
+    if (!b)
+        throw new Error(&quot;Bad assertion&quot;)
+}
+noInline(assert);
+
+function foo(a, ...b) {
+    return b;    
+}
+noInline(foo);
+
+function bar(a, ...b) {
+    return a + b[0];
+}
+noInline(bar);
+
+function baz(a, ...b) {
+    function capture() { return b; }
+    assert(b[0] === capture()[0]);
+    return a + b[0];
+}
+noInline(baz);
+
+function jaz(a, ...b) {
+    function capture() { return a + b[0]; }
+    assert(capture() === a + b[0]);
+    return a + b[0];
+}
+noInline(jaz);
+
+function kaz(a = 10, ...b) {
+    return a + b[0]
+}
+noInline(kaz);
+
+function raz(a = 10, ...b) {
+    function capture() { return a + b[0]; }
+    assert(capture() === a + b[0]);
+    return a + b[0];
+}
+noInline(raz);
+
+function restLength(a, ...b) {
+    return b.length;
+}
+noInline(restLength);
+
+function testArgumentsObject(...args) {
+    assert(args.length === arguments.length);
+    for (let i = 0; i &lt; args.length; i++)
+        assert(args[i] === arguments[i]);
+}
+noInline(testArgumentsObject);
+
+function strictModeLikeArgumentsObject(a, ...args) {
+    assert(arguments[0] === a);
+    a = &quot;a&quot;;
+    assert(arguments[0] !== a);
+    assert(arguments[0] === 20);
+    assert(arguments.length === 2);
+    assert(args.length === 1);
+    assert(arguments[1] === args[0]);
+    arguments[1] = &quot;b&quot;;
+    assert(args[0] !== &quot;b&quot;);
+}
+noInline(strictModeLikeArgumentsObject);
+
+for (let i = 0; i &lt; 10000; i++) {
+    let a1 = foo(10, 20);
+    assert(a1 instanceof Array);
+    assert(a1.length === 1);
+    assert(a1[0] === 20);
+
+    let a2 = foo(10);
+    assert(a2 instanceof Array);
+    assert(a2.length === 0);
+
+    let a3 = bar(10, 20);
+    assert(a3 === 30);
+
+    let a4 = baz(10, 20);
+    assert(a4 === 30);
+
+    let a5 = jaz(&quot;hello&quot;, &quot;world&quot;);
+    assert(a5 === &quot;helloworld&quot;);
+
+    let a6 = kaz(undefined, 40);
+    assert(a6 === 50);
+
+    let a7 = kaz(undefined, 40);
+    assert(a7 === 50);
+
+    assert(restLength() === 0);
+    assert(restLength(1) === 0);
+    assert(restLength(1, 1) === 1);
+    assert(restLength(1, 1, 1) === 2);
+    assert(restLength(1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1) === 20);
+
+    let obj = {foo: 40};
+    testArgumentsObject(&quot;hello&quot;, obj, 100, 12.34, &quot;world&quot;, obj, [1, 2, 3]);
+
+    strictModeLikeArgumentsObject(20, 30);
+}
</ins></span></pre></div>
<a id="trunkSourceJavaScriptCoretestsstressrestparameterinlinedjs"></a>
<div class="addfile"><h4>Added: trunk/Source/JavaScriptCore/tests/stress/rest-parameter-inlined.js (0 => 192671)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/tests/stress/rest-parameter-inlined.js                                (rev 0)
+++ trunk/Source/JavaScriptCore/tests/stress/rest-parameter-inlined.js        2015-11-20 02:37:47 UTC (rev 192671)
</span><span class="lines">@@ -0,0 +1,38 @@
</span><ins>+function assert(b) {
+    if (!b)
+        throw new Error(&quot;Bad assertion&quot;)
+}
+noInline(assert);
+
+function bar(...rest) {
+    return rest;
+}
+
+function foo(a, b, c) {
+    return bar(a, b, c);
+}
+noInline(foo);
+
+for (let i = 0; i &lt; 10000; i++) {
+    let result = foo(10, 20, 30);
+    assert(result.length === 3);
+    assert(result[0] === 10);
+    assert(result[1] === 20);
+    assert(result[2] === 30);
+}
+
+function baz(...rest) {
+    return rest;
+}
+function jaz(a, b, c) {
+    return baz.apply(null, Array.prototype.slice.call(arguments));
+}
+noInline(jaz);
+
+for (let i = 0; i &lt; 50000; i++) {
+    let result = jaz(10, 20, 30);
+    assert(result.length === 3);
+    assert(result[0] === 10);
+    assert(result[1] === 20);
+    assert(result[2] === 30);
+}
</ins></span></pre>
</div>
</div>

</body>
</html>