<!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>[166392] 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/166392">166392</a></dd>
<dt>Author</dt> <dd>oliver@apple.com</dd>
<dt>Date</dt> <dd>2014-03-27 18:10:25 -0700 (Thu, 27 Mar 2014)</dd>
</dl>

<h3>Log Message</h3>
<pre>Support spread operand in |new| expressions
https://bugs.webkit.org/show_bug.cgi?id=130877

Reviewed by Michael Saboff.

Source/JavaScriptCore:

Add support for the spread operator being applied in
|new| expressions.  This required adding support for
a new opcode, op_construct_varargs.  This is a relatively
simple refactoring of the call_varargs implementation.

* bytecode/BytecodeList.json:
* bytecode/BytecodeUseDef.h:
(JSC::computeUsesForBytecodeOffset):
(JSC::computeDefsForBytecodeOffset):
* bytecode/CallLinkInfo.cpp:
(JSC::CallLinkInfo::unlink):
* bytecode/CallLinkInfo.h:
(JSC::CallLinkInfo::callTypeFor):
(JSC::CallLinkInfo::specializationKind):
* bytecode/CodeBlock.cpp:
(JSC::CodeBlock::dumpBytecode):
(JSC::CodeBlock::CodeBlock):
* bytecompiler/BytecodeGenerator.cpp:
(JSC::BytecodeGenerator::emitCallVarargs):
(JSC::BytecodeGenerator::emitConstructVarargs):
(JSC::BytecodeGenerator::emitConstruct):
* bytecompiler/BytecodeGenerator.h:
* jit/JIT.cpp:
(JSC::JIT::privateCompileMainPass):
(JSC::JIT::privateCompileSlowCases):
* jit/JIT.h:
* jit/JITCall.cpp:
(JSC::JIT::compileOpCall):
(JSC::JIT::compileOpCallSlowCase):
(JSC::JIT::emit_op_construct_varargs):
(JSC::JIT::emitSlow_op_construct_varargs):
* jit/JITCall32_64.cpp:
(JSC::JIT::emitSlow_op_construct_varargs):
(JSC::JIT::emit_op_construct_varargs):
(JSC::JIT::compileOpCall):
(JSC::JIT::compileOpCallSlowCase):
* jit/JITOperations.cpp:
* llint/LLIntSlowPaths.cpp:
(JSC::LLInt::LLINT_SLOW_PATH_DECL):
* llint/LLIntSlowPaths.h:
* llint/LowLevelInterpreter.asm:
* parser/Parser.cpp:
(JSC::Parser&lt;LexerType&gt;::parseMemberExpression):

LayoutTests:

Correctness and performance tests for spread operands

* js/parser-syntax-check-expected.txt:
* js/regress/call-spread-expected.txt: Added.
* js/regress/call-spread.html: Added.
* js/regress/new-spread-expected.txt: Added.
* js/regress/new-spread.html: Added.
* js/regress/script-tests/call-spread.js: Added.
(testFunction):
(test2):
(test3):
* js/regress/script-tests/new-spread.js: Added.
(testFunction):
(test2):
(test3):
* js/script-tests/parser-syntax-check.js:</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="#trunkSourceJavaScriptCorebytecodeCallLinkInfocpp">trunk/Source/JavaScriptCore/bytecode/CallLinkInfo.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCorebytecodeCallLinkInfoh">trunk/Source/JavaScriptCore/bytecode/CallLinkInfo.h</a></li>
<li><a href="#trunkSourceJavaScriptCorebytecodeCodeBlockcpp">trunk/Source/JavaScriptCore/bytecode/CodeBlock.cpp</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="#trunkSourceJavaScriptCorejitJITcpp">trunk/Source/JavaScriptCore/jit/JIT.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCorejitJITh">trunk/Source/JavaScriptCore/jit/JIT.h</a></li>
<li><a href="#trunkSourceJavaScriptCorejitJITCallcpp">trunk/Source/JavaScriptCore/jit/JITCall.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCorejitJITCall32_64cpp">trunk/Source/JavaScriptCore/jit/JITCall32_64.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCorejitJITOperationscpp">trunk/Source/JavaScriptCore/jit/JITOperations.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCorellintLLIntSlowPathscpp">trunk/Source/JavaScriptCore/llint/LLIntSlowPaths.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCorellintLLIntSlowPathsh">trunk/Source/JavaScriptCore/llint/LLIntSlowPaths.h</a></li>
<li><a href="#trunkSourceJavaScriptCorellintLowLevelInterpreterasm">trunk/Source/JavaScriptCore/llint/LowLevelInterpreter.asm</a></li>
<li><a href="#trunkSourceJavaScriptCoreparserParsercpp">trunk/Source/JavaScriptCore/parser/Parser.cpp</a></li>
</ul>

<h3>Added Paths</h3>
<ul>
<li><a href="#trunkLayoutTestsjsregresscallspreadexpectedtxt">trunk/LayoutTests/js/regress/call-spread-expected.txt</a></li>
<li><a href="#trunkLayoutTestsjsregresscallspreadhtml">trunk/LayoutTests/js/regress/call-spread.html</a></li>
<li><a href="#trunkLayoutTestsjsregressnewspreadexpectedtxt">trunk/LayoutTests/js/regress/new-spread-expected.txt</a></li>
<li><a href="#trunkLayoutTestsjsregressnewspreadhtml">trunk/LayoutTests/js/regress/new-spread.html</a></li>
<li><a href="#trunkLayoutTestsjsregressscripttestscallspreadjs">trunk/LayoutTests/js/regress/script-tests/call-spread.js</a></li>
<li><a href="#trunkLayoutTestsjsregressscripttestsnewspreadjs">trunk/LayoutTests/js/regress/script-tests/new-spread.js</a></li>
</ul>

</div>
<div id="patch">
<h3>Diff</h3>
<a id="trunkLayoutTestsChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/LayoutTests/ChangeLog (166391 => 166392)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/ChangeLog        2014-03-28 01:00:35 UTC (rev 166391)
+++ trunk/LayoutTests/ChangeLog        2014-03-28 01:10:25 UTC (rev 166392)
</span><span class="lines">@@ -1,3 +1,27 @@
</span><ins>+2014-03-27  Oliver Hunt  &lt;oliver@apple.com&gt;
+
+        Support spread operand in |new| expressions
+        https://bugs.webkit.org/show_bug.cgi?id=130877
+
+        Reviewed by Michael Saboff.
+
+        Correctness and performance tests for spread operands
+
+        * js/parser-syntax-check-expected.txt:
+        * js/regress/call-spread-expected.txt: Added.
+        * js/regress/call-spread.html: Added.
+        * js/regress/new-spread-expected.txt: Added.
+        * js/regress/new-spread.html: Added.
+        * js/regress/script-tests/call-spread.js: Added.
+        (testFunction):
+        (test2):
+        (test3):
+        * js/regress/script-tests/new-spread.js: Added.
+        (testFunction):
+        (test2):
+        (test3):
+        * js/script-tests/parser-syntax-check.js:
+
</ins><span class="cx"> 2014-03-27  Bem Jones-Bey  &lt;bjonesbe@adobe.com&gt;
</span><span class="cx"> 
</span><span class="cx">         [CSS Shapes][css clip-path] rounded corner calculation for box shapes is wrong
</span></span></pre></div>
<a id="trunkLayoutTestsjsparsersyntaxcheckexpectedtxt"></a>
<div class="modfile"><h4>Modified: trunk/LayoutTests/js/parser-syntax-check-expected.txt (166391 => 166392)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/js/parser-syntax-check-expected.txt        2014-03-28 01:00:35 UTC (rev 166391)
+++ trunk/LayoutTests/js/parser-syntax-check-expected.txt        2014-03-28 01:10:25 UTC (rev 166392)
</span><span class="lines">@@ -668,12 +668,12 @@
</span><span class="cx"> PASS Valid:   &quot;function f() { o.foo(...bar) }&quot;
</span><span class="cx"> PASS Valid:   &quot;o[foo](...bar)&quot;
</span><span class="cx"> PASS Valid:   &quot;function f() { o[foo](...bar) }&quot;
</span><del>-PASS Invalid: &quot;new foo(...bar)&quot;
-PASS Invalid: &quot;function f() { new foo(...bar) }&quot;
-PASS Invalid: &quot;new o.foo(...bar)&quot;
-PASS Invalid: &quot;function f() { new o.foo(...bar) }&quot;
-PASS Invalid: &quot;new o[foo](...bar)&quot;
-PASS Invalid: &quot;function f() { new o[foo](...bar) }&quot;
</del><ins>+PASS Valid:   &quot;new foo(...bar)&quot;
+PASS Valid:   &quot;function f() { new foo(...bar) }&quot;
+PASS Valid:   &quot;new o.foo(...bar)&quot;
+PASS Valid:   &quot;function f() { new o.foo(...bar) }&quot;
+PASS Valid:   &quot;new o[foo](...bar)&quot;
+PASS Valid:   &quot;function f() { new o[foo](...bar) }&quot;
</ins><span class="cx"> PASS Invalid: &quot;foo(...)&quot;
</span><span class="cx"> PASS Invalid: &quot;function f() { foo(...) }&quot;
</span><span class="cx"> PASS Invalid: &quot;o.foo(...)&quot;
</span></span></pre></div>
<a id="trunkLayoutTestsjsregresscallspreadexpectedtxt"></a>
<div class="addfile"><h4>Added: trunk/LayoutTests/js/regress/call-spread-expected.txt (0 => 166392)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/js/regress/call-spread-expected.txt                                (rev 0)
+++ trunk/LayoutTests/js/regress/call-spread-expected.txt        2014-03-28 01:10:25 UTC (rev 166392)
</span><span class="lines">@@ -0,0 +1,10 @@
</span><ins>+JSRegress/call-spread
+
+On success, you will see a series of &quot;PASS&quot; messages, followed by &quot;TEST COMPLETE&quot;.
+
+
+PASS no exception thrown
+PASS successfullyParsed is true
+
+TEST COMPLETE
+
</ins></span></pre></div>
<a id="trunkLayoutTestsjsregresscallspreadhtml"></a>
<div class="addfile"><h4>Added: trunk/LayoutTests/js/regress/call-spread.html (0 => 166392)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/js/regress/call-spread.html                                (rev 0)
+++ trunk/LayoutTests/js/regress/call-spread.html        2014-03-28 01:10:25 UTC (rev 166392)
</span><span class="lines">@@ -0,0 +1,12 @@
</span><ins>+&lt;!DOCTYPE HTML PUBLIC &quot;-//IETF//DTD HTML//EN&quot;&gt;
+&lt;html&gt;
+&lt;head&gt;
+&lt;script src=&quot;../../resources/js-test-pre.js&quot;&gt;&lt;/script&gt;
+&lt;/head&gt;
+&lt;body&gt;
+&lt;script src=&quot;resources/regress-pre.js&quot;&gt;&lt;/script&gt;
+&lt;script src=&quot;script-tests/call-spread.js&quot;&gt;&lt;/script&gt;
+&lt;script src=&quot;resources/regress-post.js&quot;&gt;&lt;/script&gt;
+&lt;script src=&quot;../../resources/js-test-post.js&quot;&gt;&lt;/script&gt;
+&lt;/body&gt;
+&lt;/html&gt;
</ins></span></pre></div>
<a id="trunkLayoutTestsjsregressnewspreadexpectedtxt"></a>
<div class="addfile"><h4>Added: trunk/LayoutTests/js/regress/new-spread-expected.txt (0 => 166392)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/js/regress/new-spread-expected.txt                                (rev 0)
+++ trunk/LayoutTests/js/regress/new-spread-expected.txt        2014-03-28 01:10:25 UTC (rev 166392)
</span><span class="lines">@@ -0,0 +1,10 @@
</span><ins>+JSRegress/new-spread
+
+On success, you will see a series of &quot;PASS&quot; messages, followed by &quot;TEST COMPLETE&quot;.
+
+
+PASS no exception thrown
+PASS successfullyParsed is true
+
+TEST COMPLETE
+
</ins></span></pre></div>
<a id="trunkLayoutTestsjsregressnewspreadhtml"></a>
<div class="addfile"><h4>Added: trunk/LayoutTests/js/regress/new-spread.html (0 => 166392)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/js/regress/new-spread.html                                (rev 0)
+++ trunk/LayoutTests/js/regress/new-spread.html        2014-03-28 01:10:25 UTC (rev 166392)
</span><span class="lines">@@ -0,0 +1,12 @@
</span><ins>+&lt;!DOCTYPE HTML PUBLIC &quot;-//IETF//DTD HTML//EN&quot;&gt;
+&lt;html&gt;
+&lt;head&gt;
+&lt;script src=&quot;../../resources/js-test-pre.js&quot;&gt;&lt;/script&gt;
+&lt;/head&gt;
+&lt;body&gt;
+&lt;script src=&quot;resources/regress-pre.js&quot;&gt;&lt;/script&gt;
+&lt;script src=&quot;script-tests/new-spread.js&quot;&gt;&lt;/script&gt;
+&lt;script src=&quot;resources/regress-post.js&quot;&gt;&lt;/script&gt;
+&lt;script src=&quot;../../resources/js-test-post.js&quot;&gt;&lt;/script&gt;
+&lt;/body&gt;
+&lt;/html&gt;
</ins></span></pre></div>
<a id="trunkLayoutTestsjsregressscripttestscallspreadjs"></a>
<div class="addfile"><h4>Added: trunk/LayoutTests/js/regress/script-tests/call-spread.js (0 => 166392)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/js/regress/script-tests/call-spread.js                                (rev 0)
+++ trunk/LayoutTests/js/regress/script-tests/call-spread.js        2014-03-28 01:10:25 UTC (rev 166392)
</span><span class="lines">@@ -0,0 +1,34 @@
</span><ins>+
+function testFunction(a, b)
+{
+    &quot;use strict&quot;
+    result |= 0;
+    return a * 1000 + b * 100 + arguments[2] * 10 + arguments.length ^ (result &amp; 1024);
+}
+
+var arrayArguments = [2, 3, 4]
+var result = 0;
+for (var i = 0; i &lt; 1000000; i++)
+    result += testFunction(...arrayArguments);
+
+for (var i = 0; i &lt; 1000000; i++)
+    result += testFunction(...[1, 2, result, 4]);
+
+function test2() {
+    for (var i = 0; i &lt; 1000000; i++)
+        result += testFunction(...arguments);
+}
+
+test2(1,2,3,4)
+
+
+function test3() {
+    aliasedArguments = arguments;
+    for (var i = 0; i &lt; 1000000; i++)
+        result += testFunction(...aliasedArguments);
+}
+
+test3(1,2,result,4)
+
+if (result != -856444619779264)
+    throw &quot;Result was &quot; + result + &quot; expected -856444619779264&quot;;
</ins><span class="cx">\ No newline at end of file
</span></span></pre></div>
<a id="trunkLayoutTestsjsregressscripttestsnewspreadjs"></a>
<div class="addfile"><h4>Added: trunk/LayoutTests/js/regress/script-tests/new-spread.js (0 => 166392)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/js/regress/script-tests/new-spread.js                                (rev 0)
+++ trunk/LayoutTests/js/regress/script-tests/new-spread.js        2014-03-28 01:10:25 UTC (rev 166392)
</span><span class="lines">@@ -0,0 +1,34 @@
</span><ins>+
+function testFunction(a, b)
+{
+    &quot;use strict&quot;
+    result |= 0;
+    result += a * 1000 + b * 100 + arguments[2] * 10 + arguments.length ^ (result &amp; 1024);
+}
+
+var arrayArguments = [2, 3, 4]
+var result = 0;
+for (var i = 0; i &lt; 1000000; i++)
+    new testFunction(...arrayArguments);
+
+for (var i = 0; i &lt; 1000000; i++)
+    new testFunction(...[1, 2, result, 4]);
+
+function test2() {
+    for (var i = 0; i &lt; 1000000; i++)
+        new testFunction(...arguments);
+}
+
+test2(1,2,3,4)
+
+
+function test3() {
+    aliasedArguments = arguments;
+    for (var i = 0; i &lt; 1000000; i++)
+        new testFunction(...aliasedArguments);
+}
+
+test3(1,2,result,4)
+
+if (result != -2371153088)
+    throw &quot;Result was &quot; + result + &quot; expected -2371153088&quot;;
</ins><span class="cx">\ No newline at end of file
</span></span></pre></div>
<a id="trunkLayoutTestsjsscripttestsparsersyntaxcheckjs"></a>
<div class="modfile"><h4>Modified: trunk/LayoutTests/js/script-tests/parser-syntax-check.js (166391 => 166392)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/js/script-tests/parser-syntax-check.js        2014-03-28 01:00:35 UTC (rev 166391)
+++ trunk/LayoutTests/js/script-tests/parser-syntax-check.js        2014-03-28 01:10:25 UTC (rev 166392)
</span><span class="lines">@@ -418,9 +418,9 @@
</span><span class="cx"> valid(&quot;foo(...bar)&quot;)
</span><span class="cx"> valid(&quot;o.foo(...bar)&quot;)
</span><span class="cx"> valid(&quot;o[foo](...bar)&quot;)
</span><del>-invalid(&quot;new foo(...bar)&quot;)
-invalid(&quot;new o.foo(...bar)&quot;)
-invalid(&quot;new o[foo](...bar)&quot;)
</del><ins>+valid(&quot;new foo(...bar)&quot;)
+valid(&quot;new o.foo(...bar)&quot;)
+valid(&quot;new o[foo](...bar)&quot;)
</ins><span class="cx"> invalid(&quot;foo(...)&quot;)
</span><span class="cx"> invalid(&quot;o.foo(...)&quot;)
</span><span class="cx"> invalid(&quot;o[foo](...)&quot;)
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/ChangeLog (166391 => 166392)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/ChangeLog        2014-03-28 01:00:35 UTC (rev 166391)
+++ trunk/Source/JavaScriptCore/ChangeLog        2014-03-28 01:10:25 UTC (rev 166392)
</span><span class="lines">@@ -1,3 +1,54 @@
</span><ins>+2014-03-27  Oliver Hunt  &lt;oliver@apple.com&gt;
+
+        Support spread operand in |new| expressions
+        https://bugs.webkit.org/show_bug.cgi?id=130877
+
+        Reviewed by Michael Saboff.
+
+        Add support for the spread operator being applied in
+        |new| expressions.  This required adding support for
+        a new opcode, op_construct_varargs.  This is a relatively
+        simple refactoring of the call_varargs implementation.
+
+        * bytecode/BytecodeList.json:
+        * bytecode/BytecodeUseDef.h:
+        (JSC::computeUsesForBytecodeOffset):
+        (JSC::computeDefsForBytecodeOffset):
+        * bytecode/CallLinkInfo.cpp:
+        (JSC::CallLinkInfo::unlink):
+        * bytecode/CallLinkInfo.h:
+        (JSC::CallLinkInfo::callTypeFor):
+        (JSC::CallLinkInfo::specializationKind):
+        * bytecode/CodeBlock.cpp:
+        (JSC::CodeBlock::dumpBytecode):
+        (JSC::CodeBlock::CodeBlock):
+        * bytecompiler/BytecodeGenerator.cpp:
+        (JSC::BytecodeGenerator::emitCallVarargs):
+        (JSC::BytecodeGenerator::emitConstructVarargs):
+        (JSC::BytecodeGenerator::emitConstruct):
+        * bytecompiler/BytecodeGenerator.h:
+        * jit/JIT.cpp:
+        (JSC::JIT::privateCompileMainPass):
+        (JSC::JIT::privateCompileSlowCases):
+        * jit/JIT.h:
+        * jit/JITCall.cpp:
+        (JSC::JIT::compileOpCall):
+        (JSC::JIT::compileOpCallSlowCase):
+        (JSC::JIT::emit_op_construct_varargs):
+        (JSC::JIT::emitSlow_op_construct_varargs):
+        * jit/JITCall32_64.cpp:
+        (JSC::JIT::emitSlow_op_construct_varargs):
+        (JSC::JIT::emit_op_construct_varargs):
+        (JSC::JIT::compileOpCall):
+        (JSC::JIT::compileOpCallSlowCase):
+        * jit/JITOperations.cpp:
+        * llint/LLIntSlowPaths.cpp:
+        (JSC::LLInt::LLINT_SLOW_PATH_DECL):
+        * llint/LLIntSlowPaths.h:
+        * llint/LowLevelInterpreter.asm:
+        * parser/Parser.cpp:
+        (JSC::Parser&lt;LexerType&gt;::parseMemberExpression):
+
</ins><span class="cx"> 2014-03-27  Filip Pizlo  &lt;fpizlo@apple.com&gt;
</span><span class="cx"> 
</span><span class="cx">         Revert http://trac.webkit.org/changeset/166386 because it broke builds.
</span></span></pre></div>
<a id="trunkSourceJavaScriptCorebytecodeBytecodeListjson"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/bytecode/BytecodeList.json (166391 => 166392)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/bytecode/BytecodeList.json        2014-03-28 01:00:35 UTC (rev 166391)
+++ trunk/Source/JavaScriptCore/bytecode/BytecodeList.json        2014-03-28 01:10:25 UTC (rev 166392)
</span><span class="lines">@@ -104,6 +104,7 @@
</span><span class="cx">             { &quot;name&quot; : &quot;op_ret&quot;, &quot;length&quot; : 2 },
</span><span class="cx">             { &quot;name&quot; : &quot;op_ret_object_or_this&quot;, &quot;length&quot; : 3 },
</span><span class="cx">             { &quot;name&quot; : &quot;op_construct&quot;, &quot;length&quot; : 9 },
</span><ins>+            { &quot;name&quot; : &quot;op_construct_varargs&quot;, &quot;length&quot; : 9 },
</ins><span class="cx">             { &quot;name&quot; : &quot;op_strcat&quot;, &quot;length&quot; : 4 },
</span><span class="cx">             { &quot;name&quot; : &quot;op_to_primitive&quot;, &quot;length&quot; : 3 },
</span><span class="cx">             { &quot;name&quot; : &quot;op_get_pnames&quot;, &quot;length&quot; : 6 },
</span></span></pre></div>
<a id="trunkSourceJavaScriptCorebytecodeBytecodeUseDefh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/bytecode/BytecodeUseDef.h (166391 => 166392)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/bytecode/BytecodeUseDef.h        2014-03-28 01:00:35 UTC (rev 166391)
+++ trunk/Source/JavaScriptCore/bytecode/BytecodeUseDef.h        2014-03-28 01:10:25 UTC (rev 166392)
</span><span class="lines">@@ -176,6 +176,7 @@
</span><span class="cx">         functor(codeBlock, instruction, opcodeID, instruction[3].u.operand);
</span><span class="cx">         return;
</span><span class="cx">     }
</span><ins>+    case op_construct_varargs:
</ins><span class="cx">     case op_call_varargs: {
</span><span class="cx">         functor(codeBlock, instruction, opcodeID, instruction[2].u.operand);
</span><span class="cx">         functor(codeBlock, instruction, opcodeID, instruction[3].u.operand);
</span><span class="lines">@@ -307,6 +308,7 @@
</span><span class="cx">     case op_new_captured_func:
</span><span class="cx">     case op_new_func_exp:
</span><span class="cx">     case op_call_varargs:
</span><ins>+    case op_construct_varargs:
</ins><span class="cx">     case op_get_from_scope:
</span><span class="cx">     case op_call:
</span><span class="cx">     case op_call_eval:
</span></span></pre></div>
<a id="trunkSourceJavaScriptCorebytecodeCallLinkInfocpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/bytecode/CallLinkInfo.cpp (166391 => 166392)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/bytecode/CallLinkInfo.cpp        2014-03-28 01:00:35 UTC (rev 166391)
+++ trunk/Source/JavaScriptCore/bytecode/CallLinkInfo.cpp        2014-03-28 01:10:25 UTC (rev 166392)
</span><span class="lines">@@ -46,7 +46,7 @@
</span><span class="cx">     repatchBuffer.relink(
</span><span class="cx">         callReturnLocation,
</span><span class="cx">         repatchBuffer.codeBlock()-&gt;vm()-&gt;getCTIStub(linkThunkGeneratorFor(
</span><del>-            callType == Construct ? CodeForConstruct : CodeForCall,
</del><ins>+            (callType == Construct || callType == ConstructVarargs)? CodeForConstruct : CodeForCall,
</ins><span class="cx">             isFTL ? MustPreserveRegisters : RegisterPreservationNotRequired)).code());
</span><span class="cx">     hasSeenShouldRepatch = false;
</span><span class="cx">     callee.clear();
</span></span></pre></div>
<a id="trunkSourceJavaScriptCorebytecodeCallLinkInfoh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/bytecode/CallLinkInfo.h (166391 => 166392)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/bytecode/CallLinkInfo.h        2014-03-28 01:00:35 UTC (rev 166391)
+++ trunk/Source/JavaScriptCore/bytecode/CallLinkInfo.h        2014-03-28 01:10:25 UTC (rev 166392)
</span><span class="lines">@@ -42,13 +42,15 @@
</span><span class="cx"> class RepatchBuffer;
</span><span class="cx"> 
</span><span class="cx"> struct CallLinkInfo : public BasicRawSentinelNode&lt;CallLinkInfo&gt; {
</span><del>-    enum CallType { None, Call, CallVarargs, Construct };
</del><ins>+    enum CallType { None, Call, CallVarargs, Construct, ConstructVarargs };
</ins><span class="cx">     static CallType callTypeFor(OpcodeID opcodeID)
</span><span class="cx">     {
</span><span class="cx">         if (opcodeID == op_call || opcodeID == op_call_eval)
</span><span class="cx">             return Call;
</span><span class="cx">         if (opcodeID == op_construct)
</span><span class="cx">             return Construct;
</span><ins>+        if (opcodeID == op_construct_varargs)
+            return ConstructVarargs;
</ins><span class="cx">         ASSERT(opcodeID == op_call_varargs);
</span><span class="cx">         return CallVarargs;
</span><span class="cx">     }
</span><span class="lines">@@ -70,7 +72,7 @@
</span><span class="cx">     
</span><span class="cx">     CodeSpecializationKind specializationKind() const
</span><span class="cx">     {
</span><del>-        return specializationFromIsConstruct(callType == Construct);
</del><ins>+        return specializationFromIsConstruct(callType == Construct || callType == ConstructVarargs);
</ins><span class="cx">     }
</span><span class="cx"> 
</span><span class="cx">     CodeLocationNearCall callReturnLocation;
</span></span></pre></div>
<a id="trunkSourceJavaScriptCorebytecodeCodeBlockcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/bytecode/CodeBlock.cpp (166391 => 166392)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/bytecode/CodeBlock.cpp        2014-03-28 01:00:35 UTC (rev 166391)
+++ trunk/Source/JavaScriptCore/bytecode/CodeBlock.cpp        2014-03-28 01:10:25 UTC (rev 166392)
</span><span class="lines">@@ -627,7 +627,8 @@
</span><span class="cx"> {
</span><span class="cx">     int location = it - begin;
</span><span class="cx">     bool hasPrintedProfiling = false;
</span><del>-    switch (exec-&gt;interpreter()-&gt;getOpcodeID(it-&gt;u.opcode)) {
</del><ins>+    OpcodeID opcode = exec-&gt;interpreter()-&gt;getOpcodeID(it-&gt;u.opcode);
+    switch (opcode) {
</ins><span class="cx">         case op_enter: {
</span><span class="cx">             printLocationAndOp(out, exec, location, it, &quot;enter&quot;);
</span><span class="cx">             break;
</span><span class="lines">@@ -1188,6 +1189,8 @@
</span><span class="cx">             printCallOp(out, exec, location, it, &quot;call_eval&quot;, DontDumpCaches, hasPrintedProfiling, callLinkInfos);
</span><span class="cx">             break;
</span><span class="cx">         }
</span><ins>+            
+        case op_construct_varargs:
</ins><span class="cx">         case op_call_varargs: {
</span><span class="cx">             int result = (++it)-&gt;u.operand;
</span><span class="cx">             int callee = (++it)-&gt;u.operand;
</span><span class="lines">@@ -1196,11 +1199,12 @@
</span><span class="cx">             int firstFreeRegister = (++it)-&gt;u.operand;
</span><span class="cx">             int varArgOffset = (++it)-&gt;u.operand;
</span><span class="cx">             ++it;
</span><del>-            printLocationAndOp(out, exec, location, it, &quot;call_varargs&quot;);
</del><ins>+            printLocationAndOp(out, exec, location, it, opcode == op_call_varargs ? &quot;call_varargs&quot; : &quot;construct_varargs&quot;);
</ins><span class="cx">             out.printf(&quot;%s, %s, %s, %s, %d, %d&quot;, registerName(result).data(), registerName(callee).data(), registerName(thisValue).data(), registerName(arguments).data(), firstFreeRegister, varArgOffset);
</span><span class="cx">             dumpValueProfiling(out, it, hasPrintedProfiling);
</span><span class="cx">             break;
</span><span class="cx">         }
</span><ins>+            
</ins><span class="cx">         case op_tear_off_activation: {
</span><span class="cx">             int r0 = (++it)-&gt;u.operand;
</span><span class="cx">             printLocationOpAndRegisterOperand(out, exec, location, it, &quot;tear_off_activation&quot;, r0);
</span><span class="lines">@@ -1640,6 +1644,7 @@
</span><span class="cx">         }
</span><span class="cx">         switch (pc[0].u.opcode) {
</span><span class="cx">         case op_call_varargs:
</span><ins>+        case op_construct_varargs:
</ins><span class="cx">         case op_get_by_val:
</span><span class="cx">         case op_get_argument_by_val: {
</span><span class="cx">             int arrayProfileIndex = pc[opLength - 2].u.operand;
</span></span></pre></div>
<a id="trunkSourceJavaScriptCorebytecompilerBytecodeGeneratorcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/bytecompiler/BytecodeGenerator.cpp (166391 => 166392)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/bytecompiler/BytecodeGenerator.cpp        2014-03-28 01:00:35 UTC (rev 166391)
+++ trunk/Source/JavaScriptCore/bytecompiler/BytecodeGenerator.cpp        2014-03-28 01:10:25 UTC (rev 166392)
</span><span class="lines">@@ -1788,6 +1788,16 @@
</span><span class="cx"> 
</span><span class="cx"> RegisterID* BytecodeGenerator::emitCallVarargs(RegisterID* dst, RegisterID* func, RegisterID* thisRegister, RegisterID* arguments, RegisterID* firstFreeRegister, int32_t firstVarArgOffset, RegisterID* profileHookRegister, const JSTextPosition&amp; divot, const JSTextPosition&amp; divotStart, const JSTextPosition&amp; divotEnd)
</span><span class="cx"> {
</span><ins>+    return emitCallVarargs(op_call_varargs, dst, func, thisRegister, arguments, firstFreeRegister, firstVarArgOffset, profileHookRegister, divot, divotStart, divotEnd);
+}
+
+RegisterID* BytecodeGenerator::emitConstructVarargs(RegisterID* dst, RegisterID* func, RegisterID* arguments, RegisterID* firstFreeRegister, int32_t firstVarArgOffset, RegisterID* profileHookRegister, const JSTextPosition&amp; divot, const JSTextPosition&amp; divotStart, const JSTextPosition&amp; divotEnd)
+{
+    return emitCallVarargs(op_construct_varargs, dst, func, 0, arguments, firstFreeRegister, firstVarArgOffset, profileHookRegister, divot, divotStart, divotEnd);
+}
+    
+RegisterID* BytecodeGenerator::emitCallVarargs(OpcodeID opcode, RegisterID* dst, RegisterID* func, RegisterID* thisRegister, RegisterID* arguments, RegisterID* firstFreeRegister, int32_t firstVarArgOffset, RegisterID* profileHookRegister, const JSTextPosition&amp; divot, const JSTextPosition&amp; divotStart, const JSTextPosition&amp; divotEnd)
+{
</ins><span class="cx">     if (m_shouldEmitProfileHooks) {
</span><span class="cx">         emitMove(profileHookRegister, func);
</span><span class="cx">         emitOpcode(op_profile_will_call);
</span><span class="lines">@@ -1798,11 +1808,11 @@
</span><span class="cx"> 
</span><span class="cx">     // Emit call.
</span><span class="cx">     UnlinkedArrayProfile arrayProfile = newArrayProfile();
</span><del>-    UnlinkedValueProfile profile = emitProfiledOpcode(op_call_varargs);
</del><ins>+    UnlinkedValueProfile profile = emitProfiledOpcode(opcode);
</ins><span class="cx">     ASSERT(dst != ignoredResult());
</span><span class="cx">     instructions().append(dst-&gt;index());
</span><span class="cx">     instructions().append(func-&gt;index());
</span><del>-    instructions().append(thisRegister-&gt;index());
</del><ins>+    instructions().append(thisRegister ? thisRegister-&gt;index() : 0);
</ins><span class="cx">     instructions().append(arguments-&gt;index());
</span><span class="cx">     instructions().append(firstFreeRegister-&gt;index());
</span><span class="cx">     instructions().append(firstVarArgOffset);
</span><span class="lines">@@ -1857,6 +1867,19 @@
</span><span class="cx">     // Generate code for arguments.
</span><span class="cx">     unsigned argument = 0;
</span><span class="cx">     if (ArgumentsNode* argumentsNode = callArguments.argumentsNode()) {
</span><ins>+        
+        ArgumentListNode* n = callArguments.argumentsNode()-&gt;m_listNode;
+        if (n &amp;&amp; n-&gt;m_expr-&gt;isSpreadExpression()) {
+            RELEASE_ASSERT(!n-&gt;m_next);
+            auto expression = static_cast&lt;SpreadExpressionNode*&gt;(n-&gt;m_expr)-&gt;expression();
+            RefPtr&lt;RegisterID&gt; argumentRegister;
+            if (expression-&gt;isResolveNode() &amp;&amp; willResolveToArguments(static_cast&lt;ResolveNode*&gt;(expression)-&gt;identifier()) &amp;&amp; !symbolTable().slowArguments())
+                argumentRegister = uncheckedRegisterForArguments();
+            else
+                argumentRegister = expression-&gt;emitBytecode(*this, callArguments.argumentRegister(0));
+            return emitConstructVarargs(dst, func, argumentRegister.get(), newTemporary(), 0, callArguments.profileHookRegister(), divot, divotStart, divotEnd);
+        }
+        
</ins><span class="cx">         for (ArgumentListNode* n = argumentsNode-&gt;m_listNode; n; n = n-&gt;m_next)
</span><span class="cx">             emitNode(callArguments.argumentRegister(argument++), n);
</span><span class="cx">     }
</span></span></pre></div>
<a id="trunkSourceJavaScriptCorebytecompilerBytecodeGeneratorh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/bytecompiler/BytecodeGenerator.h (166391 => 166392)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/bytecompiler/BytecodeGenerator.h        2014-03-28 01:00:35 UTC (rev 166391)
+++ trunk/Source/JavaScriptCore/bytecompiler/BytecodeGenerator.h        2014-03-28 01:10:25 UTC (rev 166392)
</span><span class="lines">@@ -551,7 +551,10 @@
</span><span class="cx">         }
</span><span class="cx"> 
</span><span class="cx">         RegisterID* emitInitLazyRegister(RegisterID*);
</span><del>-
</del><ins>+        
+        RegisterID* emitConstructVarargs(RegisterID* dst, RegisterID* func, RegisterID* arguments, RegisterID* firstFreeRegister, int32_t firstVarArgOffset, RegisterID* profileHookRegister, const JSTextPosition&amp; divot, const JSTextPosition&amp; divotStart, const JSTextPosition&amp; divotEnd);
+        RegisterID* emitCallVarargs(OpcodeID, RegisterID* dst, RegisterID* func, RegisterID* thisRegister, RegisterID* arguments, RegisterID* firstFreeRegister, int32_t firstVarArgOffset, RegisterID* profileHookRegister, const JSTextPosition&amp; divot, const JSTextPosition&amp; divotStart, const JSTextPosition&amp; divotEnd);
+        
</ins><span class="cx">     public:
</span><span class="cx">         JSString* addStringConstant(const Identifier&amp;);
</span><span class="cx"> 
</span></span></pre></div>
<a id="trunkSourceJavaScriptCorejitJITcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/jit/JIT.cpp (166391 => 166392)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/jit/JIT.cpp        2014-03-28 01:00:35 UTC (rev 166391)
+++ trunk/Source/JavaScriptCore/jit/JIT.cpp        2014-03-28 01:10:25 UTC (rev 166392)
</span><span class="lines">@@ -186,6 +186,7 @@
</span><span class="cx">         DEFINE_OP(op_call)
</span><span class="cx">         DEFINE_OP(op_call_eval)
</span><span class="cx">         DEFINE_OP(op_call_varargs)
</span><ins>+        DEFINE_OP(op_construct_varargs)
</ins><span class="cx">         DEFINE_OP(op_catch)
</span><span class="cx">         DEFINE_OP(op_construct)
</span><span class="cx">         DEFINE_OP(op_get_callee)
</span><span class="lines">@@ -353,6 +354,7 @@
</span><span class="cx">         DEFINE_SLOWCASE_OP(op_call)
</span><span class="cx">         DEFINE_SLOWCASE_OP(op_call_eval)
</span><span class="cx">         DEFINE_SLOWCASE_OP(op_call_varargs)
</span><ins>+        DEFINE_SLOWCASE_OP(op_construct_varargs)
</ins><span class="cx">         DEFINE_SLOWCASE_OP(op_construct)
</span><span class="cx">         DEFINE_SLOWCASE_OP(op_to_this)
</span><span class="cx">         DEFINE_SLOWCASE_OP(op_create_this)
</span></span></pre></div>
<a id="trunkSourceJavaScriptCorejitJITh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/jit/JIT.h (166391 => 166392)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/jit/JIT.h        2014-03-28 01:00:35 UTC (rev 166391)
+++ trunk/Source/JavaScriptCore/jit/JIT.h        2014-03-28 01:10:25 UTC (rev 166392)
</span><span class="lines">@@ -455,6 +455,7 @@
</span><span class="cx">         void emit_op_call(Instruction*);
</span><span class="cx">         void emit_op_call_eval(Instruction*);
</span><span class="cx">         void emit_op_call_varargs(Instruction*);
</span><ins>+        void emit_op_construct_varargs(Instruction*);
</ins><span class="cx">         void emit_op_captured_mov(Instruction*);
</span><span class="cx">         void emit_op_catch(Instruction*);
</span><span class="cx">         void emit_op_construct(Instruction*);
</span><span class="lines">@@ -554,6 +555,7 @@
</span><span class="cx">         void emitSlow_op_call(Instruction*, Vector&lt;SlowCaseEntry&gt;::iterator&amp;);
</span><span class="cx">         void emitSlow_op_call_eval(Instruction*, Vector&lt;SlowCaseEntry&gt;::iterator&amp;);
</span><span class="cx">         void emitSlow_op_call_varargs(Instruction*, Vector&lt;SlowCaseEntry&gt;::iterator&amp;);
</span><ins>+        void emitSlow_op_construct_varargs(Instruction*, Vector&lt;SlowCaseEntry&gt;::iterator&amp;);
</ins><span class="cx">         void emitSlow_op_captured_mov(Instruction*, Vector&lt;SlowCaseEntry&gt;::iterator&amp;);
</span><span class="cx">         void emitSlow_op_construct(Instruction*, Vector&lt;SlowCaseEntry&gt;::iterator&amp;);
</span><span class="cx">         void emitSlow_op_to_this(Instruction*, Vector&lt;SlowCaseEntry&gt;::iterator&amp;);
</span></span></pre></div>
<a id="trunkSourceJavaScriptCorejitJITCallcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/jit/JITCall.cpp (166391 => 166392)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/jit/JITCall.cpp        2014-03-28 01:00:35 UTC (rev 166391)
+++ trunk/Source/JavaScriptCore/jit/JITCall.cpp        2014-03-28 01:10:25 UTC (rev 166392)
</span><span class="lines">@@ -186,7 +186,8 @@
</span><span class="cx">     */
</span><span class="cx">     COMPILE_ASSERT(OPCODE_LENGTH(op_call) == OPCODE_LENGTH(op_construct), call_and_construct_opcodes_must_be_same_length);
</span><span class="cx">     COMPILE_ASSERT(OPCODE_LENGTH(op_call) == OPCODE_LENGTH(op_call_varargs), call_and_call_varargs_opcodes_must_be_same_length);
</span><del>-    if (opcodeID == op_call_varargs)
</del><ins>+    COMPILE_ASSERT(OPCODE_LENGTH(op_call) == OPCODE_LENGTH(op_construct_varargs), call_and_construct_varargs_opcodes_must_be_same_length);
+    if (opcodeID == op_call_varargs || opcodeID == op_construct_varargs)
</ins><span class="cx">         compileLoadVarargs(instruction);
</span><span class="cx">     else {
</span><span class="cx">         int argCount = instruction[3].u.operand;
</span><span class="lines">@@ -252,7 +253,7 @@
</span><span class="cx">     linkSlowCase(iter);
</span><span class="cx"> 
</span><span class="cx">     ThunkGenerator generator = linkThunkGeneratorFor(
</span><del>-        opcodeID == op_construct ? CodeForConstruct : CodeForCall,
</del><ins>+        (opcodeID == op_construct || opcodeID == op_construct_varargs) ? CodeForConstruct : CodeForCall,
</ins><span class="cx">         RegisterPreservationNotRequired);
</span><span class="cx">     
</span><span class="cx">     move(TrustedImmPtr(m_callCompilationInfo[callLinkInfoIndex].callLinkInfo), regT2);
</span><span class="lines">@@ -326,6 +327,11 @@
</span><span class="cx"> {
</span><span class="cx">     compileOpCall(op_call_varargs, currentInstruction, m_callLinkInfoIndex++);
</span><span class="cx"> }
</span><ins>+    
+void JIT::emit_op_construct_varargs(Instruction* currentInstruction)
+{
+    compileOpCall(op_construct_varargs, currentInstruction, m_callLinkInfoIndex++);
+}
</ins><span class="cx"> 
</span><span class="cx"> void JIT::emit_op_construct(Instruction* currentInstruction)
</span><span class="cx"> {
</span><span class="lines">@@ -346,7 +352,12 @@
</span><span class="cx"> {
</span><span class="cx">     compileOpCallSlowCase(op_call_varargs, currentInstruction, iter, m_callLinkInfoIndex++);
</span><span class="cx"> }
</span><del>-
</del><ins>+    
+void JIT::emitSlow_op_construct_varargs(Instruction* currentInstruction, Vector&lt;SlowCaseEntry&gt;::iterator&amp; iter)
+{
+    compileOpCallSlowCase(op_construct_varargs, currentInstruction, iter, m_callLinkInfoIndex++);
+}
+    
</ins><span class="cx"> void JIT::emitSlow_op_construct(Instruction* currentInstruction, Vector&lt;SlowCaseEntry&gt;::iterator&amp; iter)
</span><span class="cx"> {
</span><span class="cx">     compileOpCallSlowCase(op_construct, currentInstruction, iter, m_callLinkInfoIndex++);
</span></span></pre></div>
<a id="trunkSourceJavaScriptCorejitJITCall32_64cpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/jit/JITCall32_64.cpp (166391 => 166392)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/jit/JITCall32_64.cpp        2014-03-28 01:00:35 UTC (rev 166391)
+++ trunk/Source/JavaScriptCore/jit/JITCall32_64.cpp        2014-03-28 01:10:25 UTC (rev 166392)
</span><span class="lines">@@ -99,7 +99,12 @@
</span><span class="cx"> {
</span><span class="cx">     compileOpCallSlowCase(op_call_varargs, currentInstruction, iter, m_callLinkInfoIndex++);
</span><span class="cx"> }
</span><del>-
</del><ins>+    
+void JIT::emitSlow_op_construct_varargs(Instruction* currentInstruction, Vector&lt;SlowCaseEntry&gt;::iterator&amp; iter)
+{
+    compileOpCallSlowCase(op_construct_varargs, currentInstruction, iter, m_callLinkInfoIndex++);
+}
+    
</ins><span class="cx"> void JIT::emitSlow_op_construct(Instruction* currentInstruction, Vector&lt;SlowCaseEntry&gt;::iterator&amp; iter)
</span><span class="cx"> {
</span><span class="cx">     compileOpCallSlowCase(op_construct, currentInstruction, iter, m_callLinkInfoIndex++);
</span><span class="lines">@@ -119,7 +124,12 @@
</span><span class="cx"> {
</span><span class="cx">     compileOpCall(op_call_varargs, currentInstruction, m_callLinkInfoIndex++);
</span><span class="cx"> }
</span><del>-
</del><ins>+    
+void JIT::emit_op_construct_varargs(Instruction* currentInstruction)
+{
+    compileOpCall(op_construct_varargs, currentInstruction, m_callLinkInfoIndex++);
+}
+    
</ins><span class="cx"> void JIT::emit_op_construct(Instruction* currentInstruction)
</span><span class="cx"> {
</span><span class="cx">     compileOpCall(op_construct, currentInstruction, m_callLinkInfoIndex++);
</span><span class="lines">@@ -263,7 +273,7 @@
</span><span class="cx">         - Caller restores callFrameRegister after return.
</span><span class="cx">     */
</span><span class="cx">     
</span><del>-    if (opcodeID == op_call_varargs)
</del><ins>+    if (opcodeID == op_call_varargs || opcodeID == op_construct_varargs)
</ins><span class="cx">         compileLoadVarargs(instruction);
</span><span class="cx">     else {
</span><span class="cx">         int argCount = instruction[3].u.operand;
</span><span class="lines">@@ -334,7 +344,7 @@
</span><span class="cx">     linkSlowCase(iter);
</span><span class="cx"> 
</span><span class="cx">     ThunkGenerator generator = linkThunkGeneratorFor(
</span><del>-        opcodeID == op_construct ? CodeForConstruct : CodeForCall,
</del><ins>+        (opcodeID == op_construct || opcodeID == op_construct_varargs) ? CodeForConstruct : CodeForCall,
</ins><span class="cx">         RegisterPreservationNotRequired);
</span><span class="cx">     
</span><span class="cx">     move(TrustedImmPtr(m_callCompilationInfo[callLinkInfoIndex].callLinkInfo), regT2);
</span></span></pre></div>
<a id="trunkSourceJavaScriptCorejitJITOperationscpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/jit/JITOperations.cpp (166391 => 166392)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/jit/JITOperations.cpp        2014-03-28 01:00:35 UTC (rev 166391)
+++ trunk/Source/JavaScriptCore/jit/JITOperations.cpp        2014-03-28 01:10:25 UTC (rev 166392)
</span><span class="lines">@@ -705,7 +705,7 @@
</span><span class="cx">         }
</span><span class="cx">         codeBlock = functionExecutable-&gt;codeBlockFor(kind);
</span><span class="cx">         ArityCheckMode arity;
</span><del>-        if (execCallee-&gt;argumentCountIncludingThis() &lt; static_cast&lt;size_t&gt;(codeBlock-&gt;numParameters()) || callLinkInfo-&gt;callType == CallLinkInfo::CallVarargs)
</del><ins>+        if (execCallee-&gt;argumentCountIncludingThis() &lt; static_cast&lt;size_t&gt;(codeBlock-&gt;numParameters()) || callLinkInfo-&gt;callType == CallLinkInfo::CallVarargs || callLinkInfo-&gt;callType == CallLinkInfo::ConstructVarargs)
</ins><span class="cx">             arity = MustCheckArity;
</span><span class="cx">         else
</span><span class="cx">             arity = ArityCheckNotRequired;
</span><span class="lines">@@ -802,7 +802,7 @@
</span><span class="cx">         codeBlock = 0;
</span><span class="cx">     else {
</span><span class="cx">         codeBlock = jsCast&lt;FunctionExecutable*&gt;(callee-&gt;executable())-&gt;codeBlockForCall();
</span><del>-        if (execCallee-&gt;argumentCountIncludingThis() &lt; static_cast&lt;size_t&gt;(codeBlock-&gt;numParameters()) || callLinkInfo.callType == CallLinkInfo::CallVarargs)
</del><ins>+        if (execCallee-&gt;argumentCountIncludingThis() &lt; static_cast&lt;size_t&gt;(codeBlock-&gt;numParameters()) || callLinkInfo.callType == CallLinkInfo::CallVarargs || callLinkInfo.callType == CallLinkInfo::ConstructVarargs)
</ins><span class="cx">             return false;
</span><span class="cx">     }
</span><span class="cx">     
</span></span></pre></div>
<a id="trunkSourceJavaScriptCorellintLLIntSlowPathscpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/llint/LLIntSlowPaths.cpp (166391 => 166392)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/llint/LLIntSlowPaths.cpp        2014-03-28 01:00:35 UTC (rev 166391)
+++ trunk/Source/JavaScriptCore/llint/LLIntSlowPaths.cpp        2014-03-28 01:10:25 UTC (rev 166392)
</span><span class="lines">@@ -1192,7 +1192,28 @@
</span><span class="cx">     
</span><span class="cx">     return setUpCall(execCallee, pc, CodeForCall, calleeAsValue);
</span><span class="cx"> }
</span><del>-
</del><ins>+    
+LLINT_SLOW_PATH_DECL(slow_path_construct_varargs)
+{
+    LLINT_BEGIN_NO_SET_PC();
+    // This needs to:
+    // - Figure out what to call and compile it if necessary.
+    // - Return a tuple of machine code address to call and the new call frame.
+    
+    JSValue calleeAsValue = LLINT_OP_C(2).jsValue();
+    
+    ExecState* execCallee = vm.newCallFrameReturnValue;
+    
+    loadVarargs(exec, execCallee, LLINT_OP_C(3).jsValue(), LLINT_OP_C(4).jsValue(), pc[6].u.operand);
+    LLINT_CALL_CHECK_EXCEPTION(exec);
+    
+    execCallee-&gt;uncheckedR(JSStack::Callee) = calleeAsValue;
+    execCallee-&gt;setCallerFrame(exec);
+    exec-&gt;setCurrentVPC(pc);
+    
+    return setUpCall(execCallee, pc, CodeForConstruct, calleeAsValue);
+}
+    
</ins><span class="cx"> LLINT_SLOW_PATH_DECL(slow_path_call_eval)
</span><span class="cx"> {
</span><span class="cx">     LLINT_BEGIN_NO_SET_PC();
</span></span></pre></div>
<a id="trunkSourceJavaScriptCorellintLLIntSlowPathsh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/llint/LLIntSlowPaths.h (166391 => 166392)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/llint/LLIntSlowPaths.h        2014-03-28 01:00:35 UTC (rev 166391)
+++ trunk/Source/JavaScriptCore/llint/LLIntSlowPaths.h        2014-03-28 01:10:25 UTC (rev 166392)
</span><span class="lines">@@ -103,6 +103,7 @@
</span><span class="cx"> LLINT_SLOW_PATH_HIDDEN_DECL(slow_path_construct);
</span><span class="cx"> LLINT_SLOW_PATH_HIDDEN_DECL(slow_path_size_frame_for_varargs);
</span><span class="cx"> LLINT_SLOW_PATH_HIDDEN_DECL(slow_path_call_varargs);
</span><ins>+LLINT_SLOW_PATH_HIDDEN_DECL(slow_path_construct_varargs);
</ins><span class="cx"> LLINT_SLOW_PATH_HIDDEN_DECL(slow_path_call_eval);
</span><span class="cx"> LLINT_SLOW_PATH_HIDDEN_DECL(slow_path_tear_off_activation);
</span><span class="cx"> LLINT_SLOW_PATH_HIDDEN_DECL(slow_path_tear_off_arguments);
</span></span></pre></div>
<a id="trunkSourceJavaScriptCorellintLowLevelInterpreterasm"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/llint/LowLevelInterpreter.asm (166391 => 166392)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/llint/LowLevelInterpreter.asm        2014-03-28 01:00:35 UTC (rev 166391)
+++ trunk/Source/JavaScriptCore/llint/LowLevelInterpreter.asm        2014-03-28 01:10:25 UTC (rev 166392)
</span><span class="lines">@@ -991,7 +991,25 @@
</span><span class="cx">     end
</span><span class="cx">     slowPathForCall(_llint_slow_path_call_varargs)
</span><span class="cx"> 
</span><ins>+_llint_op_construct_varargs:
+    traceExecution()
+    callSlowPath(_llint_slow_path_size_frame_for_varargs)
+    branchIfException(_llint_throw_from_slow_path_trampoline)
+    # calleeFrame in t1
+    if JSVALUE64
+        move t1, sp
+    else
+        # The calleeFrame is not stack aligned, move down by CallerFrameAndPCSize to align
+        if ARMv7
+            subp t1, CallerFrameAndPCSize, t2
+            move t2, sp
+        else
+            subp t1, CallerFrameAndPCSize, sp
+        end
+    end
+    slowPathForCall(_llint_slow_path_construct_varargs)
</ins><span class="cx"> 
</span><ins>+
</ins><span class="cx"> _llint_op_call_eval:
</span><span class="cx">     traceExecution()
</span><span class="cx">     
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreparserParsercpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/parser/Parser.cpp (166391 => 166392)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/parser/Parser.cpp        2014-03-28 01:00:35 UTC (rev 166391)
+++ trunk/Source/JavaScriptCore/parser/Parser.cpp        2014-03-28 01:10:25 UTC (rev 166392)
</span><span class="lines">@@ -2144,7 +2144,7 @@
</span><span class="cx">             if (newCount) {
</span><span class="cx">                 newCount--;
</span><span class="cx">                 JSTextPosition expressionEnd = lastTokenEndPosition();
</span><del>-                TreeArguments arguments = parseArguments(context, DontAllowSpread);
</del><ins>+                TreeArguments arguments = parseArguments(context, AllowSpread);
</ins><span class="cx">                 failIfFalse(arguments, &quot;Cannot parse call arguments&quot;);
</span><span class="cx">                 base = context.createNewExpr(location, base, arguments, expressionStart, expressionEnd, lastTokenEndPosition());
</span><span class="cx">             } else {
</span></span></pre>
</div>
</div>

</body>
</html>