<!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>[198808] 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/198808">198808</a></dd>
<dt>Author</dt> <dd>keith_miller@apple.com</dd>
<dt>Date</dt> <dd>2016-03-29 15:57:01 -0700 (Tue, 29 Mar 2016)</dd>
</dl>

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

Reviewed by Saam Barati.

Source/JavaScriptCore:

This patch adds support for Symbol.isConcatSpreadable. In order to do so it was necessary to move the
Array.prototype.concat function to JS. A number of different optimizations were needed to make such the move to
a builtin performant. First, four new DFG intrinsics were added.

1) IsArrayObject (I would have called it IsArray but we use the same name for an IndexingType): an intrinsic of
   the Array.isArray function.
2) IsJSArray: checks the first child is a JSArray object.
3) IsArrayConstructor: checks the first child is an instance of ArrayConstructor.
4) CallObjectConstructor: an intrinsic of the Object constructor.

IsActualObject, IsJSArray, and CallObjectConstructor can all be converted into constants in the abstract interpreter if
we are able to prove that the first child is an Array or for ToObject an Object.

In order to further improve the perfomance we also now cover more indexing types in our fast path memcpy
code. Before we would only memcpy Arrays if they had the same indexing type and did not have Array storage and
were not undecided. Now the memcpy code covers the following additional two cases: One array is undecided and
the other is a non-array storage and the case where one array is Int32 and the other is contiguous (we map this
into a contiguous array).

This patch also adds a new fast path for concat with more than one array argument by using memcpy to append
values onto the result array. This works roughly the same as the two array fast path using the same methodology
to decide if we can memcpy the other butterfly into the result butterfly.

Two new debugging tools are also added to the jsc cli. One is a version of the print function with a private
name so it can be used for debugging builtins. The other is dumpDataLog, which takes a JSValue and runs our
dataLog function on it.

Finally, this patch add a new constructor to JSValueRegsTemporary that allows it to reuse the the registers of a
JSValueOperand if the operand's use count is one.

* JavaScriptCore.xcodeproj/project.pbxproj:
* builtins/ArrayPrototype.js:
(concatSlowPath):
(concat):
* bytecode/BytecodeIntrinsicRegistry.cpp:
(JSC::BytecodeIntrinsicRegistry::BytecodeIntrinsicRegistry):
* bytecode/BytecodeIntrinsicRegistry.h:
* dfg/DFGAbstractInterpreterInlines.h:
(JSC::DFG::AbstractInterpreter&lt;AbstractStateType&gt;::executeEffects):
* dfg/DFGByteCodeParser.cpp:
(JSC::DFG::ByteCodeParser::handleIntrinsicCall):
(JSC::DFG::ByteCodeParser::handleConstantInternalFunction):
* dfg/DFGClobberize.h:
(JSC::DFG::clobberize):
* dfg/DFGDoesGC.cpp:
(JSC::DFG::doesGC):
* dfg/DFGFixupPhase.cpp:
(JSC::DFG::FixupPhase::fixupNode):
* 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::compileCurrentBlock):
(JSC::DFG::SpeculativeJIT::compileIsJSArray):
(JSC::DFG::SpeculativeJIT::compileIsArrayObject):
(JSC::DFG::SpeculativeJIT::compileIsArrayConstructor):
(JSC::DFG::SpeculativeJIT::compileCallObjectConstructor):
* 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/FTLLowerDFGToB3.cpp:
(JSC::FTL::DFG::LowerDFGToB3::compileNode):
(JSC::FTL::DFG::LowerDFGToB3::compileCallObjectConstructor):
(JSC::FTL::DFG::LowerDFGToB3::compileIsArrayObject):
(JSC::FTL::DFG::LowerDFGToB3::compileIsJSArray):
(JSC::FTL::DFG::LowerDFGToB3::compileIsArrayConstructor):
(JSC::FTL::DFG::LowerDFGToB3::isArray):
* jit/JITOperations.h:
* jsc.cpp:
(WTF::RuntimeArray::createStructure):
(GlobalObject::finishCreation):
(functionDebug):
(functionDataLogValue):
* runtime/ArrayConstructor.cpp:
(JSC::ArrayConstructor::finishCreation):
(JSC::arrayConstructorPrivateFuncIsArrayConstructor):
* runtime/ArrayConstructor.h:
(JSC::isArrayConstructor):
* runtime/ArrayPrototype.cpp:
(JSC::ArrayPrototype::finishCreation):
(JSC::arrayProtoPrivateFuncIsJSArray):
(JSC::moveElements):
(JSC::arrayProtoPrivateFuncConcatMemcpy):
(JSC::arrayProtoPrivateFuncAppendMemcpy):
(JSC::arrayProtoFuncConcat): Deleted.
* runtime/ArrayPrototype.h:
(JSC::ArrayPrototype::createStructure):
* runtime/CommonIdentifiers.h:
* runtime/Intrinsic.h:
* runtime/JSArray.cpp:
(JSC::JSArray::appendMemcpy):
(JSC::JSArray::fastConcatWith): Deleted.
* runtime/JSArray.h:
(JSC::JSArray::createStructure):
(JSC::JSArray::fastConcatType): Deleted.
* runtime/JSArrayInlines.h: Added.
(JSC::JSArray::memCopyWithIndexingType):
(JSC::JSArray::canFastCopy):
* runtime/JSGlobalObject.cpp:
(JSC::JSGlobalObject::init):
* runtime/JSType.h:
* runtime/ObjectConstructor.h:
(JSC::constructObject):
* tests/es6.yaml:
* tests/stress/array-concat-spread-object.js: Added.
(arrayEq):
* tests/stress/array-concat-spread-proxy-exception-check.js: Added.
(arrayEq):
* tests/stress/array-concat-spread-proxy.js: Added.
(arrayEq):
* tests/stress/array-concat-with-slow-indexingtypes.js: Added.
(arrayEq):
* tests/stress/array-species-config-array-constructor.js:

Source/WebCore:

Makes runtime arrays have the new ArrayType

* bridge/runtime_array.h:
(JSC::RuntimeArray::createStructure):

LayoutTests:

Fix tests for Symbol.isConcatSpreadable on the Symbol object.

* js/Object-getOwnPropertyNames-expected.txt:
* js/dom/array-prototype-properties-expected.txt:
* js/script-tests/Object-getOwnPropertyNames.js:</pre>

<h3>Modified Paths</h3>
<ul>
<li><a href="#trunkLayoutTestsChangeLog">trunk/LayoutTests/ChangeLog</a></li>
<li><a href="#trunkLayoutTestsjsObjectgetOwnPropertyNamesexpectedtxt">trunk/LayoutTests/js/Object-getOwnPropertyNames-expected.txt</a></li>
<li><a href="#trunkLayoutTestsjsdomarrayprototypepropertiesexpectedtxt">trunk/LayoutTests/js/dom/array-prototype-properties-expected.txt</a></li>
<li><a href="#trunkLayoutTestsjsscripttestsObjectgetOwnPropertyNamesjs">trunk/LayoutTests/js/script-tests/Object-getOwnPropertyNames.js</a></li>
<li><a href="#trunkSourceJavaScriptCoreChangeLog">trunk/Source/JavaScriptCore/ChangeLog</a></li>
<li><a href="#trunkSourceJavaScriptCoreJavaScriptCorexcodeprojprojectpbxproj">trunk/Source/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj</a></li>
<li><a href="#trunkSourceJavaScriptCorebuiltinsArrayPrototypejs">trunk/Source/JavaScriptCore/builtins/ArrayPrototype.js</a></li>
<li><a href="#trunkSourceJavaScriptCorebytecodeBytecodeIntrinsicRegistrycpp">trunk/Source/JavaScriptCore/bytecode/BytecodeIntrinsicRegistry.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCorebytecodeBytecodeIntrinsicRegistryh">trunk/Source/JavaScriptCore/bytecode/BytecodeIntrinsicRegistry.h</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="#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="#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="#trunkSourceJavaScriptCoreftlFTLLowerDFGToB3cpp">trunk/Source/JavaScriptCore/ftl/FTLLowerDFGToB3.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCorejitJITOperationsh">trunk/Source/JavaScriptCore/jit/JITOperations.h</a></li>
<li><a href="#trunkSourceJavaScriptCorejsccpp">trunk/Source/JavaScriptCore/jsc.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoreruntimeArrayConstructorcpp">trunk/Source/JavaScriptCore/runtime/ArrayConstructor.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoreruntimeArrayConstructorh">trunk/Source/JavaScriptCore/runtime/ArrayConstructor.h</a></li>
<li><a href="#trunkSourceJavaScriptCoreruntimeArrayPrototypecpp">trunk/Source/JavaScriptCore/runtime/ArrayPrototype.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoreruntimeArrayPrototypeh">trunk/Source/JavaScriptCore/runtime/ArrayPrototype.h</a></li>
<li><a href="#trunkSourceJavaScriptCoreruntimeCommonIdentifiersh">trunk/Source/JavaScriptCore/runtime/CommonIdentifiers.h</a></li>
<li><a href="#trunkSourceJavaScriptCoreruntimeIntrinsich">trunk/Source/JavaScriptCore/runtime/Intrinsic.h</a></li>
<li><a href="#trunkSourceJavaScriptCoreruntimeJSArraycpp">trunk/Source/JavaScriptCore/runtime/JSArray.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoreruntimeJSArrayh">trunk/Source/JavaScriptCore/runtime/JSArray.h</a></li>
<li><a href="#trunkSourceJavaScriptCoreruntimeJSGlobalObjectcpp">trunk/Source/JavaScriptCore/runtime/JSGlobalObject.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoreruntimeJSTypeh">trunk/Source/JavaScriptCore/runtime/JSType.h</a></li>
<li><a href="#trunkSourceJavaScriptCoreruntimeObjectConstructorh">trunk/Source/JavaScriptCore/runtime/ObjectConstructor.h</a></li>
<li><a href="#trunkSourceJavaScriptCoretestses6yaml">trunk/Source/JavaScriptCore/tests/es6.yaml</a></li>
<li><a href="#trunkSourceJavaScriptCoretestsstressarrayspeciesconfigarrayconstructorjs">trunk/Source/JavaScriptCore/tests/stress/array-species-config-array-constructor.js</a></li>
<li><a href="#trunkSourceWebCoreChangeLog">trunk/Source/WebCore/ChangeLog</a></li>
<li><a href="#trunkSourceWebCorebridgeruntime_arrayh">trunk/Source/WebCore/bridge/runtime_array.h</a></li>
</ul>

<h3>Added Paths</h3>
<ul>
<li><a href="#trunkSourceJavaScriptCoreruntimeJSArrayInlinesh">trunk/Source/JavaScriptCore/runtime/JSArrayInlines.h</a></li>
<li><a href="#trunkSourceJavaScriptCoretestsstressarrayconcatspreadobjectjs">trunk/Source/JavaScriptCore/tests/stress/array-concat-spread-object.js</a></li>
<li><a href="#trunkSourceJavaScriptCoretestsstressarrayconcatspreadproxyexceptioncheckjs">trunk/Source/JavaScriptCore/tests/stress/array-concat-spread-proxy-exception-check.js</a></li>
<li><a href="#trunkSourceJavaScriptCoretestsstressarrayconcatspreadproxyjs">trunk/Source/JavaScriptCore/tests/stress/array-concat-spread-proxy.js</a></li>
<li><a href="#trunkSourceJavaScriptCoretestsstressarrayconcatwithslowindexingtypesjs">trunk/Source/JavaScriptCore/tests/stress/array-concat-with-slow-indexingtypes.js</a></li>
</ul>

</div>
<div id="patch">
<h3>Diff</h3>
<a id="trunkLayoutTestsChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/LayoutTests/ChangeLog (198807 => 198808)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/ChangeLog        2016-03-29 22:23:42 UTC (rev 198807)
+++ trunk/LayoutTests/ChangeLog        2016-03-29 22:57:01 UTC (rev 198808)
</span><span class="lines">@@ -1,3 +1,16 @@
</span><ins>+2016-03-29  Keith Miller  &lt;keith_miller@apple.com&gt;
+
+        [ES6] Add support for Symbol.isConcatSpreadable.
+        https://bugs.webkit.org/show_bug.cgi?id=155351
+
+        Reviewed by Saam Barati.
+
+        Fix tests for Symbol.isConcatSpreadable on the Symbol object.
+
+        * js/Object-getOwnPropertyNames-expected.txt:
+        * js/dom/array-prototype-properties-expected.txt:
+        * js/script-tests/Object-getOwnPropertyNames.js:
+
</ins><span class="cx"> 2016-03-29  Nan Wang  &lt;n_wang@apple.com&gt;
</span><span class="cx"> 
</span><span class="cx">         AX: VoiceOver: Navigating Numbered Lists Causes Number to be announced On Each Line of List
</span></span></pre></div>
<a id="trunkLayoutTestsjsObjectgetOwnPropertyNamesexpectedtxt"></a>
<div class="modfile"><h4>Modified: trunk/LayoutTests/js/Object-getOwnPropertyNames-expected.txt (198807 => 198808)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/js/Object-getOwnPropertyNames-expected.txt        2016-03-29 22:23:42 UTC (rev 198807)
+++ trunk/LayoutTests/js/Object-getOwnPropertyNames-expected.txt        2016-03-29 22:57:01 UTC (rev 198808)
</span><span class="lines">@@ -61,7 +61,7 @@
</span><span class="cx"> PASS getSortedOwnPropertyNames(Error.prototype) is ['constructor', 'message', 'name', 'toString']
</span><span class="cx"> PASS getSortedOwnPropertyNames(Math) is ['E','LN10','LN2','LOG10E','LOG2E','PI','SQRT1_2','SQRT2','abs','acos','acosh','asin','asinh','atan','atan2','atanh','cbrt','ceil','clz32','cos','cosh','exp','expm1','floor','fround','hypot','imul','log','log10','log1p','log2','max','min','pow','random','round','sign','sin','sinh','sqrt','tan','tanh','trunc']
</span><span class="cx"> PASS getSortedOwnPropertyNames(JSON) is ['parse', 'stringify']
</span><del>-PASS getSortedOwnPropertyNames(Symbol) is ['for', 'hasInstance', 'iterator', 'keyFor', 'length', 'match', 'name', 'prototype', 'search', 'species', 'toPrimitive', 'toStringTag', 'unscopables']
</del><ins>+PASS getSortedOwnPropertyNames(Symbol) is ['for', 'hasInstance', 'isConcatSpreadable', 'iterator', 'keyFor', 'length', 'match', 'name', 'prototype', 'search', 'species', 'toPrimitive', 'toStringTag', 'unscopables']
</ins><span class="cx"> PASS getSortedOwnPropertyNames(Symbol.prototype) is ['constructor', 'toString', 'valueOf']
</span><span class="cx"> PASS getSortedOwnPropertyNames(Map) is ['length', 'name', 'prototype']
</span><span class="cx"> PASS getSortedOwnPropertyNames(Map.prototype) is ['clear', 'constructor', 'delete', 'entries', 'forEach', 'get', 'has', 'keys', 'set', 'size', 'values']
</span></span></pre></div>
<a id="trunkLayoutTestsjsdomarrayprototypepropertiesexpectedtxt"></a>
<div class="modfile"><h4>Modified: trunk/LayoutTests/js/dom/array-prototype-properties-expected.txt (198807 => 198808)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/js/dom/array-prototype-properties-expected.txt        2016-03-29 22:23:42 UTC (rev 198807)
+++ trunk/LayoutTests/js/dom/array-prototype-properties-expected.txt        2016-03-29 22:57:01 UTC (rev 198808)
</span><span class="lines">@@ -5,7 +5,7 @@
</span><span class="cx"> 
</span><span class="cx"> PASS Array.prototype.toString.call(undefined) threw exception TypeError: undefined is not an object (evaluating 'Array.prototype.toString.call(undefined)').
</span><span class="cx"> PASS Array.prototype.toLocaleString.call(undefined) threw exception TypeError: undefined is not an object (evaluating 'Array.prototype.toLocaleString.call(undefined)').
</span><del>-PASS Array.prototype.concat.call(undefined, []) threw exception TypeError: undefined is not an object (evaluating 'Array.prototype.concat.call(undefined, [])').
</del><ins>+PASS Array.prototype.concat.call(undefined, []) threw exception TypeError: Array.prototype.concat requires that |this| not be undefined.
</ins><span class="cx"> PASS Array.prototype.join.call(undefined, []) threw exception TypeError: undefined is not an object (evaluating 'Array.prototype.join.call(undefined, [])').
</span><span class="cx"> PASS Array.prototype.pop.call(undefined) threw exception TypeError: undefined is not an object (evaluating 'Array.prototype.pop.call(undefined)').
</span><span class="cx"> PASS Array.prototype.push.call(undefined, {}) threw exception TypeError: undefined is not an object (evaluating 'Array.prototype.push.call(undefined, {})').
</span></span></pre></div>
<a id="trunkLayoutTestsjsscripttestsObjectgetOwnPropertyNamesjs"></a>
<div class="modfile"><h4>Modified: trunk/LayoutTests/js/script-tests/Object-getOwnPropertyNames.js (198807 => 198808)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/js/script-tests/Object-getOwnPropertyNames.js        2016-03-29 22:23:42 UTC (rev 198807)
+++ trunk/LayoutTests/js/script-tests/Object-getOwnPropertyNames.js        2016-03-29 22:57:01 UTC (rev 198808)
</span><span class="lines">@@ -70,7 +70,7 @@
</span><span class="cx">     &quot;Error.prototype&quot;: &quot;['constructor', 'message', 'name', 'toString']&quot;,
</span><span class="cx">     &quot;Math&quot;: &quot;['E','LN10','LN2','LOG10E','LOG2E','PI','SQRT1_2','SQRT2','abs','acos','acosh','asin','asinh','atan','atan2','atanh','cbrt','ceil','clz32','cos','cosh','exp','expm1','floor','fround','hypot','imul','log','log10','log1p','log2','max','min','pow','random','round','sign','sin','sinh','sqrt','tan','tanh','trunc']&quot;,
</span><span class="cx">     &quot;JSON&quot;: &quot;['parse', 'stringify']&quot;,
</span><del>-    &quot;Symbol&quot;: &quot;['for', 'hasInstance', 'iterator', 'keyFor', 'length', 'match', 'name', 'prototype', 'search', 'species', 'toPrimitive', 'toStringTag', 'unscopables']&quot;,
</del><ins>+    &quot;Symbol&quot;: &quot;['for', 'hasInstance', 'isConcatSpreadable', 'iterator', 'keyFor', 'length', 'match', 'name', 'prototype', 'search', 'species', 'toPrimitive', 'toStringTag', 'unscopables']&quot;,
</ins><span class="cx">     &quot;Symbol.prototype&quot;: &quot;['constructor', 'toString', 'valueOf']&quot;,
</span><span class="cx">     &quot;Map&quot;: &quot;['length', 'name', 'prototype']&quot;,
</span><span class="cx">     &quot;Map.prototype&quot;: &quot;['clear', 'constructor', 'delete', 'entries', 'forEach', 'get', 'has', 'keys', 'set', 'size', 'values']&quot;,
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/ChangeLog (198807 => 198808)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/ChangeLog        2016-03-29 22:23:42 UTC (rev 198807)
+++ trunk/Source/JavaScriptCore/ChangeLog        2016-03-29 22:57:01 UTC (rev 198808)
</span><span class="lines">@@ -1,3 +1,133 @@
</span><ins>+2016-03-29  Keith Miller  &lt;keith_miller@apple.com&gt;
+
+        [ES6] Add support for Symbol.isConcatSpreadable.
+        https://bugs.webkit.org/show_bug.cgi?id=155351
+
+        Reviewed by Saam Barati.
+
+        This patch adds support for Symbol.isConcatSpreadable. In order to do so it was necessary to move the
+        Array.prototype.concat function to JS. A number of different optimizations were needed to make such the move to
+        a builtin performant. First, four new DFG intrinsics were added.
+
+        1) IsArrayObject (I would have called it IsArray but we use the same name for an IndexingType): an intrinsic of
+           the Array.isArray function.
+        2) IsJSArray: checks the first child is a JSArray object.
+        3) IsArrayConstructor: checks the first child is an instance of ArrayConstructor.
+        4) CallObjectConstructor: an intrinsic of the Object constructor.
+
+        IsActualObject, IsJSArray, and CallObjectConstructor can all be converted into constants in the abstract interpreter if
+        we are able to prove that the first child is an Array or for ToObject an Object.
+
+        In order to further improve the perfomance we also now cover more indexing types in our fast path memcpy
+        code. Before we would only memcpy Arrays if they had the same indexing type and did not have Array storage and
+        were not undecided. Now the memcpy code covers the following additional two cases: One array is undecided and
+        the other is a non-array storage and the case where one array is Int32 and the other is contiguous (we map this
+        into a contiguous array).
+
+        This patch also adds a new fast path for concat with more than one array argument by using memcpy to append
+        values onto the result array. This works roughly the same as the two array fast path using the same methodology
+        to decide if we can memcpy the other butterfly into the result butterfly.
+
+        Two new debugging tools are also added to the jsc cli. One is a version of the print function with a private
+        name so it can be used for debugging builtins. The other is dumpDataLog, which takes a JSValue and runs our
+        dataLog function on it.
+
+        Finally, this patch add a new constructor to JSValueRegsTemporary that allows it to reuse the the registers of a
+        JSValueOperand if the operand's use count is one.
+
+        * JavaScriptCore.xcodeproj/project.pbxproj:
+        * builtins/ArrayPrototype.js:
+        (concatSlowPath):
+        (concat):
+        * bytecode/BytecodeIntrinsicRegistry.cpp:
+        (JSC::BytecodeIntrinsicRegistry::BytecodeIntrinsicRegistry):
+        * bytecode/BytecodeIntrinsicRegistry.h:
+        * dfg/DFGAbstractInterpreterInlines.h:
+        (JSC::DFG::AbstractInterpreter&lt;AbstractStateType&gt;::executeEffects):
+        * dfg/DFGByteCodeParser.cpp:
+        (JSC::DFG::ByteCodeParser::handleIntrinsicCall):
+        (JSC::DFG::ByteCodeParser::handleConstantInternalFunction):
+        * dfg/DFGClobberize.h:
+        (JSC::DFG::clobberize):
+        * dfg/DFGDoesGC.cpp:
+        (JSC::DFG::doesGC):
+        * dfg/DFGFixupPhase.cpp:
+        (JSC::DFG::FixupPhase::fixupNode):
+        * 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::compileCurrentBlock):
+        (JSC::DFG::SpeculativeJIT::compileIsJSArray):
+        (JSC::DFG::SpeculativeJIT::compileIsArrayObject):
+        (JSC::DFG::SpeculativeJIT::compileIsArrayConstructor):
+        (JSC::DFG::SpeculativeJIT::compileCallObjectConstructor):
+        * 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/FTLLowerDFGToB3.cpp:
+        (JSC::FTL::DFG::LowerDFGToB3::compileNode):
+        (JSC::FTL::DFG::LowerDFGToB3::compileCallObjectConstructor):
+        (JSC::FTL::DFG::LowerDFGToB3::compileIsArrayObject):
+        (JSC::FTL::DFG::LowerDFGToB3::compileIsJSArray):
+        (JSC::FTL::DFG::LowerDFGToB3::compileIsArrayConstructor):
+        (JSC::FTL::DFG::LowerDFGToB3::isArray):
+        * jit/JITOperations.h:
+        * jsc.cpp:
+        (WTF::RuntimeArray::createStructure):
+        (GlobalObject::finishCreation):
+        (functionDebug):
+        (functionDataLogValue):
+        * runtime/ArrayConstructor.cpp:
+        (JSC::ArrayConstructor::finishCreation):
+        (JSC::arrayConstructorPrivateFuncIsArrayConstructor):
+        * runtime/ArrayConstructor.h:
+        (JSC::isArrayConstructor):
+        * runtime/ArrayPrototype.cpp:
+        (JSC::ArrayPrototype::finishCreation):
+        (JSC::arrayProtoPrivateFuncIsJSArray):
+        (JSC::moveElements):
+        (JSC::arrayProtoPrivateFuncConcatMemcpy):
+        (JSC::arrayProtoPrivateFuncAppendMemcpy):
+        (JSC::arrayProtoFuncConcat): Deleted.
+        * runtime/ArrayPrototype.h:
+        (JSC::ArrayPrototype::createStructure):
+        * runtime/CommonIdentifiers.h:
+        * runtime/Intrinsic.h:
+        * runtime/JSArray.cpp:
+        (JSC::JSArray::appendMemcpy):
+        (JSC::JSArray::fastConcatWith): Deleted.
+        * runtime/JSArray.h:
+        (JSC::JSArray::createStructure):
+        (JSC::JSArray::fastConcatType): Deleted.
+        * runtime/JSArrayInlines.h: Added.
+        (JSC::JSArray::memCopyWithIndexingType):
+        (JSC::JSArray::canFastCopy):
+        * runtime/JSGlobalObject.cpp:
+        (JSC::JSGlobalObject::init):
+        * runtime/JSType.h:
+        * runtime/ObjectConstructor.h:
+        (JSC::constructObject):
+        * tests/es6.yaml:
+        * tests/stress/array-concat-spread-object.js: Added.
+        (arrayEq):
+        * tests/stress/array-concat-spread-proxy-exception-check.js: Added.
+        (arrayEq):
+        * tests/stress/array-concat-spread-proxy.js: Added.
+        (arrayEq):
+        * tests/stress/array-concat-with-slow-indexingtypes.js: Added.
+        (arrayEq):
+        * tests/stress/array-species-config-array-constructor.js:
+
</ins><span class="cx"> 2016-03-29  Saam barati  &lt;sbarati@apple.com&gt;
</span><span class="cx"> 
</span><span class="cx">         We don't properly optimize TDZ checks when we declare a let variable without an initializer
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreJavaScriptCorexcodeprojprojectpbxproj"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj (198807 => 198808)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj        2016-03-29 22:23:42 UTC (rev 198807)
+++ trunk/Source/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj        2016-03-29 22:57:01 UTC (rev 198808)
</span><span class="lines">@@ -1184,6 +1184,7 @@
</span><span class="cx">                 5370B4F51BF26202005C40FC /* AdaptiveInferredPropertyValueWatchpointBase.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 5370B4F31BF25EA2005C40FC /* AdaptiveInferredPropertyValueWatchpointBase.cpp */; };
</span><span class="cx">                 5370B4F61BF26205005C40FC /* AdaptiveInferredPropertyValueWatchpointBase.h in Headers */ = {isa = PBXBuildFile; fileRef = 5370B4F41BF25EA2005C40FC /* AdaptiveInferredPropertyValueWatchpointBase.h */; };
</span><span class="cx">                 53917E7B1B7906FA000EBD33 /* JSGenericTypedArrayViewPrototypeFunctions.h in Headers */ = {isa = PBXBuildFile; fileRef = 53917E7A1B7906E4000EBD33 /* JSGenericTypedArrayViewPrototypeFunctions.h */; };
</span><ins>+                539FB8BA1C99DA7C00940FA1 /* JSArrayInlines.h in Headers */ = {isa = PBXBuildFile; fileRef = 539FB8B91C99DA7C00940FA1 /* JSArrayInlines.h */; };
</ins><span class="cx">                 53F6BF6D1C3F060A00F41E5D /* InternalFunctionAllocationProfile.h in Headers */ = {isa = PBXBuildFile; fileRef = 53F6BF6C1C3F060A00F41E5D /* InternalFunctionAllocationProfile.h */; settings = {ATTRIBUTES = (Private, ); }; };
</span><span class="cx">                 5D53726F0E1C54880021E549 /* Tracing.h in Headers */ = {isa = PBXBuildFile; fileRef = 5D53726E0E1C54880021E549 /* Tracing.h */; };
</span><span class="cx">                 5D5D8AD10E0D0EBE00F9C692 /* libedit.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = 5D5D8AD00E0D0EBE00F9C692 /* libedit.dylib */; };
</span><span class="lines">@@ -3312,6 +3313,7 @@
</span><span class="cx">                 53917E7A1B7906E4000EBD33 /* JSGenericTypedArrayViewPrototypeFunctions.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JSGenericTypedArrayViewPrototypeFunctions.h; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><span class="cx">                 53917E7C1B791106000EBD33 /* JSTypedArrayViewPrototype.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JSTypedArrayViewPrototype.h; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><span class="cx">                 53917E831B791CB8000EBD33 /* TypedArrayPrototype.js */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.javascript; name = TypedArrayPrototype.js; path = builtins/TypedArrayPrototype.js; sourceTree = SOURCE_ROOT; };
</span><ins>+                539FB8B91C99DA7C00940FA1 /* JSArrayInlines.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JSArrayInlines.h; sourceTree = &quot;&lt;group&gt;&quot;; };
</ins><span class="cx">                 53F256E11B87E28000B4B768 /* JSTypedArrayViewPrototype.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = JSTypedArrayViewPrototype.cpp; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><span class="cx">                 53F6BF6C1C3F060A00F41E5D /* InternalFunctionAllocationProfile.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = InternalFunctionAllocationProfile.h; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><span class="cx">                 593D43CCA0BBE06D89C59707 /* MapDataInlines.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MapDataInlines.h; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><span class="lines">@@ -5657,6 +5659,7 @@
</span><span class="cx">                                 70DC3E081B2DF2C700054299 /* IteratorPrototype.h */,
</span><span class="cx">                                 93ADFCE60CCBD7AC00D30B08 /* JSArray.cpp */,
</span><span class="cx">                                 938772E5038BFE19008635CE /* JSArray.h */,
</span><ins>+                                539FB8B91C99DA7C00940FA1 /* JSArrayInlines.h */,
</ins><span class="cx">                                 0F2B66B417B6B5AB00A7AE3F /* JSArrayBuffer.cpp */,
</span><span class="cx">                                 0F2B66B517B6B5AB00A7AE3F /* JSArrayBuffer.h */,
</span><span class="cx">                                 0F2B66B617B6B5AB00A7AE3F /* JSArrayBufferConstructor.cpp */,
</span><span class="lines">@@ -7500,6 +7503,7 @@
</span><span class="cx">                                 0FB7F39B15ED8E4600F167B2 /* IndexingType.h in Headers */,
</span><span class="cx">                                 0F0A75231B94BFA900110660 /* InferredType.h in Headers */,
</span><span class="cx">                                 0FFC92121B94D4DF0071DD66 /* InferredTypeTable.h in Headers */,
</span><ins>+                                539FB8BA1C99DA7C00940FA1 /* JSArrayInlines.h in Headers */,
</ins><span class="cx">                                 0FF8BDEB1AD4CF7100DFE884 /* InferredValue.h in Headers */,
</span><span class="cx">                                 BC18C4100E16F5CD00B34460 /* InitializeThreading.h in Headers */,
</span><span class="cx">                                 A513E5B8185B8BD3007E95AD /* InjectedScript.h in Headers */,
</span></span></pre></div>
<a id="trunkSourceJavaScriptCorebuiltinsArrayPrototypejs"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/builtins/ArrayPrototype.js (198807 => 198808)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/builtins/ArrayPrototype.js        2016-03-29 22:23:42 UTC (rev 198807)
+++ trunk/Source/JavaScriptCore/builtins/ArrayPrototype.js        2016-03-29 22:57:01 UTC (rev 198808)
</span><span class="lines">@@ -646,6 +646,94 @@
</span><span class="cx">     return array;
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+function concatSlowPath()
+{
+    &quot;use strict&quot;;
+
+    var argCount = arguments.length;
+    var result = new this.species(0);
+    var resultIsArray = @isJSArray(result);
+
+    var currentElement = this.array;
+    var resultIndex = 0;
+    var argIndex = 0;
+
+    do {
+        var spreadable = @isObject(currentElement) &amp;&amp; currentElement[@symbolIsConcatSpreadable];
+        if ((spreadable == @undefined &amp;&amp; @isArray(currentElement)) || spreadable) {
+            var length = @toLength(currentElement.length);
+            if (resultIsArray &amp;&amp; @isJSArray(currentElement)
+                &amp;&amp; @appendMemcpy(result, currentElement)) {
+
+                resultIndex += length;
+            } else {
+                if (length + resultIndex &gt; @MAX_SAFE_INTEGER)
+                    throw @TypeError(&quot;length exceeded the maximum safe integer&quot;);
+                for (var i = 0; i &lt; length; i++) {
+                    if (i in currentElement)
+                        @putByValDirect(result, resultIndex, currentElement[i]);
+                    resultIndex++;
+                }
+            }
+        } else {
+            if (resultIndex &gt;= @MAX_SAFE_INTEGER)
+                throw @TypeError(&quot;length exceeded the maximum safe integer&quot;);
+            @putByValDirect(result, resultIndex++, currentElement);
+        }
+        currentElement = arguments[argIndex];
+    } while (argIndex++ &lt; argCount);
+
+    result.length = resultIndex;
+    return result;
+}
+
+function concat(first)
+{
+    &quot;use strict&quot;;
+
+    if (this == null) {
+        if (this === null)
+            throw new @TypeError(&quot;Array.prototype.concat requires that |this| not be null&quot;);
+        throw new @TypeError(&quot;Array.prototype.concat requires that |this| not be undefined&quot;);
+    }
+
+    var array = @Object(this);
+
+    var constructor;
+    if (@isArray(array)) {
+        constructor = array.constructor;
+        // We have this check so that if some array from a different global object
+        // calls this map they don't get an array with the Array.prototype of the
+        // other global object.
+        if (@isArrayConstructor(constructor) &amp;&amp; @Array !== constructor)
+            constructor = @undefined;
+        if (@isObject(constructor)) {
+            constructor = constructor[@symbolSpecies];
+            if (constructor === null)
+                constructor = @Array;
+        }
+    }
+    if (constructor === @undefined)
+        constructor = @Array;
+
+    var result;
+    if (arguments.length === 1
+        &amp;&amp; constructor === @Array
+        &amp;&amp; @isJSArray(array)
+        &amp;&amp; @isJSArray(first)
+        // FIXME: these get_by_ids should be &quot;in&quot;s but using &quot;in&quot; here is a 10% regression.
+        // https://bugs.webkit.org/show_bug.cgi?id=155590
+        &amp;&amp; array[@symbolIsConcatSpreadable] == @undefined
+        &amp;&amp; first[@symbolIsConcatSpreadable] == @undefined) {
+
+        result = @concatMemcpy(array, first);
+        if (result !== null)
+            return result;
+    }
+
+    return @concatSlowPath.@apply({ array: array, species: constructor }, arguments);
+}
+
</ins><span class="cx"> function copyWithin(target, start /*, end */)
</span><span class="cx"> {
</span><span class="cx">     &quot;use strict&quot;;
</span></span></pre></div>
<a id="trunkSourceJavaScriptCorebytecodeBytecodeIntrinsicRegistrycpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/bytecode/BytecodeIntrinsicRegistry.cpp (198807 => 198808)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/bytecode/BytecodeIntrinsicRegistry.cpp        2016-03-29 22:23:42 UTC (rev 198807)
+++ trunk/Source/JavaScriptCore/bytecode/BytecodeIntrinsicRegistry.cpp        2016-03-29 22:57:01 UTC (rev 198808)
</span><span class="lines">@@ -47,9 +47,11 @@
</span><span class="cx">     m_arrayIterationKindKey.set(m_vm, jsNumber(ArrayIterateKey));
</span><span class="cx">     m_arrayIterationKindValue.set(m_vm, jsNumber(ArrayIterateValue));
</span><span class="cx">     m_arrayIterationKindKeyValue.set(m_vm, jsNumber(ArrayIterateKeyValue));
</span><ins>+    m_MAX_SAFE_INTEGER.set(m_vm, jsDoubleNumber(9007199254740991.0)); // 2 ^ 53 - 1
</ins><span class="cx">     m_promiseStatePending.set(m_vm, jsNumber(static_cast&lt;unsigned&gt;(JSPromise::Status::Pending)));
</span><span class="cx">     m_promiseStateFulfilled.set(m_vm, jsNumber(static_cast&lt;unsigned&gt;(JSPromise::Status::Fulfilled)));
</span><span class="cx">     m_promiseStateRejected.set(m_vm, jsNumber(static_cast&lt;unsigned&gt;(JSPromise::Status::Rejected)));
</span><ins>+    m_symbolIsConcatSpreadable.set(m_vm, Symbol::create(m_vm, static_cast&lt;SymbolImpl&amp;&gt;(*m_vm.propertyNames-&gt;isConcatSpreadableSymbol.impl())));
</ins><span class="cx">     m_symbolIterator.set(m_vm, Symbol::create(m_vm, static_cast&lt;SymbolImpl&amp;&gt;(*m_vm.propertyNames-&gt;iteratorSymbol.impl())));
</span><span class="cx">     m_symbolMatch.set(m_vm, Symbol::create(m_vm, static_cast&lt;SymbolImpl&amp;&gt;(*m_vm.propertyNames-&gt;matchSymbol.impl())));
</span><span class="cx">     m_symbolSearch.set(m_vm, Symbol::create(m_vm, static_cast&lt;SymbolImpl&amp;&gt;(*m_vm.propertyNames-&gt;searchSymbol.impl())));
</span></span></pre></div>
<a id="trunkSourceJavaScriptCorebytecodeBytecodeIntrinsicRegistryh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/bytecode/BytecodeIntrinsicRegistry.h (198807 => 198808)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/bytecode/BytecodeIntrinsicRegistry.h        2016-03-29 22:23:42 UTC (rev 198807)
+++ trunk/Source/JavaScriptCore/bytecode/BytecodeIntrinsicRegistry.h        2016-03-29 22:57:01 UTC (rev 198808)
</span><span class="lines">@@ -49,9 +49,11 @@
</span><span class="cx">     macro(arrayIterationKindKey) \
</span><span class="cx">     macro(arrayIterationKindValue) \
</span><span class="cx">     macro(arrayIterationKindKeyValue) \
</span><ins>+    macro(MAX_SAFE_INTEGER) \
</ins><span class="cx">     macro(promiseStatePending) \
</span><span class="cx">     macro(promiseStateFulfilled) \
</span><span class="cx">     macro(promiseStateRejected) \
</span><ins>+    macro(symbolIsConcatSpreadable) \
</ins><span class="cx">     macro(symbolIterator) \
</span><span class="cx">     macro(symbolMatch) \
</span><span class="cx">     macro(symbolSearch) \
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoredfgDFGAbstractInterpreterInlinesh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/dfg/DFGAbstractInterpreterInlines.h (198807 => 198808)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/dfg/DFGAbstractInterpreterInlines.h        2016-03-29 22:23:42 UTC (rev 198807)
+++ trunk/Source/JavaScriptCore/dfg/DFGAbstractInterpreterInlines.h        2016-03-29 22:57:01 UTC (rev 198808)
</span><span class="lines">@@ -28,6 +28,7 @@
</span><span class="cx"> 
</span><span class="cx"> #if ENABLE(DFG_JIT)
</span><span class="cx"> 
</span><ins>+#include &quot;ArrayConstructor.h&quot;
</ins><span class="cx"> #include &quot;DFGAbstractInterpreter.h&quot;
</span><span class="cx"> #include &quot;GetByIdStatus.h&quot;
</span><span class="cx"> #include &quot;GetterSetter.h&quot;
</span><span class="lines">@@ -952,7 +953,10 @@
</span><span class="cx">         }
</span><span class="cx">         break;
</span><span class="cx">     }
</span><del>-        
</del><ins>+
+    case IsArrayObject:
+    case IsJSArray:
+    case IsArrayConstructor:
</ins><span class="cx">     case IsUndefined:
</span><span class="cx">     case IsBoolean:
</span><span class="cx">     case IsNumber:
</span><span class="lines">@@ -964,6 +968,28 @@
</span><span class="cx">         if (child.value()) {
</span><span class="cx">             bool constantWasSet = true;
</span><span class="cx">             switch (node-&gt;op()) {
</span><ins>+            case IsArrayObject:
+                if (child.value().isObject()) {
+                    if (child.value().getObject()-&gt;type() == ArrayType) {
+                        setConstant(node, jsBoolean(true));
+                        break;
+                    }
+
+                    if (child.value().getObject()-&gt;type() == ProxyObjectType) {
+                        // We have no way of knowing what type we are proxing yet.
+                        constantWasSet = false;
+                        break;
+                    }
+                }
+
+                setConstant(node, jsBoolean(false));
+                break;
+            case IsJSArray:
+                setConstant(node, jsBoolean(child.value().isObject() &amp;&amp; child.value().getObject()-&gt;type() == ArrayType));
+                break;
+            case IsArrayConstructor:
+                setConstant(node, jsBoolean(child.value().isObject() &amp;&amp; child.value().getObject()-&gt;classInfo() == ArrayConstructor::info()));
+                break;
</ins><span class="cx">             case IsUndefined:
</span><span class="cx">                 setConstant(node, jsBoolean(
</span><span class="cx">                     child.value().isCell()
</span><span class="lines">@@ -1026,6 +1052,22 @@
</span><span class="cx">         
</span><span class="cx">         bool constantWasSet = false;
</span><span class="cx">         switch (node-&gt;op()) {
</span><ins>+        case IsJSArray:
+        case IsArrayObject:
+            // We don't have a SpeculatedType for Proxies yet so we can't do better at proving false.
+            if (!(child.m_type &amp; ~SpecArray)) {
+                setConstant(node, jsBoolean(true));
+                constantWasSet = true;
+                break;
+            }
+
+            if (!(child.m_type &amp; SpecObject)) {
+                setConstant(node, jsBoolean(false));
+                constantWasSet = true;
+                break;
+            }
+
+            break;
</ins><span class="cx">         case IsUndefined:
</span><span class="cx">             // FIXME: Use the masquerades-as-undefined watchpoint thingy.
</span><span class="cx">             // https://bugs.webkit.org/show_bug.cgi?id=144456
</span><span class="lines">@@ -1779,7 +1821,21 @@
</span><span class="cx">         ASSERT(node-&gt;structure());
</span><span class="cx">         forNode(node).set(m_graph, node-&gt;structure());
</span><span class="cx">         break;
</span><del>-        
</del><ins>+
+    case CallObjectConstructor: {
+        AbstractValue&amp; source = forNode(node-&gt;child1());
+        AbstractValue&amp; destination = forNode(node);
+
+        if (!(source.m_type &amp; ~SpecObject)) {
+            m_state.setFoundConstants(true);
+            destination = source;
+            break;
+        }
+
+        forNode(node).setType(m_graph, SpecObject);
+        break;
+    }
+
</ins><span class="cx">     case PhantomNewObject:
</span><span class="cx">     case PhantomNewFunction:
</span><span class="cx">     case PhantomNewGeneratorFunction:
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoredfgDFGByteCodeParsercpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/dfg/DFGByteCodeParser.cpp (198807 => 198808)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/dfg/DFGByteCodeParser.cpp        2016-03-29 22:23:42 UTC (rev 198807)
+++ trunk/Source/JavaScriptCore/dfg/DFGByteCodeParser.cpp        2016-03-29 22:57:01 UTC (rev 198808)
</span><span class="lines">@@ -43,6 +43,7 @@
</span><span class="cx"> #include &quot;JSLexicalEnvironment.h&quot;
</span><span class="cx"> #include &quot;JSCInlines.h&quot;
</span><span class="cx"> #include &quot;JSModuleEnvironment.h&quot;
</span><ins>+#include &quot;ObjectConstructor.h&quot;
</ins><span class="cx"> #include &quot;PreciseJumpTargets.h&quot;
</span><span class="cx"> #include &quot;PutByIdFlags.h&quot;
</span><span class="cx"> #include &quot;PutByIdStatus.h&quot;
</span><span class="lines">@@ -2121,6 +2122,34 @@
</span><span class="cx">         }
</span><span class="cx">     }
</span><span class="cx"> 
</span><ins>+    case IsArrayIntrinsic: {
+        if (argumentCountIncludingThis != 2)
+            return false;
+
+        insertChecks();
+        Node* isArray = addToGraph(IsArrayObject, OpInfo(prediction), get(virtualRegisterForArgument(1, registerOffset)));
+        set(VirtualRegister(resultOperand), isArray);
+        return true;
+    }
+
+    case IsJSArrayIntrinsic: {
+        ASSERT(argumentCountIncludingThis == 2);
+
+        insertChecks();
+        Node* isArray = addToGraph(IsJSArray, OpInfo(prediction), get(virtualRegisterForArgument(1, registerOffset)));
+        set(VirtualRegister(resultOperand), isArray);
+        return true;
+    }
+
+    case IsArrayConstructorIntrinsic: {
+        ASSERT(argumentCountIncludingThis == 2);
+
+        insertChecks();
+        Node* isArray = addToGraph(IsArrayConstructor, OpInfo(prediction), get(virtualRegisterForArgument(1, registerOffset)));
+        set(VirtualRegister(resultOperand), isArray);
+        return true;
+    }
+
</ins><span class="cx">     case CharCodeAtIntrinsic: {
</span><span class="cx">         if (argumentCountIncludingThis != 2)
</span><span class="cx">             return false;
</span><span class="lines">@@ -2493,7 +2522,16 @@
</span><span class="cx">         set(VirtualRegister(resultOperand), result);
</span><span class="cx">         return true;
</span><span class="cx">     }
</span><del>-    
</del><ins>+
+    // FIXME: This should handle construction as well. https://bugs.webkit.org/show_bug.cgi?id=155591
+    if (function-&gt;classInfo() == ObjectConstructor::info() &amp;&amp; kind == CodeForCall) {
+        insertChecks();
+
+        Node* result = addToGraph(CallObjectConstructor, get(virtualRegisterForArgument(1, registerOffset)));
+        set(VirtualRegister(resultOperand), result);
+        return true;
+    }
+
</ins><span class="cx">     for (unsigned typeIndex = 0; typeIndex &lt; NUMBER_OF_TYPED_ARRAY_TYPES; ++typeIndex) {
</span><span class="cx">         bool result = handleTypedArrayConstructor(
</span><span class="cx">             resultOperand, function, registerOffset, argumentCountIncludingThis,
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoredfgDFGClobberizeh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/dfg/DFGClobberize.h (198807 => 198808)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/dfg/DFGClobberize.h        2016-03-29 22:23:42 UTC (rev 198807)
+++ trunk/Source/JavaScriptCore/dfg/DFGClobberize.h        2016-03-29 22:57:01 UTC (rev 198808)
</span><span class="lines">@@ -142,6 +142,8 @@
</span><span class="cx">     case GetGlobalObject:
</span><span class="cx">     case StringCharCodeAt:
</span><span class="cx">     case CompareStrictEq:
</span><ins>+    case IsJSArray:
+    case IsArrayConstructor:
</ins><span class="cx">     case IsUndefined:
</span><span class="cx">     case IsBoolean:
</span><span class="cx">     case IsNumber:
</span><span class="lines">@@ -181,7 +183,8 @@
</span><span class="cx">         read(MathDotRandomState);
</span><span class="cx">         write(MathDotRandomState);
</span><span class="cx">         return;
</span><del>-        
</del><ins>+
+    case IsArrayObject:
</ins><span class="cx">     case HasGenericProperty:
</span><span class="cx">     case HasStructureProperty:
</span><span class="cx">     case GetEnumerableLength:
</span><span class="lines">@@ -397,6 +400,7 @@
</span><span class="cx">         write(HeapObjectCount);
</span><span class="cx">         return;
</span><span class="cx"> 
</span><ins>+    case CallObjectConstructor:
</ins><span class="cx">     case ToThis:
</span><span class="cx">     case CreateThis:
</span><span class="cx">         read(MiscFields);
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoredfgDFGDoesGCcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/dfg/DFGDoesGC.cpp (198807 => 198808)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/dfg/DFGDoesGC.cpp        2016-03-29 22:23:42 UTC (rev 198807)
+++ trunk/Source/JavaScriptCore/dfg/DFGDoesGC.cpp        2016-03-29 22:57:01 UTC (rev 198808)
</span><span class="lines">@@ -149,6 +149,9 @@
</span><span class="cx">     case OverridesHasInstance:
</span><span class="cx">     case InstanceOf:
</span><span class="cx">     case InstanceOfCustom:
</span><ins>+    case IsArrayObject:
+    case IsJSArray:
+    case IsArrayConstructor:
</ins><span class="cx">     case IsUndefined:
</span><span class="cx">     case IsBoolean:
</span><span class="cx">     case IsNumber:
</span><span class="lines">@@ -238,6 +241,7 @@
</span><span class="cx">     case CreateDirectArguments:
</span><span class="cx">     case CreateScopedArguments:
</span><span class="cx">     case CreateClonedArguments:
</span><ins>+    case CallObjectConstructor:
</ins><span class="cx">     case ToThis:
</span><span class="cx">     case CreateThis:
</span><span class="cx">     case AllocatePropertyStorage:
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoredfgDFGFixupPhasecpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/dfg/DFGFixupPhase.cpp (198807 => 198808)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/dfg/DFGFixupPhase.cpp        2016-03-29 22:23:42 UTC (rev 198807)
+++ trunk/Source/JavaScriptCore/dfg/DFGFixupPhase.cpp        2016-03-29 22:57:01 UTC (rev 198808)
</span><span class="lines">@@ -1028,7 +1028,18 @@
</span><span class="cx">             fixEdge&lt;Int32Use&gt;(node-&gt;child1());
</span><span class="cx">             break;
</span><span class="cx">         }
</span><del>-            
</del><ins>+
+        case CallObjectConstructor: {
+            if (node-&gt;child1()-&gt;shouldSpeculateObject()) {
+                fixEdge&lt;ObjectUse&gt;(node-&gt;child1());
+                node-&gt;convertToIdentity();
+                break;
+            }
+
+            fixEdge&lt;UntypedUse&gt;(node-&gt;child1());
+            break;
+        }
+
</ins><span class="cx">         case ToThis: {
</span><span class="cx">             fixupToThis(node);
</span><span class="cx">             break;
</span><span class="lines">@@ -1488,6 +1499,9 @@
</span><span class="cx">         case NewRegexp:
</span><span class="cx">         case ProfileWillCall:
</span><span class="cx">         case ProfileDidCall:
</span><ins>+        case IsArrayObject:
+        case IsJSArray:
+        case IsArrayConstructor:
</ins><span class="cx">         case IsUndefined:
</span><span class="cx">         case IsBoolean:
</span><span class="cx">         case IsNumber:
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoredfgDFGNodeTypeh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/dfg/DFGNodeType.h (198807 => 198808)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/dfg/DFGNodeType.h        2016-03-29 22:23:42 UTC (rev 198807)
+++ trunk/Source/JavaScriptCore/dfg/DFGNodeType.h        2016-03-29 22:57:01 UTC (rev 198808)
</span><span class="lines">@@ -290,6 +290,11 @@
</span><span class="cx">     macro(OverridesHasInstance, NodeMustGenerate | NodeResultBoolean) \
</span><span class="cx">     macro(InstanceOf, NodeResultBoolean) \
</span><span class="cx">     macro(InstanceOfCustom, NodeMustGenerate | NodeResultBoolean) \
</span><ins>+    \
+    /* I'd like to call this IsArray but then we get namespace problems with the indexing type name. Also, it is marked must generate because it can throw. */ \
+    macro(IsArrayObject, NodeMustGenerate | NodeResultBoolean) \
+    macro(IsJSArray, NodeResultBoolean) \
+    macro(IsArrayConstructor, NodeResultBoolean) \
</ins><span class="cx">     macro(IsUndefined, NodeResultBoolean) \
</span><span class="cx">     macro(IsBoolean, NodeResultBoolean) \
</span><span class="cx">     macro(IsNumber, NodeResultBoolean) \
</span><span class="lines">@@ -301,6 +306,7 @@
</span><span class="cx">     macro(LogicalNot, NodeResultBoolean) \
</span><span class="cx">     macro(ToPrimitive, NodeResultJS | NodeMustGenerate) \
</span><span class="cx">     macro(ToString, NodeResultJS | NodeMustGenerate) \
</span><ins>+    macro(CallObjectConstructor, NodeResultJS) \
</ins><span class="cx">     macro(CallStringConstructor, NodeResultJS | NodeMustGenerate) \
</span><span class="cx">     macro(NewStringObject, NodeResultJS) \
</span><span class="cx">     macro(MakeRope, NodeResultJS) \
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoredfgDFGOperationscpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/dfg/DFGOperations.cpp (198807 => 198808)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/dfg/DFGOperations.cpp        2016-03-29 22:23:42 UTC (rev 198807)
+++ trunk/Source/JavaScriptCore/dfg/DFGOperations.cpp        2016-03-29 22:57:01 UTC (rev 198808)
</span><span class="lines">@@ -26,6 +26,7 @@
</span><span class="cx"> #include &quot;config.h&quot;
</span><span class="cx"> #include &quot;DFGOperations.h&quot;
</span><span class="cx"> 
</span><ins>+#include &quot;ArrayConstructor.h&quot;
</ins><span class="cx"> #include &quot;ButterflyInlines.h&quot;
</span><span class="cx"> #include &quot;ClonedArguments.h&quot;
</span><span class="cx"> #include &quot;CodeBlock.h&quot;
</span><span class="lines">@@ -176,6 +177,19 @@
</span><span class="cx">     return constructEmptyObject(exec);
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+JSCell* JIT_OPERATION operationObjectConstructor(ExecState* exec, JSGlobalObject* globalObject, EncodedJSValue encodedTarget)
+{
+    VM* vm = &amp;exec-&gt;vm();
+    NativeCallFrameTracer tracer(vm, exec);
+
+    JSValue value = JSValue::decode(encodedTarget);
+    ASSERT(!value.isObject());
+
+    if (value.isUndefinedOrNull())
+        return constructEmptyObject(exec, globalObject-&gt;objectPrototype());
+    return value.toObject(exec, globalObject);
+}
+
</ins><span class="cx"> EncodedJSValue JIT_OPERATION operationValueBitAnd(ExecState* exec, EncodedJSValue encodedOp1, EncodedJSValue encodedOp2)
</span><span class="cx"> {
</span><span class="cx">     VM* vm = &amp;exec-&gt;vm();
</span><span class="lines">@@ -710,6 +724,22 @@
</span><span class="cx">     return asRegExpObject(base)-&gt;test(exec, globalObject, input);
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+size_t JIT_OPERATION operationIsArrayConstructor(ExecState* exec, EncodedJSValue encodedTarget)
+{
+    VM&amp; vm = exec-&gt;vm();
+    NativeCallFrameTracer tracer(&amp;vm, exec);
+
+    return isArrayConstructor(JSValue::decode(encodedTarget));
+}
+
+size_t JIT_OPERATION operationIsArrayObject(ExecState* exec, EncodedJSValue encodedTarget)
+{
+    VM&amp; vm = exec-&gt;vm();
+    NativeCallFrameTracer tracer(&amp;vm, exec);
+
+    return isArray(exec, JSValue::decode(encodedTarget));
+}
+
</ins><span class="cx"> size_t JIT_OPERATION operationCompareStrictEqCell(ExecState* exec, EncodedJSValue encodedOp1, EncodedJSValue encodedOp2)
</span><span class="cx"> {
</span><span class="cx">     VM* vm = &amp;exec-&gt;vm();
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoredfgDFGOperationsh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/dfg/DFGOperations.h (198807 => 198808)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/dfg/DFGOperations.h        2016-03-29 22:23:42 UTC (rev 198807)
+++ trunk/Source/JavaScriptCore/dfg/DFGOperations.h        2016-03-29 22:57:01 UTC (rev 198808)
</span><span class="lines">@@ -41,6 +41,7 @@
</span><span class="cx"> EncodedJSValue JIT_OPERATION operationStringFromCharCodeUntyped(ExecState*, EncodedJSValue)  WTF_INTERNAL;
</span><span class="cx"> 
</span><span class="cx"> // These routines are provide callbacks out to C++ implementations of operations too complex to JIT.
</span><ins>+JSCell* JIT_OPERATION operationObjectConstructor(ExecState*, JSGlobalObject*, EncodedJSValue encodedTarget) WTF_INTERNAL;
</ins><span class="cx"> JSCell* JIT_OPERATION operationCreateThis(ExecState*, JSObject* constructor, int32_t inlineCapacity) WTF_INTERNAL;
</span><span class="cx"> EncodedJSValue JIT_OPERATION operationToThis(ExecState*, EncodedJSValue encodedOp1) WTF_INTERNAL;
</span><span class="cx"> EncodedJSValue JIT_OPERATION operationToThisStrict(ExecState*, EncodedJSValue encodedOp1) WTF_INTERNAL;
</span><span class="lines">@@ -110,6 +111,8 @@
</span><span class="cx"> size_t JIT_OPERATION operationRegExpTestGeneric(ExecState*, JSGlobalObject*, EncodedJSValue, EncodedJSValue) WTF_INTERNAL;
</span><span class="cx"> size_t JIT_OPERATION operationCompareStrictEqCell(ExecState*, EncodedJSValue encodedOp1, EncodedJSValue encodedOp2) WTF_INTERNAL;
</span><span class="cx"> size_t JIT_OPERATION operationCompareStrictEq(ExecState*, EncodedJSValue encodedOp1, EncodedJSValue encodedOp2) WTF_INTERNAL;
</span><ins>+size_t JIT_OPERATION operationIsArrayConstructor(ExecState*, EncodedJSValue);
+size_t JIT_OPERATION operationIsArrayObject(ExecState*, EncodedJSValue);
</ins><span class="cx"> JSCell* JIT_OPERATION operationCreateActivationDirect(ExecState*, Structure*, JSScope*, SymbolTable*, EncodedJSValue);
</span><span class="cx"> JSCell* JIT_OPERATION operationCreateDirectArguments(ExecState*, Structure*, int32_t length, int32_t minCapacity);
</span><span class="cx"> JSCell* JIT_OPERATION operationCreateDirectArgumentsDuringExit(ExecState*, InlineCallFrame*, JSFunction*, int32_t argumentCount);
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoredfgDFGPredictionPropagationPhasecpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/dfg/DFGPredictionPropagationPhase.cpp (198807 => 198808)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/dfg/DFGPredictionPropagationPhase.cpp        2016-03-29 22:23:42 UTC (rev 198807)
+++ trunk/Source/JavaScriptCore/dfg/DFGPredictionPropagationPhase.cpp        2016-03-29 22:57:01 UTC (rev 198808)
</span><span class="lines">@@ -417,6 +417,9 @@
</span><span class="cx">         case OverridesHasInstance:
</span><span class="cx">         case InstanceOf:
</span><span class="cx">         case InstanceOfCustom:
</span><ins>+        case IsArrayObject:
+        case IsJSArray:
+        case IsArrayConstructor:
</ins><span class="cx">         case IsUndefined:
</span><span class="cx">         case IsBoolean:
</span><span class="cx">         case IsNumber:
</span><span class="lines">@@ -490,6 +493,11 @@
</span><span class="cx">             break;
</span><span class="cx">         }
</span><span class="cx"> 
</span><ins>+        case CallObjectConstructor: {
+            changed |= setPrediction(SpecObject);
+            break;
+        }
+
</ins><span class="cx">         case ToThis: {
</span><span class="cx">             // ToThis in methods for primitive types should speculate primitive types in strict mode.
</span><span class="cx">             ECMAMode ecmaMode = m_graph.executableFor(node-&gt;origin.semantic)-&gt;isStrictMode() ? StrictMode : NotStrictMode;
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoredfgDFGSafeToExecuteh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/dfg/DFGSafeToExecute.h (198807 => 198808)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/dfg/DFGSafeToExecute.h        2016-03-29 22:23:42 UTC (rev 198807)
+++ trunk/Source/JavaScriptCore/dfg/DFGSafeToExecute.h        2016-03-29 22:57:01 UTC (rev 198808)
</span><span class="lines">@@ -250,6 +250,9 @@
</span><span class="cx">     case OverridesHasInstance:
</span><span class="cx">     case InstanceOf:
</span><span class="cx">     case InstanceOfCustom:
</span><ins>+    case IsArrayObject:
+    case IsJSArray:
+    case IsArrayConstructor:
</ins><span class="cx">     case IsUndefined:
</span><span class="cx">     case IsBoolean:
</span><span class="cx">     case IsNumber:
</span><span class="lines">@@ -259,6 +262,7 @@
</span><span class="cx">     case IsFunction:
</span><span class="cx">     case TypeOf:
</span><span class="cx">     case LogicalNot:
</span><ins>+    case CallObjectConstructor:
</ins><span class="cx">     case ToPrimitive:
</span><span class="cx">     case ToString:
</span><span class="cx">     case SetFunctionName:
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoredfgDFGSpeculativeJITcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/dfg/DFGSpeculativeJIT.cpp (198807 => 198808)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/dfg/DFGSpeculativeJIT.cpp        2016-03-29 22:23:42 UTC (rev 198807)
+++ trunk/Source/JavaScriptCore/dfg/DFGSpeculativeJIT.cpp        2016-03-29 22:57:01 UTC (rev 198808)
</span><span class="lines">@@ -1503,7 +1503,7 @@
</span><span class="cx">             dataLog(&quot;\n&quot;);
</span><span class="cx">         }
</span><span class="cx"> 
</span><del>-        if (Options::validateDFGExceptionHandling() &amp;&amp; mayExit(m_jit.graph(), m_currentNode) != DoesNotExit)
</del><ins>+        if (Options::validateDFGExceptionHandling() &amp;&amp; (mayExit(m_jit.graph(), m_currentNode) != DoesNotExit || m_currentNode-&gt;isTerminal()))
</ins><span class="cx">             m_jit.jitReleaseAssertNoException();
</span><span class="cx"> 
</span><span class="cx">         m_jit.pcToCodeOriginMapBuilder().appendItem(m_jit.label(), m_origin.semantic);
</span><span class="lines">@@ -3248,6 +3248,98 @@
</span><span class="cx">     unblessedBooleanResult(resultGPR, node);
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+void SpeculativeJIT::compileIsJSArray(Node* node)
+{
+    JSValueOperand value(this, node-&gt;child1());
+    GPRFlushedCallResult result(this);
+
+    JSValueRegs valueRegs = value.jsValueRegs();
+    GPRReg resultGPR = result.gpr();
+
+    JITCompiler::Jump isNotCell = m_jit.branchIfNotCell(valueRegs);
+
+    m_jit.compare8(JITCompiler::Equal,
+        JITCompiler::Address(valueRegs.payloadGPR(), JSCell::typeInfoTypeOffset()),
+        TrustedImm32(ArrayType),
+        resultGPR);
+    blessBoolean(resultGPR);
+    JITCompiler::Jump done = m_jit.jump();
+
+    isNotCell.link(&amp;m_jit);
+    moveFalseTo(resultGPR);
+
+    done.link(&amp;m_jit);
+    blessedBooleanResult(resultGPR, node);
+}
+
+void SpeculativeJIT::compileIsArrayObject(Node* node)
+{
+    JSValueOperand value(this, node-&gt;child1());
+    GPRFlushedCallResult result(this);
+
+    JSValueRegs valueRegs = value.jsValueRegs();
+    GPRReg resultGPR = result.gpr();
+
+    JITCompiler::JumpList done;
+
+    JITCompiler::Jump isNotCell = m_jit.branchIfNotCell(valueRegs);
+
+    JITCompiler::Jump notJSArray = m_jit.branch8(JITCompiler::NotEqual,
+        JITCompiler::Address(valueRegs.payloadGPR(), JSCell::typeInfoTypeOffset()),
+        TrustedImm32(ArrayType));
+    m_jit.move(TrustedImm32(true), resultGPR);
+    done.append(m_jit.jump());
+
+    notJSArray.link(&amp;m_jit);
+    silentSpillAllRegisters(resultGPR);
+    callOperation(operationIsArrayObject, resultGPR, valueRegs);
+    silentFillAllRegisters(resultGPR);
+    m_jit.exceptionCheck();
+    done.append(m_jit.jump());
+
+    isNotCell.link(&amp;m_jit);
+    m_jit.move(TrustedImm32(false), resultGPR);
+
+    done.link(&amp;m_jit);
+    unblessedBooleanResult(resultGPR, node);
+}
+
+// FIXME: This function should just get the ClassInfo and check if it's == ArrayConstructor::info(). https://bugs.webkit.org/show_bug.cgi?id=155667
+void SpeculativeJIT::compileIsArrayConstructor(Node* node)
+{
+    JSValueOperand value(this, node-&gt;child1());
+    GPRFlushedCallResult result(this);
+
+    JSValueRegs valueRegs = value.jsValueRegs();
+    GPRReg resultGPR = result.gpr();
+
+    flushRegisters();
+    callOperation(operationIsArrayConstructor, resultGPR, valueRegs);
+    unblessedBooleanResult(resultGPR, node);
+}
+
+void SpeculativeJIT::compileCallObjectConstructor(Node* node)
+{
+    RELEASE_ASSERT(node-&gt;child1().useKind() == UntypedUse);
+    JSValueOperand value(this, node-&gt;child1());
+#if USE(JSVALUE64)
+    GPRTemporary result(this, Reuse, value);
+#else
+    GPRTemporary result(this, Reuse, value, PayloadWord);
+#endif
+
+    JSValueRegs valueRegs = value.jsValueRegs();
+    GPRReg resultGPR = result.gpr();
+
+    MacroAssembler::JumpList slowCases;
+    slowCases.append(m_jit.branchIfNotCell(valueRegs));
+    slowCases.append(m_jit.branchIfNotObject(valueRegs.payloadGPR()));
+    m_jit.move(valueRegs.payloadGPR(), resultGPR);
+
+    addSlowPathGenerator(slowPathCall(slowCases, this, operationObjectConstructor, resultGPR, m_jit.globalObjectFor(node-&gt;origin.semantic), valueRegs));
+    cellResult(resultGPR, node);
+}
+
</ins><span class="cx"> void SpeculativeJIT::compileArithAdd(Node* node)
</span><span class="cx"> {
</span><span class="cx">     switch (node-&gt;binaryUseKind()) {
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoredfgDFGSpeculativeJITh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/dfg/DFGSpeculativeJIT.h (198807 => 198808)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/dfg/DFGSpeculativeJIT.h        2016-03-29 22:23:42 UTC (rev 198807)
+++ trunk/Source/JavaScriptCore/dfg/DFGSpeculativeJIT.h        2016-03-29 22:57:01 UTC (rev 198808)
</span><span class="lines">@@ -729,6 +729,10 @@
</span><span class="cx">     void compileInstanceOfForObject(Node*, GPRReg valueReg, GPRReg prototypeReg, GPRReg scratchAndResultReg, GPRReg scratch2Reg);
</span><span class="cx">     void compileInstanceOf(Node*);
</span><span class="cx">     void compileInstanceOfCustom(Node*);
</span><ins>+
+    void compileIsJSArray(Node*);
+    void compileIsArrayConstructor(Node*);
+    void compileIsArrayObject(Node*);
</ins><span class="cx">     
</span><span class="cx">     void emitCall(Node*);
</span><span class="cx">     
</span><span class="lines">@@ -1392,6 +1396,17 @@
</span><span class="cx">         return appendCallSetResult(operation, result);
</span><span class="cx">     }
</span><span class="cx"> 
</span><ins>+    JITCompiler::Call callOperation(C_JITOperation_EGJ operation, GPRReg result, JSGlobalObject* globalObject, GPRReg arg1)
+    {
+        m_jit.setupArgumentsWithExecState(TrustedImmPtr(globalObject), arg1);
+        return appendCallSetResult(operation, result);
+    }
+
+    JITCompiler::Call callOperation(C_JITOperation_EGJ operation, GPRReg result, JSGlobalObject* globalObject, JSValueRegs arg1)
+    {
+        return callOperation(operation, result, globalObject, arg1.gpr());
+    }
+
</ins><span class="cx">     JITCompiler::Call callOperation(C_JITOperation_EJ operation, GPRReg result, GPRReg arg1)
</span><span class="cx">     {
</span><span class="cx">         m_jit.setupArgumentsWithExecState(arg1);
</span><span class="lines">@@ -1432,10 +1447,18 @@
</span><span class="cx">         m_jit.setupArgumentsWithExecState(arg1);
</span><span class="cx">         return appendCallSetResult(operation, result);
</span><span class="cx">     }
</span><ins>+    JITCompiler::Call callOperation(S_JITOperation_EJ operation, GPRReg result, JSValueRegs arg1)
+    {
+        return callOperation(operation, result, arg1.gpr());
+    }
</ins><span class="cx">     JITCompiler::Call callOperation(J_JITOperation_EJ operation, JSValueRegs result, JSValueRegs arg1)
</span><span class="cx">     {
</span><span class="cx">         return callOperation(operation, result.payloadGPR(), arg1.payloadGPR());
</span><span class="cx">     }
</span><ins>+    JITCompiler::Call callOperation(J_JITOperation_EJ operation, GPRReg result, JSValueRegs arg1)
+    {
+        return callOperation(operation, result, arg1.payloadGPR());
+    }
</ins><span class="cx">     JITCompiler::Call callOperation(J_JITOperation_EJ operation, GPRReg result, GPRReg arg1)
</span><span class="cx">     {
</span><span class="cx">         m_jit.setupArgumentsWithExecState(arg1);
</span><span class="lines">@@ -1815,6 +1838,17 @@
</span><span class="cx">         return appendCallSetResult(operation, result);
</span><span class="cx">     }
</span><span class="cx"> 
</span><ins>+    JITCompiler::Call callOperation(C_JITOperation_EGJ operation, GPRReg result, JSGlobalObject* globalObject, GPRReg arg1Tag, GPRReg arg1Payload)
+    {
+        m_jit.setupArgumentsWithExecState(TrustedImmPtr(globalObject), arg1Payload, arg1Tag);
+        return appendCallSetResult(operation, result);
+    }
+
+    JITCompiler::Call callOperation(C_JITOperation_EGJ operation, GPRReg result, JSGlobalObject* globalObject, JSValueRegs arg1)
+    {
+        return callOperation(operation, result, globalObject, arg1.payloadGPR(), arg1.tagGPR());
+    }
+
</ins><span class="cx">     JITCompiler::Call callOperation(C_JITOperation_EJ operation, GPRReg result, GPRReg arg1Tag, GPRReg arg1Payload)
</span><span class="cx">     {
</span><span class="cx">         m_jit.setupArgumentsWithExecState(EABI_32BIT_DUMMY_ARG arg1Payload, arg1Tag);
</span><span class="lines">@@ -1839,6 +1873,11 @@
</span><span class="cx">         return appendCallSetResult(operation, result);
</span><span class="cx">     }
</span><span class="cx"> 
</span><ins>+    JITCompiler::Call callOperation(S_JITOperation_EJ operation, GPRReg result, JSValueRegs arg1)
+    {
+        return callOperation(operation, result, arg1.tagGPR(), arg1.payloadGPR());
+    }
+
</ins><span class="cx">     JITCompiler::Call callOperation(S_JITOperation_EJJ operation, GPRReg result, GPRReg arg1Tag, GPRReg arg1Payload, GPRReg arg2Tag, GPRReg arg2Payload)
</span><span class="cx">     {
</span><span class="cx">         m_jit.setupArgumentsWithExecState(EABI_32BIT_DUMMY_ARG arg1Payload, arg1Tag, SH4_32BIT_DUMMY_ARG arg2Payload, arg2Tag);
</span><span class="lines">@@ -2412,7 +2451,9 @@
</span><span class="cx">     void compileGetRegExpObjectLastIndex(Node*);
</span><span class="cx">     void compileSetRegExpObjectLastIndex(Node*);
</span><span class="cx">     void compileLazyJSConstant(Node*);
</span><del>-    
</del><ins>+
+    void compileCallObjectConstructor(Node*);
+
</ins><span class="cx">     void moveTrueTo(GPRReg);
</span><span class="cx">     void moveFalseTo(GPRReg);
</span><span class="cx">     void blessBoolean(GPRReg);
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoredfgDFGSpeculativeJIT32_64cpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/dfg/DFGSpeculativeJIT32_64.cpp (198807 => 198808)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/dfg/DFGSpeculativeJIT32_64.cpp        2016-03-29 22:23:42 UTC (rev 198807)
+++ trunk/Source/JavaScriptCore/dfg/DFGSpeculativeJIT32_64.cpp        2016-03-29 22:57:01 UTC (rev 198808)
</span><span class="lines">@@ -3807,6 +3807,11 @@
</span><span class="cx">         cellResult(resultPayload.gpr(), node);
</span><span class="cx">         break;
</span><span class="cx">     }
</span><ins>+
+    case CallObjectConstructor: {
+        compileCallObjectConstructor(node);
+        break;
+    }
</ins><span class="cx">         
</span><span class="cx">     case ToThis: {
</span><span class="cx">         ASSERT(node-&gt;child1().useKind() == UntypedUse);
</span><span class="lines">@@ -4458,6 +4463,21 @@
</span><span class="cx">         break;
</span><span class="cx">     }
</span><span class="cx"> 
</span><ins>+    case IsJSArray: {
+        compileIsJSArray(node);
+        break;
+    }
+
+    case IsArrayObject: {
+        compileIsArrayObject(node);
+        break;
+    }
+
+    case IsArrayConstructor: {
+        compileIsArrayConstructor(node);
+        break;
+    }
+
</ins><span class="cx">     case IsObject: {
</span><span class="cx">         JSValueOperand value(this, node-&gt;child1());
</span><span class="cx">         GPRTemporary result(this, Reuse, value, TagWord);
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoredfgDFGSpeculativeJIT64cpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/dfg/DFGSpeculativeJIT64.cpp (198807 => 198808)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/dfg/DFGSpeculativeJIT64.cpp        2016-03-29 22:23:42 UTC (rev 198807)
+++ trunk/Source/JavaScriptCore/dfg/DFGSpeculativeJIT64.cpp        2016-03-29 22:57:01 UTC (rev 198808)
</span><span class="lines">@@ -3871,7 +3871,12 @@
</span><span class="cx">         cellResult(result.gpr(), node);
</span><span class="cx">         break;
</span><span class="cx">     }
</span><del>-        
</del><ins>+
+    case CallObjectConstructor: {
+        compileCallObjectConstructor(node);
+        break;
+    }
+
</ins><span class="cx">     case ToThis: {
</span><span class="cx">         ASSERT(node-&gt;child1().useKind() == UntypedUse);
</span><span class="cx">         JSValueOperand thisValue(this, node-&gt;child1());
</span><span class="lines">@@ -4474,6 +4479,21 @@
</span><span class="cx">         break;
</span><span class="cx">     }
</span><span class="cx"> 
</span><ins>+    case IsJSArray: {
+        compileIsJSArray(node);
+        break;
+    }
+
+    case IsArrayObject: {
+        compileIsArrayObject(node);
+        break;
+    }
+
+    case IsArrayConstructor: {
+        compileIsArrayConstructor(node);
+        break;
+    }
+
</ins><span class="cx">     case IsObject: {
</span><span class="cx">         JSValueOperand value(this, node-&gt;child1());
</span><span class="cx">         GPRTemporary result(this, Reuse, value);
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreftlFTLCapabilitiescpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/ftl/FTLCapabilities.cpp (198807 => 198808)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/ftl/FTLCapabilities.cpp        2016-03-29 22:23:42 UTC (rev 198807)
+++ trunk/Source/JavaScriptCore/ftl/FTLCapabilities.cpp        2016-03-29 22:57:01 UTC (rev 198808)
</span><span class="lines">@@ -161,6 +161,7 @@
</span><span class="cx">     case GetScope:
</span><span class="cx">     case GetCallee:
</span><span class="cx">     case GetArgumentCount:
</span><ins>+    case CallObjectConstructor:
</ins><span class="cx">     case ToString:
</span><span class="cx">     case CallStringConstructor:
</span><span class="cx">     case MakeRope:
</span><span class="lines">@@ -174,6 +175,9 @@
</span><span class="cx">     case Throw:
</span><span class="cx">     case ThrowReferenceError:
</span><span class="cx">     case Unreachable:
</span><ins>+    case IsArrayObject:
+    case IsJSArray:
+    case IsArrayConstructor:
</ins><span class="cx">     case IsUndefined:
</span><span class="cx">     case IsBoolean:
</span><span class="cx">     case IsNumber:
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreftlFTLLowerDFGToB3cpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/ftl/FTLLowerDFGToB3.cpp (198807 => 198808)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/ftl/FTLLowerDFGToB3.cpp        2016-03-29 22:23:42 UTC (rev 198807)
+++ trunk/Source/JavaScriptCore/ftl/FTLLowerDFGToB3.cpp        2016-03-29 22:57:01 UTC (rev 198808)
</span><span class="lines">@@ -479,6 +479,9 @@
</span><span class="cx">         case DFG::Check:
</span><span class="cx">             compileNoOp();
</span><span class="cx">             break;
</span><ins>+        case CallObjectConstructor:
+            compileCallObjectConstructor();
+            break;
</ins><span class="cx">         case ToThis:
</span><span class="cx">             compileToThis();
</span><span class="cx">             break;
</span><span class="lines">@@ -842,6 +845,15 @@
</span><span class="cx">         case IsString:
</span><span class="cx">             compileIsString();
</span><span class="cx">             break;
</span><ins>+        case IsArrayObject:
+            compileIsArrayObject();
+            break;
+        case IsJSArray:
+            compileIsJSArray();
+            break;
+        case IsArrayConstructor:
+            compileIsArrayConstructor();
+            break;
</ins><span class="cx">         case IsObject:
</span><span class="cx">             compileIsObject();
</span><span class="cx">             break;
</span><span class="lines">@@ -1397,6 +1409,28 @@
</span><span class="cx">     {
</span><span class="cx">         DFG_NODE_DO_TO_CHILDREN(m_graph, m_node, speculate);
</span><span class="cx">     }
</span><ins>+
+    void compileCallObjectConstructor()
+    {
+        LValue value = lowJSValue(m_node-&gt;child1());
+
+        LBasicBlock isCellCase = m_out.newBlock();
+        LBasicBlock slowCase = m_out.newBlock();
+        LBasicBlock continuation = m_out.newBlock();
+
+        m_out.branch(isCell(value, provenType(m_node-&gt;child1())), usually(isCellCase), rarely(slowCase));
+
+        LBasicBlock lastNext = m_out.appendTo(isCellCase, slowCase);
+        ValueFromBlock fastResult = m_out.anchor(value);
+        m_out.branch(isObject(value), usually(continuation), rarely(slowCase));
+
+        m_out.appendTo(slowCase, continuation);
+        ValueFromBlock slowResult = m_out.anchor(vmCall(m_out.int64, m_out.operation(operationToObject), m_callFrame, value));
+        m_out.jump(continuation);
+
+        m_out.appendTo(continuation, lastNext);
+        setJSValue(m_out.phi(m_out.int64, fastResult, slowResult));
+    }
</ins><span class="cx">     
</span><span class="cx">     void compileToThis()
</span><span class="cx">     {
</span><span class="lines">@@ -5692,6 +5726,55 @@
</span><span class="cx">         setBoolean(m_out.phi(m_out.boolean, notCellResult, cellResult));
</span><span class="cx">     }
</span><span class="cx"> 
</span><ins>+    void compileIsArrayObject()
+    {
+        LValue value = lowJSValue(m_node-&gt;child1());
+
+        LBasicBlock cellCase = m_out.newBlock();
+        LBasicBlock notArrayCase = m_out.newBlock();
+        LBasicBlock continuation = m_out.newBlock();
+
+        ValueFromBlock notCellResult = m_out.anchor(m_out.booleanFalse);
+        m_out.branch(isCell(value, provenType(m_node-&gt;child1())), unsure(cellCase), unsure(continuation));
+
+        LBasicBlock lastNext = m_out.appendTo(cellCase, notArrayCase);
+        ValueFromBlock arrayResult = m_out.anchor(m_out.booleanTrue);
+        m_out.branch(isArray(value, provenType(m_node-&gt;child1())), unsure(continuation), unsure(notArrayCase));
+
+        m_out.appendTo(notArrayCase, continuation);
+        ValueFromBlock notArrayResult = m_out.anchor(vmCall(m_out.boolean, m_out.operation(operationIsArrayObject), m_callFrame, value));
+        m_out.jump(continuation);
+
+        m_out.appendTo(continuation, lastNext);
+        setBoolean(m_out.phi(m_out.boolean, notCellResult, arrayResult, notArrayResult));
+    }
+
+    void compileIsJSArray()
+    {
+        LValue value = lowJSValue(m_node-&gt;child1());
+
+        LBasicBlock isCellCase = m_out.newBlock();
+        LBasicBlock continuation = m_out.newBlock();
+
+        ValueFromBlock notCellResult = m_out.anchor(m_out.booleanFalse);
+        m_out.branch(
+            isCell(value, provenType(m_node-&gt;child1())), unsure(isCellCase), unsure(continuation));
+
+        LBasicBlock lastNext = m_out.appendTo(isCellCase, continuation);
+        ValueFromBlock cellResult = m_out.anchor(isArray(value, provenType(m_node-&gt;child1())));
+        m_out.jump(continuation);
+
+        m_out.appendTo(continuation, lastNext);
+        setBoolean(m_out.phi(m_out.boolean, notCellResult, cellResult));
+    }
+
+    void compileIsArrayConstructor()
+    {
+        LValue value = lowJSValue(m_node-&gt;child1());
+
+        setBoolean(vmCall(m_out.boolean, m_out.operation(operationIsArrayConstructor), m_callFrame, value));
+    }
+
</ins><span class="cx">     void compileIsObject()
</span><span class="cx">     {
</span><span class="cx">         LValue value = lowJSValue(m_node-&gt;child1());
</span><span class="lines">@@ -9459,6 +9542,15 @@
</span><span class="cx">         
</span><span class="cx">         jsValueToStrictInt52(edge, lowJSValue(edge, ManualOperandSpeculation));
</span><span class="cx">     }
</span><ins>+
+    LValue isArray(LValue cell, SpeculatedType type = SpecFullTop)
+    {
+        if (LValue proven = isProvenValue(type &amp; SpecCell, SpecArray))
+            return proven;
+        return m_out.equal(
+            m_out.load8ZeroExt32(cell, m_heaps.JSCell_typeInfoType),
+            m_out.constInt32(ArrayType));
+    }
</ins><span class="cx">     
</span><span class="cx">     LValue isObject(LValue cell, SpeculatedType type = SpecFullTop)
</span><span class="cx">     {
</span></span></pre></div>
<a id="trunkSourceJavaScriptCorejitJITOperationsh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/jit/JITOperations.h (198807 => 198808)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/jit/JITOperations.h        2016-03-29 22:23:42 UTC (rev 198807)
+++ trunk/Source/JavaScriptCore/jit/JITOperations.h        2016-03-29 22:57:01 UTC (rev 198808)
</span><span class="lines">@@ -163,6 +163,7 @@
</span><span class="cx"> typedef JSCell* JIT_OPERATION (*C_JITOperation_ECZC)(ExecState*, JSCell*, int32_t, JSCell*);
</span><span class="cx"> typedef JSCell* JIT_OPERATION (*C_JITOperation_ECC)(ExecState*, JSCell*, JSCell*);
</span><span class="cx"> typedef JSCell* JIT_OPERATION (*C_JITOperation_EGC)(ExecState*, JSGlobalObject*, JSCell*);
</span><ins>+typedef JSCell* JIT_OPERATION (*C_JITOperation_EGJ)(ExecState*, JSGlobalObject*, EncodedJSValue);
</ins><span class="cx"> typedef JSCell* JIT_OPERATION (*C_JITOperation_EIcf)(ExecState*, InlineCallFrame*);
</span><span class="cx"> typedef JSCell* JIT_OPERATION (*C_JITOperation_EJ)(ExecState*, EncodedJSValue);
</span><span class="cx"> typedef JSCell* JIT_OPERATION (*C_JITOperation_EJsc)(ExecState*, JSScope*);
</span></span></pre></div>
<a id="trunkSourceJavaScriptCorejsccpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/jsc.cpp (198807 => 198808)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/jsc.cpp        2016-03-29 22:23:42 UTC (rev 198807)
+++ trunk/Source/JavaScriptCore/jsc.cpp        2016-03-29 22:57:01 UTC (rev 198808)
</span><span class="lines">@@ -437,7 +437,7 @@
</span><span class="cx"> 
</span><span class="cx">     static Structure* createStructure(VM&amp; vm, JSGlobalObject* globalObject, JSValue prototype)
</span><span class="cx">     {
</span><del>-        return Structure::create(vm, globalObject, prototype, TypeInfo(ObjectType, StructureFlags), info(), ArrayClass);
</del><ins>+        return Structure::create(vm, globalObject, prototype, TypeInfo(ArrayType, StructureFlags), info(), ArrayClass);
</ins><span class="cx">     }
</span><span class="cx"> 
</span><span class="cx"> protected:
</span><span class="lines">@@ -558,6 +558,7 @@
</span><span class="cx"> static EncodedJSValue JSC_HOST_CALL functionSetHiddenValue(ExecState*);
</span><span class="cx"> static EncodedJSValue JSC_HOST_CALL functionPrint(ExecState*);
</span><span class="cx"> static EncodedJSValue JSC_HOST_CALL functionDebug(ExecState*);
</span><ins>+static EncodedJSValue JSC_HOST_CALL functionDataLogValue(ExecState*);
</ins><span class="cx"> static EncodedJSValue JSC_HOST_CALL functionDescribe(ExecState*);
</span><span class="cx"> static EncodedJSValue JSC_HOST_CALL functionDescribeArray(ExecState*);
</span><span class="cx"> static EncodedJSValue JSC_HOST_CALL functionJSCStack(ExecState*);
</span><span class="lines">@@ -723,7 +724,8 @@
</span><span class="cx">     void finishCreation(VM&amp; vm, const Vector&lt;String&gt;&amp; arguments)
</span><span class="cx">     {
</span><span class="cx">         Base::finishCreation(vm);
</span><del>-        
</del><ins>+
+        addFunction(vm, &quot;dataLogValue&quot;, functionDataLogValue, 1);
</ins><span class="cx">         addFunction(vm, &quot;debug&quot;, functionDebug, 1);
</span><span class="cx">         addFunction(vm, &quot;describe&quot;, functionDescribe, 1);
</span><span class="cx">         addFunction(vm, &quot;describeArray&quot;, functionDescribeArray, 1);
</span><span class="lines">@@ -821,6 +823,7 @@
</span><span class="cx">         }
</span><span class="cx"> 
</span><span class="cx">         putDirect(vm, Identifier::fromString(globalExec(), &quot;console&quot;), jsUndefined());
</span><ins>+        putDirect(vm, vm.propertyNames-&gt;printPrivateName, JSFunction::create(vm, this, 1, vm.propertyNames-&gt;printPrivateName.string(), functionPrint));
</ins><span class="cx">     }
</span><span class="cx"> 
</span><span class="cx">     void addFunction(VM&amp; vm, const char* name, NativeFunction function, unsigned arguments)
</span><span class="lines">@@ -1120,6 +1123,12 @@
</span><span class="cx">     return JSValue::encode(jsUndefined());
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+EncodedJSValue JSC_HOST_CALL functionDataLogValue(ExecState* exec)
+{
+    dataLog(&quot;value is: &quot;, exec-&gt;argument(0), &quot;\n&quot;);
+    return JSValue::encode(jsUndefined());
+}
+
</ins><span class="cx"> EncodedJSValue JSC_HOST_CALL functionDescribe(ExecState* exec)
</span><span class="cx"> {
</span><span class="cx">     if (exec-&gt;argumentCount() &lt; 1)
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreruntimeArrayConstructorcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/runtime/ArrayConstructor.cpp (198807 => 198808)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/runtime/ArrayConstructor.cpp        2016-03-29 22:23:42 UTC (rev 198807)
+++ trunk/Source/JavaScriptCore/runtime/ArrayConstructor.cpp        2016-03-29 22:57:01 UTC (rev 198808)
</span><span class="lines">@@ -68,7 +68,7 @@
</span><span class="cx">     putDirectWithoutTransition(vm, vm.propertyNames-&gt;prototype, arrayPrototype, DontEnum | DontDelete | ReadOnly);
</span><span class="cx">     putDirectWithoutTransition(vm, vm.propertyNames-&gt;length, jsNumber(1), ReadOnly | DontEnum | DontDelete);
</span><span class="cx">     putDirectNonIndexAccessor(vm, vm.propertyNames-&gt;speciesSymbol, speciesSymbol, Accessor | ReadOnly | DontEnum);
</span><del>-    JSC_NATIVE_FUNCTION_WITHOUT_TRANSITION(vm.propertyNames-&gt;isArray, arrayConstructorIsArray, DontEnum, 1);
</del><ins>+    JSC_NATIVE_INTRINSIC_FUNCTION_WITHOUT_TRANSITION(vm.propertyNames-&gt;isArray, arrayConstructorIsArray, DontEnum, 1, IsArrayIntrinsic);
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> bool ArrayConstructor::getOwnPropertySlot(JSObject* object, ExecState* exec, PropertyName propertyName, PropertySlot &amp;slot)
</span><span class="lines">@@ -135,7 +135,7 @@
</span><span class="cx"> 
</span><span class="cx"> EncodedJSValue JSC_HOST_CALL arrayConstructorPrivateFuncIsArrayConstructor(ExecState* exec)
</span><span class="cx"> {
</span><del>-    return JSValue::encode(jsBoolean(jsDynamicCast&lt;ArrayConstructor*&gt;(exec-&gt;uncheckedArgument(0))));
</del><ins>+    return JSValue::encode(jsBoolean(isArrayConstructor(exec-&gt;uncheckedArgument(0))));
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> } // namespace JSC
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreruntimeArrayConstructorh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/runtime/ArrayConstructor.h (198807 => 198808)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/runtime/ArrayConstructor.h        2016-03-29 22:23:42 UTC (rev 198807)
+++ trunk/Source/JavaScriptCore/runtime/ArrayConstructor.h        2016-03-29 22:57:01 UTC (rev 198808)
</span><span class="lines">@@ -91,6 +91,14 @@
</span><span class="cx">     ASSERT_NOT_REACHED();
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+inline bool isArrayConstructor(JSValue argumentValue)
+{
+    if (!argumentValue.isObject())
+        return false;
+
+    return jsCast&lt;JSObject*&gt;(argumentValue)-&gt;classInfo() == ArrayConstructor::info();
+}
+
</ins><span class="cx"> } // namespace JSC
</span><span class="cx"> 
</span><span class="cx"> #endif // ArrayConstructor_h
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreruntimeArrayPrototypecpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/runtime/ArrayPrototype.cpp (198807 => 198808)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/runtime/ArrayPrototype.cpp        2016-03-29 22:23:42 UTC (rev 198807)
+++ trunk/Source/JavaScriptCore/runtime/ArrayPrototype.cpp        2016-03-29 22:57:01 UTC (rev 198808)
</span><span class="lines">@@ -34,6 +34,7 @@
</span><span class="cx"> #include &quot;Error.h&quot;
</span><span class="cx"> #include &quot;Interpreter.h&quot;
</span><span class="cx"> #include &quot;JIT.h&quot;
</span><ins>+#include &quot;JSArrayInlines.h&quot;
</ins><span class="cx"> #include &quot;JSArrayIterator.h&quot;
</span><span class="cx"> #include &quot;JSCBuiltins.h&quot;
</span><span class="cx"> #include &quot;JSCInlines.h&quot;
</span><span class="lines">@@ -50,7 +51,6 @@
</span><span class="cx"> namespace JSC {
</span><span class="cx"> 
</span><span class="cx"> EncodedJSValue JSC_HOST_CALL arrayProtoFuncToLocaleString(ExecState*);
</span><del>-EncodedJSValue JSC_HOST_CALL arrayProtoFuncConcat(ExecState*);
</del><span class="cx"> EncodedJSValue JSC_HOST_CALL arrayProtoFuncJoin(ExecState*);
</span><span class="cx"> EncodedJSValue JSC_HOST_CALL arrayProtoFuncPop(ExecState*);
</span><span class="cx"> EncodedJSValue JSC_HOST_CALL arrayProtoFuncPush(ExecState*);
</span><span class="lines">@@ -93,7 +93,7 @@
</span><span class="cx">     
</span><span class="cx">     JSC_NATIVE_FUNCTION_WITHOUT_TRANSITION(vm.propertyNames-&gt;toString, arrayProtoFuncToString, DontEnum, 0);
</span><span class="cx">     JSC_NATIVE_FUNCTION_WITHOUT_TRANSITION(vm.propertyNames-&gt;toLocaleString, arrayProtoFuncToLocaleString, DontEnum, 0);
</span><del>-    JSC_NATIVE_FUNCTION_WITHOUT_TRANSITION(&quot;concat&quot;, arrayProtoFuncConcat, DontEnum, 1);
</del><ins>+    JSC_BUILTIN_FUNCTION_WITHOUT_TRANSITION(&quot;concat&quot;, arrayPrototypeConcatCodeGenerator, DontEnum);
</ins><span class="cx">     JSC_BUILTIN_FUNCTION_WITHOUT_TRANSITION(&quot;fill&quot;, arrayPrototypeFillCodeGenerator, DontEnum);
</span><span class="cx">     JSC_NATIVE_FUNCTION_WITHOUT_TRANSITION(vm.propertyNames-&gt;join, arrayProtoFuncJoin, DontEnum, 1);
</span><span class="cx">     JSC_NATIVE_INTRINSIC_FUNCTION_WITHOUT_TRANSITION(&quot;pop&quot;, arrayProtoFuncPop, DontEnum, 0, ArrayPopIntrinsic);
</span><span class="lines">@@ -590,87 +590,6 @@
</span><span class="cx">     return JSValue::encode(join(*exec, thisObject, separator-&gt;view(exec).get()));
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-EncodedJSValue JSC_HOST_CALL arrayProtoFuncConcat(ExecState* exec)
-{
-    JSValue thisValue = exec-&gt;thisValue().toThis(exec, StrictMode);
-    unsigned argCount = exec-&gt;argumentCount();
-    JSValue curArg = thisValue.toObject(exec);
-    if (!curArg)
-        return JSValue::encode(JSValue());
-    Checked&lt;unsigned, RecordOverflow&gt; finalArraySize = 0;
-
-    // We need to do species construction before geting the rest of the elements.
-    std::pair&lt;SpeciesConstructResult, JSObject*&gt; speciesResult = speciesConstructArray(exec, curArg.getObject(), 0);
-    if (speciesResult.first == SpeciesConstructResult::Exception)
-        return JSValue::encode(jsUndefined());
-
-    JSArray* currentArray = nullptr;
-    JSArray* previousArray = nullptr;
-    for (unsigned i = 0; ; ++i) {
-        previousArray = currentArray;
-        currentArray = jsDynamicCast&lt;JSArray*&gt;(curArg);
-        if (currentArray) {
-            // Can't use JSArray::length here because this might be a RuntimeArray!
-            finalArraySize += getLength(exec, currentArray);
-            if (exec-&gt;hadException())
-                return JSValue::encode(jsUndefined());
-        } else
-            ++finalArraySize;
-        if (i == argCount)
-            break;
-        curArg = exec-&gt;uncheckedArgument(i);
-    }
-
-    if (finalArraySize.hasOverflowed())
-        return JSValue::encode(throwOutOfMemoryError(exec));
-
-    if (speciesResult.first == SpeciesConstructResult::FastPath &amp;&amp; argCount == 1 &amp;&amp; previousArray &amp;&amp; currentArray &amp;&amp; finalArraySize.unsafeGet() &lt; MIN_SPARSE_ARRAY_INDEX) {
-        IndexingType type = JSArray::fastConcatType(exec-&gt;vm(), *previousArray, *currentArray);
-        if (type != NonArray)
-            return previousArray-&gt;fastConcatWith(*exec, *currentArray);
-    }
-
-    ASSERT(speciesResult.first != SpeciesConstructResult::Exception);
-
-    JSObject* result;
-    if (speciesResult.first == SpeciesConstructResult::CreatedObject)
-        result = speciesResult.second;
-    else {
-        // We add the newTarget because the compiler gets confused between 0 being a number and a pointer.
-        result = constructEmptyArray(exec, nullptr, 0, JSValue());
-        if (exec-&gt;hadException())
-            return JSValue::encode(jsUndefined());
-    }
-
-    curArg = thisValue.toObject(exec);
-    ASSERT(!exec-&gt;hadException());
-    unsigned n = 0;
-    for (unsigned i = 0; ; ++i) {
-        if (JSArray* currentArray = jsDynamicCast&lt;JSArray*&gt;(curArg)) {
-            // Can't use JSArray::length here because this might be a RuntimeArray!
-            unsigned length = getLength(exec, currentArray);
-            if (exec-&gt;hadException())
-                return JSValue::encode(jsUndefined());
-            for (unsigned k = 0; k &lt; length; ++k) {
-                JSValue v = getProperty(exec, currentArray, k);
-                if (exec-&gt;hadException())
-                    return JSValue::encode(jsUndefined());
-                if (v)
-                    result-&gt;putDirectIndex(exec, n, v);
-                n++;
-            }
-        } else {
-            result-&gt;putDirectIndex(exec, n, curArg);
-            n++;
-        }
-        if (i == argCount)
-            break;
-        curArg = exec-&gt;uncheckedArgument(i);
-    }
-    setLength(exec, result, n);
-    return JSValue::encode(result);
-}
-
</del><span class="cx"> EncodedJSValue JSC_HOST_CALL arrayProtoFuncPop(ExecState* exec)
</span><span class="cx"> {
</span><span class="cx">     JSValue thisValue = exec-&gt;thisValue().toThis(exec, StrictMode);
</span><span class="lines">@@ -1095,6 +1014,92 @@
</span><span class="cx">     return JSValue::encode(JSArrayIterator::create(exec, exec-&gt;callee()-&gt;globalObject()-&gt;arrayIteratorStructure(), ArrayIterateKey, thisObj));
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+EncodedJSValue JSC_HOST_CALL arrayProtoPrivateFuncIsJSArray(ExecState* exec)
+{
+    JSValue value = exec-&gt;uncheckedArgument(0);
+    if (value.isObject())
+        return JSValue::encode(jsBoolean(value.getObject()-&gt;type() == ArrayType));
+    return JSValue::encode(jsBoolean(false));
+}
+
+inline bool moveElements(ExecState* exec, VM&amp; vm, JSArray* target, unsigned targetOffset, JSArray* source, unsigned sourceLength)
+{
+    ASSERT(!hasAnyArrayStorage(source-&gt;indexingType()));
+    for (unsigned i = 0; i &lt; sourceLength; ++i) {
+        JSValue value = getProperty(exec, source, i);
+        if (vm.exception())
+            return false;
+        if (value) {
+            target-&gt;putDirectIndex(exec, targetOffset + i, value);
+            if (vm.exception())
+                return false;
+        }
+    }
+    return true;
+}
+
+EncodedJSValue JSC_HOST_CALL arrayProtoPrivateFuncConcatMemcpy(ExecState* exec)
+{
+    ASSERT(exec-&gt;argumentCount() == 2);
+    VM&amp; vm = exec-&gt;vm();
+
+    JSArray* firstArray = jsCast&lt;JSArray*&gt;(exec-&gt;uncheckedArgument(0));
+    JSArray* secondArray = jsCast&lt;JSArray*&gt;(exec-&gt;uncheckedArgument(1));
+
+    if (!firstArray-&gt;canFastCopy(vm, secondArray))
+        return JSValue::encode(jsNull());
+
+    Butterfly* firstButterfly = firstArray-&gt;butterfly();
+    Butterfly* secondButterfly = secondArray-&gt;butterfly();
+
+    unsigned firstArraySize = firstButterfly-&gt;publicLength();
+    unsigned secondArraySize = secondButterfly-&gt;publicLength();
+
+    IndexingType type = firstArray-&gt;memCopyWithIndexingType(secondArray-&gt;indexingType());
+    if (type == NonArray || firstArraySize + secondArraySize &gt;= MIN_SPARSE_ARRAY_INDEX) {
+        JSArray* result = constructEmptyArray(exec, nullptr, firstArraySize + secondArraySize);
+        if (vm.exception())
+            return JSValue::encode(JSValue());
+
+        if (!moveElements(exec, vm, result, 0, firstArray, firstArraySize)
+            || !moveElements(exec, vm, result, firstArraySize, secondArray, secondArraySize)) {
+            ASSERT(vm.exception());
+            return JSValue::encode(JSValue());
+        }
+
+        return JSValue::encode(result);
+    }
+
+    Structure* resultStructure = exec-&gt;lexicalGlobalObject()-&gt;arrayStructureForIndexingTypeDuringAllocation(type);
+    JSArray* result = JSArray::tryCreateUninitialized(vm, resultStructure, firstArraySize + secondArraySize);
+    if (!result)
+        return JSValue::encode(throwOutOfMemoryError(exec));
+
+    if (type == ArrayWithDouble) {
+        double* buffer = result-&gt;butterfly()-&gt;contiguousDouble().data();
+        memcpy(buffer, firstButterfly-&gt;contiguousDouble().data(), sizeof(JSValue) * firstArraySize);
+        memcpy(buffer + firstArraySize, secondButterfly-&gt;contiguousDouble().data(), sizeof(JSValue) * secondArraySize);
+    } else if (type != ArrayWithUndecided) {
+        WriteBarrier&lt;Unknown&gt;* buffer = result-&gt;butterfly()-&gt;contiguous().data();
+        memcpy(buffer, firstButterfly-&gt;contiguous().data(), sizeof(JSValue) * firstArraySize);
+        memcpy(buffer + firstArraySize, secondButterfly-&gt;contiguous().data(), sizeof(JSValue) * secondArraySize);
+    }
+
+    result-&gt;butterfly()-&gt;setPublicLength(firstArraySize + secondArraySize);
+    return JSValue::encode(result);
+}
+
+EncodedJSValue JSC_HOST_CALL arrayProtoPrivateFuncAppendMemcpy(ExecState* exec)
+{
+    ASSERT(exec-&gt;argumentCount() == 2);
+
+    JSArray* resultArray = jsCast&lt;JSArray*&gt;(exec-&gt;uncheckedArgument(0));
+    JSArray* otherArray = jsCast&lt;JSArray*&gt;(exec-&gt;uncheckedArgument(1));
+
+    return JSValue::encode(jsBoolean(resultArray-&gt;appendMemcpy(exec, exec-&gt;vm(), otherArray)));
+}
+
+
</ins><span class="cx"> // -------------------- ArrayPrototype.constructor Watchpoint ------------------
</span><span class="cx"> 
</span><span class="cx"> class ArrayPrototypeAdaptiveInferredPropertyWatchpoint : public AdaptiveInferredPropertyValueWatchpointBase {
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreruntimeArrayPrototypeh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/runtime/ArrayPrototype.h (198807 => 198808)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/runtime/ArrayPrototype.h        2016-03-29 22:23:42 UTC (rev 198807)
+++ trunk/Source/JavaScriptCore/runtime/ArrayPrototype.h        2016-03-29 22:57:01 UTC (rev 198808)
</span><span class="lines">@@ -41,7 +41,7 @@
</span><span class="cx"> 
</span><span class="cx">     static Structure* createStructure(VM&amp; vm, JSGlobalObject* globalObject, JSValue prototype)
</span><span class="cx">     {
</span><del>-        return Structure::create(vm, globalObject, prototype, TypeInfo(ObjectType, StructureFlags), info(), ArrayClass);
</del><ins>+        return Structure::create(vm, globalObject, prototype, TypeInfo(ArrayType, StructureFlags), info(), ArrayClass);
</ins><span class="cx">     }
</span><span class="cx"> 
</span><span class="cx">     void setConstructor(VM&amp;, JSObject* constructorProperty, unsigned attributes);
</span><span class="lines">@@ -65,6 +65,9 @@
</span><span class="cx"> 
</span><span class="cx"> EncodedJSValue JSC_HOST_CALL arrayProtoFuncToString(ExecState*);
</span><span class="cx"> EncodedJSValue JSC_HOST_CALL arrayProtoFuncValues(ExecState*);
</span><ins>+EncodedJSValue JSC_HOST_CALL arrayProtoPrivateFuncIsJSArray(ExecState*);
+EncodedJSValue JSC_HOST_CALL arrayProtoPrivateFuncConcatMemcpy(ExecState*);
+EncodedJSValue JSC_HOST_CALL arrayProtoPrivateFuncAppendMemcpy(ExecState*);
</ins><span class="cx"> 
</span><span class="cx"> } // namespace JSC
</span><span class="cx"> 
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreruntimeCommonIdentifiersh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/runtime/CommonIdentifiers.h (198807 => 198808)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/runtime/CommonIdentifiers.h        2016-03-29 22:23:42 UTC (rev 198807)
+++ trunk/Source/JavaScriptCore/runtime/CommonIdentifiers.h        2016-03-29 22:57:01 UTC (rev 198808)
</span><span class="lines">@@ -273,12 +273,12 @@
</span><span class="cx">     macro(yield)
</span><span class="cx"> 
</span><span class="cx"> #define JSC_COMMON_PRIVATE_IDENTIFIERS_EACH_WELL_KNOWN_SYMBOL_NOT_IMPLEMENTED_YET(macro)\
</span><del>-    macro(isConcatSpreadable) \
</del><span class="cx">     macro(replace) \
</span><span class="cx">     macro(split)
</span><span class="cx"> 
</span><span class="cx"> #define JSC_COMMON_PRIVATE_IDENTIFIERS_EACH_WELL_KNOWN_SYMBOL(macro) \
</span><span class="cx">     macro(hasInstance) \
</span><ins>+    macro(isConcatSpreadable) \
</ins><span class="cx">     macro(iterator) \
</span><span class="cx">     macro(match) \
</span><span class="cx">     macro(search) \
</span><span class="lines">@@ -373,7 +373,12 @@
</span><span class="cx">     macro(hasInstanceBoundFunction) \
</span><span class="cx">     macro(instanceOf) \
</span><span class="cx">     macro(isArray) \
</span><ins>+    macro(isJSArray) \
</ins><span class="cx">     macro(isArrayConstructor) \
</span><ins>+    macro(concatMemcpy) \
+    macro(appendMemcpy) \
+    macro(predictFinalLengthFromArgumunts) \
+    macro(print) \
</ins><span class="cx">     macro(isSet) \
</span><span class="cx">     macro(isMap) \
</span><span class="cx">     macro(SetIterator) \
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreruntimeIntrinsich"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/runtime/Intrinsic.h (198807 => 198808)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/runtime/Intrinsic.h        2016-03-29 22:23:42 UTC (rev 198807)
+++ trunk/Source/JavaScriptCore/runtime/Intrinsic.h        2016-03-29 22:57:01 UTC (rev 198808)
</span><span class="lines">@@ -56,6 +56,9 @@
</span><span class="cx">     IMulIntrinsic,
</span><span class="cx">     RandomIntrinsic,
</span><span class="cx">     FRoundIntrinsic,
</span><ins>+    IsArrayIntrinsic,
+    IsArrayConstructorIntrinsic,
+    IsJSArrayIntrinsic,
</ins><span class="cx"> 
</span><span class="cx">     // Getter intrinsics.
</span><span class="cx">     TypedArrayLengthIntrinsic,
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreruntimeJSArraycpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/runtime/JSArray.cpp (198807 => 198808)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/runtime/JSArray.cpp        2016-03-29 22:23:42 UTC (rev 198807)
+++ trunk/Source/JavaScriptCore/runtime/JSArray.cpp        2016-03-29 22:57:01 UTC (rev 198808)
</span><span class="lines">@@ -392,6 +392,37 @@
</span><span class="cx">     return true;
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+bool JSArray::appendMemcpy(ExecState* exec, VM&amp; vm, JSC::JSArray* otherArray)
+{
+    if (!canFastCopy(vm, otherArray))
+        return false;
+
+    IndexingType type = indexingType();
+    if (type != memCopyWithIndexingType(otherArray-&gt;indexingType()))
+        return false;
+
+    unsigned oldLength = length();
+    unsigned otherLength = otherArray-&gt;length();
+    unsigned newLength = oldLength + otherLength;
+    if (newLength &gt;= MIN_SPARSE_ARRAY_INDEX)
+        return false;
+
+    if (!ensureLength(vm, newLength))
+        return false;
+    ASSERT(type == indexingType());
+    if (length() != newLength) {
+        throwOutOfMemoryError(exec);
+        return false;
+    }
+
+    if (type == ArrayWithDouble)
+        memcpy(butterfly()-&gt;contiguousDouble().data() + oldLength, otherArray-&gt;butterfly()-&gt;contiguousDouble().data(), sizeof(JSValue) * otherLength);
+    else
+        memcpy(butterfly()-&gt;contiguous().data() + oldLength, otherArray-&gt;butterfly()-&gt;contiguous().data(), sizeof(JSValue) * otherLength);
+
+    return true;
+}
+
</ins><span class="cx"> bool JSArray::setLength(ExecState* exec, unsigned newLength, bool throwException)
</span><span class="cx"> {
</span><span class="cx">     Butterfly* butterfly = m_butterfly.get();
</span><span class="lines">@@ -719,38 +750,6 @@
</span><span class="cx">     }
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-EncodedJSValue JSArray::fastConcatWith(ExecState&amp; exec, JSArray&amp; otherArray)
-{
-    auto newArrayType = indexingType();
-
-    VM&amp; vm = exec.vm();
-    ASSERT(newArrayType == fastConcatType(vm, *this, otherArray));
-
-    unsigned thisArraySize = m_butterfly.get()-&gt;publicLength();
-    unsigned otherArraySize = otherArray.m_butterfly.get()-&gt;publicLength();
-    ASSERT(thisArraySize + otherArraySize &lt; MIN_SPARSE_ARRAY_INDEX);
-
-    Structure* resultStructure = exec.lexicalGlobalObject()-&gt;arrayStructureForIndexingTypeDuringAllocation(newArrayType);
-    JSArray* resultArray = JSArray::tryCreateUninitialized(vm, resultStructure, thisArraySize + otherArraySize);
-    if (!resultArray)
-        return JSValue::encode(throwOutOfMemoryError(&amp;exec));
-
-    auto&amp; resultButterfly = *resultArray-&gt;butterfly();
-    auto&amp; otherButterfly = *otherArray.butterfly();
-    if (newArrayType == ArrayWithDouble) {
-        auto buffer = resultButterfly.contiguousDouble().data();
-        memcpy(buffer, m_butterfly.get()-&gt;contiguousDouble().data(), sizeof(JSValue) * thisArraySize);
-        memcpy(buffer + thisArraySize, otherButterfly.contiguousDouble().data(), sizeof(JSValue) * otherArraySize);
-    } else {
-        auto buffer = resultButterfly.contiguous().data();
-        memcpy(buffer, m_butterfly.get()-&gt;contiguous().data(), sizeof(JSValue) * thisArraySize);
-        memcpy(buffer + thisArraySize, otherButterfly.contiguous().data(), sizeof(JSValue) * otherArraySize);
-    }
-
-    resultButterfly.setPublicLength(thisArraySize + otherArraySize);
-    return JSValue::encode(resultArray);
-}
-
</del><span class="cx"> bool JSArray::shiftCountWithArrayStorage(VM&amp; vm, unsigned startIndex, unsigned count, ArrayStorage* storage)
</span><span class="cx"> {
</span><span class="cx">     unsigned oldLength = storage-&gt;length();
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreruntimeJSArrayh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/runtime/JSArray.h (198807 => 198808)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/runtime/JSArray.h        2016-03-29 22:23:42 UTC (rev 198807)
+++ trunk/Source/JavaScriptCore/runtime/JSArray.h        2016-03-29 22:57:01 UTC (rev 198808)
</span><span class="lines">@@ -23,6 +23,7 @@
</span><span class="cx"> 
</span><span class="cx"> #include &quot;ArrayConventions.h&quot;
</span><span class="cx"> #include &quot;ButterflyInlines.h&quot;
</span><ins>+#include &quot;JSCellInlines.h&quot;
</ins><span class="cx"> #include &quot;JSObject.h&quot;
</span><span class="cx"> 
</span><span class="cx"> namespace JSC {
</span><span class="lines">@@ -78,19 +79,10 @@
</span><span class="cx"> 
</span><span class="cx">     JSArray* fastSlice(ExecState&amp;, unsigned startIndex, unsigned count);
</span><span class="cx"> 
</span><del>-    static IndexingType fastConcatType(VM&amp; vm, JSArray&amp; firstArray, JSArray&amp; secondArray)
-    {
-        IndexingType type = firstArray.indexingType();
-        if (type != secondArray.indexingType())
-            return NonArray;
-        if (type != ArrayWithDouble &amp;&amp; type != ArrayWithInt32 &amp;&amp; type != ArrayWithContiguous)
-            return NonArray;
-        if (firstArray.structure(vm)-&gt;holesMustForwardToPrototype(vm)
-            || secondArray.structure(vm)-&gt;holesMustForwardToPrototype(vm))
-            return NonArray;
-        return type;
-    }
-    EncodedJSValue fastConcatWith(ExecState&amp;, JSArray&amp;);
</del><ins>+    bool canFastCopy(VM&amp;, JSArray* otherArray);
+    // This function returns NonArray if the indexing types are not compatable for memcpying.
+    IndexingType memCopyWithIndexingType(IndexingType other);
+    bool appendMemcpy(ExecState*, VM&amp;, JSArray* otherArray);
</ins><span class="cx"> 
</span><span class="cx">     enum ShiftCountMode {
</span><span class="cx">         // This form of shift hints that we're doing queueing. With this assumption in hand,
</span><span class="lines">@@ -152,7 +144,7 @@
</span><span class="cx"> 
</span><span class="cx">     static Structure* createStructure(VM&amp; vm, JSGlobalObject* globalObject, JSValue prototype, IndexingType indexingType)
</span><span class="cx">     {
</span><del>-        return Structure::create(vm, globalObject, prototype, TypeInfo(ObjectType, StructureFlags), info(), indexingType);
</del><ins>+        return Structure::create(vm, globalObject, prototype, TypeInfo(ArrayType, StructureFlags), info(), indexingType);
</ins><span class="cx">     }
</span><span class="cx">         
</span><span class="cx"> protected:
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreruntimeJSArrayInlinesh"></a>
<div class="addfile"><h4>Added: trunk/Source/JavaScriptCore/runtime/JSArrayInlines.h (0 => 198808)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/runtime/JSArrayInlines.h                                (rev 0)
+++ trunk/Source/JavaScriptCore/runtime/JSArrayInlines.h        2016-03-29 22:57:01 UTC (rev 198808)
</span><span class="lines">@@ -0,0 +1,73 @@
</span><ins>+/*
+ *  Copyright (C) 2016 Apple Inc. All rights reserved.
+ *
+ *  This library is free software; you can redistribute it and/or
+ *  modify it under the terms of the GNU Lesser General Public
+ *  License as published by the Free Software Foundation; either
+ *  version 2 of the License, or (at your option) any later version.
+ *
+ *  This library is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *  Lesser General Public License for more details.
+ *
+ *  You should have received a copy of the GNU Lesser General Public
+ *  License along with this library; if not, write to the Free Software
+ *  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+ *
+ */
+
+#ifndef JSArrayInlines_h
+#define JSArrayInlines_h
+
+#include &quot;JSArray.h&quot;
+#include &quot;JSCellInlines.h&quot;
+#include &quot;Structure.h&quot;
+
+namespace JSC {
+
+IndexingType JSArray::memCopyWithIndexingType(IndexingType other)
+{
+    IndexingType type = indexingType();
+    if (!(type &amp; IsArray &amp;&amp; other &amp; IsArray))
+        return NonArray;
+
+    if (hasAnyArrayStorage(type) || hasAnyArrayStorage(other))
+        return NonArray;
+
+    if (type == ArrayWithUndecided)
+        return other;
+
+    if (other == ArrayWithUndecided)
+        return type;
+
+    // We can memcpy an Int32 and a Contiguous into a Contiguous array since
+    // both share the same memory layout for Int32 numbers.
+    if ((type == ArrayWithInt32 || type == ArrayWithContiguous)
+        &amp;&amp; (other == ArrayWithInt32 || other == ArrayWithContiguous)) {
+        if (other == ArrayWithContiguous)
+            return other;
+        return type;
+    }
+
+    if (type != other)
+        return NonArray;
+
+    return type;
+}
+
+bool JSArray::canFastCopy(VM&amp; vm, JSArray* otherArray)
+{
+    if (hasAnyArrayStorage(this-&gt;indexingType()) || hasAnyArrayStorage(otherArray-&gt;indexingType()))
+        return false;
+    // FIXME: We should have a watchpoint for indexed properties on Array.prototype and Object.prototype
+    // instead of walking the prototype chain. https://bugs.webkit.org/show_bug.cgi?id=155592
+    if (otherArray-&gt;structure(vm)-&gt;holesMustForwardToPrototype(vm)
+        || otherArray-&gt;structure(vm)-&gt;holesMustForwardToPrototype(vm))
+        return false;
+    return true;
+}
+
+} // namespace JSC
+
+#endif /* JSArrayInlines_h */
</ins></span></pre></div>
<a id="trunkSourceJavaScriptCoreruntimeJSGlobalObjectcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/runtime/JSGlobalObject.cpp (198807 => 198808)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/runtime/JSGlobalObject.cpp        2016-03-29 22:23:42 UTC (rev 198807)
+++ trunk/Source/JavaScriptCore/runtime/JSGlobalObject.cpp        2016-03-29 22:57:01 UTC (rev 198808)
</span><span class="lines">@@ -515,6 +515,8 @@
</span><span class="cx">     putDirectWithoutTransition(vm, vm.propertyNames-&gt;Uint32ArrayPrivateName, m_typedArrays[toIndex(TypeUint32)].constructor.get(), DontEnum);
</span><span class="cx">     putDirectWithoutTransition(vm, vm.propertyNames-&gt;Float32ArrayPrivateName, m_typedArrays[toIndex(TypeFloat32)].constructor.get(), DontEnum);
</span><span class="cx">     putDirectWithoutTransition(vm, vm.propertyNames-&gt;Float64ArrayPrivateName, m_typedArrays[toIndex(TypeFloat64)].constructor.get(), DontEnum);
</span><ins>+    putDirectWithoutTransition(vm, vm.propertyNames-&gt;ObjectPrivateName, objectConstructor, DontEnum | DontDelete | ReadOnly);
+    putDirectWithoutTransition(vm, vm.propertyNames-&gt;ArrayPrivateName, arrayConstructor, DontEnum | DontDelete | ReadOnly);
</ins><span class="cx"> 
</span><span class="cx">     m_moduleLoader.set(vm, this, ModuleLoaderObject::create(vm, this, ModuleLoaderObject::createStructure(vm, this, m_objectPrototype.get())));
</span><span class="cx">     if (Options::exposeInternalModuleLoader())
</span><span class="lines">@@ -537,13 +539,16 @@
</span><span class="cx">     JSFunction* privateFuncHasInstanceBoundFunction = JSFunction::create(vm, this, 0, String(), hasInstanceBoundFunction);
</span><span class="cx">     JSFunction* privateFuncInstanceOf = JSFunction::create(vm, this, 0, String(), objectPrivateFuncInstanceOf);
</span><span class="cx">     JSFunction* privateFuncThisTimeValue = JSFunction::create(vm, this, 0, String(), dateProtoFuncGetTime);
</span><del>-    JSFunction* privateFuncIsArrayConstructor = JSFunction::create(vm, this, 0, String(), arrayConstructorPrivateFuncIsArrayConstructor);
</del><ins>+    JSFunction* privateFuncIsArrayConstructor = JSFunction::create(vm, this, 0, String(), arrayConstructorPrivateFuncIsArrayConstructor, IsArrayConstructorIntrinsic);
+    JSFunction* privateFuncIsJSArray = JSFunction::create(vm, this, 0, String(), arrayProtoPrivateFuncIsJSArray, IsJSArrayIntrinsic);
+    JSFunction* privateFuncConcatMemcpy = JSFunction::create(vm, this, 0, String(), arrayProtoPrivateFuncConcatMemcpy);
+    JSFunction* privateFuncAppendMemcpy = JSFunction::create(vm, this, 0, String(), arrayProtoPrivateFuncAppendMemcpy);
+    JSFunction* privateFuncConcatSlowPath = JSFunction::createBuiltinFunction(vm, arrayPrototypeConcatSlowPathCodeGenerator(vm), this);
</ins><span class="cx"> 
</span><span class="cx">     GlobalPropertyInfo staticGlobals[] = {
</span><span class="cx">         GlobalPropertyInfo(vm.propertyNames-&gt;NaN, jsNaN(), DontEnum | DontDelete | ReadOnly),
</span><span class="cx">         GlobalPropertyInfo(vm.propertyNames-&gt;Infinity, jsNumber(std::numeric_limits&lt;double&gt;::infinity()), DontEnum | DontDelete | ReadOnly),
</span><span class="cx">         GlobalPropertyInfo(vm.propertyNames-&gt;undefinedKeyword, jsUndefined(), DontEnum | DontDelete | ReadOnly),
</span><del>-        GlobalPropertyInfo(vm.propertyNames-&gt;ObjectPrivateName, objectConstructor, DontEnum | DontDelete | ReadOnly),
</del><span class="cx">         GlobalPropertyInfo(vm.propertyNames-&gt;ownEnumerablePropertyKeysPrivateName, JSFunction::create(vm, this, 0, String(), ownEnumerablePropertyKeys), DontEnum | DontDelete | ReadOnly),
</span><span class="cx">         GlobalPropertyInfo(vm.propertyNames-&gt;getTemplateObjectPrivateName, privateFuncGetTemplateObject, DontEnum | DontDelete | ReadOnly),
</span><span class="cx">         GlobalPropertyInfo(vm.propertyNames-&gt;enqueueJobPrivateName, JSFunction::create(vm, this, 0, String(), enqueueJob), DontEnum | DontDelete | ReadOnly),
</span><span class="lines">@@ -556,7 +561,6 @@
</span><span class="cx">         GlobalPropertyInfo(vm.propertyNames-&gt;hasInstanceBoundFunctionPrivateName, privateFuncHasInstanceBoundFunction, DontEnum | DontDelete | ReadOnly),
</span><span class="cx">         GlobalPropertyInfo(vm.propertyNames-&gt;instanceOfPrivateName, privateFuncInstanceOf, DontEnum | DontDelete | ReadOnly),
</span><span class="cx">         GlobalPropertyInfo(vm.propertyNames-&gt;BuiltinLogPrivateName, builtinLog, DontEnum | DontDelete | ReadOnly),
</span><del>-        GlobalPropertyInfo(vm.propertyNames-&gt;ArrayPrivateName, arrayConstructor, DontEnum | DontDelete | ReadOnly),
</del><span class="cx">         GlobalPropertyInfo(vm.propertyNames-&gt;NumberPrivateName, numberConstructor, DontEnum | DontDelete | ReadOnly),
</span><span class="cx">         GlobalPropertyInfo(vm.propertyNames-&gt;RegExpPrivateName, m_regExpConstructor.get(), DontEnum | DontDelete | ReadOnly),
</span><span class="cx">         GlobalPropertyInfo(vm.propertyNames-&gt;StringPrivateName, stringConstructor, DontEnum | DontDelete | ReadOnly),
</span><span class="lines">@@ -574,6 +578,10 @@
</span><span class="cx">         GlobalPropertyInfo(vm.propertyNames-&gt;isMapPrivateName, JSFunction::create(vm, this, 1, String(), privateFuncIsMap), DontEnum | DontDelete | ReadOnly),
</span><span class="cx">         GlobalPropertyInfo(vm.propertyNames-&gt;isArrayPrivateName, arrayConstructor-&gt;getDirect(vm, vm.propertyNames-&gt;isArray), DontEnum | DontDelete | ReadOnly),
</span><span class="cx">         GlobalPropertyInfo(vm.propertyNames-&gt;isArrayConstructorPrivateName, privateFuncIsArrayConstructor, DontEnum | DontDelete | ReadOnly),
</span><ins>+        GlobalPropertyInfo(vm.propertyNames-&gt;isJSArrayPrivateName, privateFuncIsJSArray, DontEnum | DontDelete | ReadOnly),
+        GlobalPropertyInfo(vm.propertyNames-&gt;concatMemcpyPrivateName, privateFuncConcatMemcpy, DontEnum | DontDelete | ReadOnly),
+        GlobalPropertyInfo(vm.propertyNames-&gt;appendMemcpyPrivateName, privateFuncAppendMemcpy, DontEnum | DontDelete | ReadOnly),
+        GlobalPropertyInfo(vm.propertyNames-&gt;builtinNames().concatSlowPathPrivateName(), privateFuncConcatSlowPath, DontEnum | DontDelete | ReadOnly),
</ins><span class="cx">         GlobalPropertyInfo(vm.propertyNames-&gt;MapIteratorPrivateName, JSFunction::create(vm, this, 1, String(), privateFuncMapIterator), DontEnum | DontDelete | ReadOnly),
</span><span class="cx">         GlobalPropertyInfo(vm.propertyNames-&gt;mapIteratorNextPrivateName, JSFunction::create(vm, this, 0, String(), privateFuncMapIteratorNext), DontEnum | DontDelete | ReadOnly),
</span><span class="cx"> 
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreruntimeJSTypeh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/runtime/JSType.h (198807 => 198808)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/runtime/JSType.h        2016-03-29 22:23:42 UTC (rev 198807)
+++ trunk/Source/JavaScriptCore/runtime/JSType.h        2016-03-29 22:57:01 UTC (rev 198808)
</span><span class="lines">@@ -61,6 +61,7 @@
</span><span class="cx">     PureForwardingProxyType,
</span><span class="cx">     ImpureProxyType,
</span><span class="cx">     WithScopeType,
</span><ins>+    ArrayType,
</ins><span class="cx">     DirectArgumentsType,
</span><span class="cx">     ScopedArgumentsType,
</span><span class="cx"> 
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreruntimeObjectConstructorh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/runtime/ObjectConstructor.h (198807 => 198808)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/runtime/ObjectConstructor.h        2016-03-29 22:23:42 UTC (rev 198807)
+++ trunk/Source/JavaScriptCore/runtime/ObjectConstructor.h        2016-03-29 22:57:01 UTC (rev 198808)
</span><span class="lines">@@ -91,6 +91,13 @@
</span><span class="cx">     return constructEmptyObject(exec, exec-&gt;lexicalGlobalObject()-&gt;objectPrototype());
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+inline JSObject* constructObject(ExecState* exec, JSGlobalObject* globalObject, JSValue arg)
+{
+    if (arg.isUndefinedOrNull())
+        return constructEmptyObject(exec, globalObject-&gt;objectPrototype());
+    return arg.toObject(exec, globalObject);
+}
+
</ins><span class="cx"> // Section 6.2.4.4 of the ES6 specification.
</span><span class="cx"> // https://tc39.github.io/ecma262/#sec-frompropertydescriptor
</span><span class="cx"> inline JSObject* constructObjectFromPropertyDescriptor(ExecState* exec, const PropertyDescriptor&amp; descriptor)
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoretestses6yaml"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/tests/es6.yaml (198807 => 198808)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/tests/es6.yaml        2016-03-29 22:23:42 UTC (rev 198807)
+++ trunk/Source/JavaScriptCore/tests/es6.yaml        2016-03-29 22:57:01 UTC (rev 198808)
</span><span class="lines">@@ -955,7 +955,7 @@
</span><span class="cx"> - path: es6/Proxy_internal_get_calls_Array.from.js
</span><span class="cx">   cmd: runES6 :normal
</span><span class="cx"> - path: es6/Proxy_internal_get_calls_Array.prototype.concat.js
</span><del>-  cmd: runES6 :fail
</del><ins>+  cmd: runES6 :normal
</ins><span class="cx"> - path: es6/Proxy_internal_get_calls_Array.prototype.pop.js
</span><span class="cx">   cmd: runES6 :normal
</span><span class="cx"> - path: es6/Proxy_internal_get_calls_Array.prototype.reverse.js
</span><span class="lines">@@ -1195,7 +1195,7 @@
</span><span class="cx"> - path: es6/well-known_symbols_Symbol.hasInstance.js
</span><span class="cx">   cmd: runES6 :normal
</span><span class="cx"> - path: es6/well-known_symbols_Symbol.isConcatSpreadable.js
</span><del>-  cmd: runES6 :fail
</del><ins>+  cmd: runES6 :normal
</ins><span class="cx"> - path: es6/well-known_symbols_Symbol.match.js
</span><span class="cx">   cmd: runES6 :normal
</span><span class="cx"> - path: es6/well-known_symbols_Symbol.replace.js
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoretestsstressarrayconcatspreadobjectjs"></a>
<div class="addfile"><h4>Added: trunk/Source/JavaScriptCore/tests/stress/array-concat-spread-object.js (0 => 198808)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/tests/stress/array-concat-spread-object.js                                (rev 0)
+++ trunk/Source/JavaScriptCore/tests/stress/array-concat-spread-object.js        2016-03-29 22:57:01 UTC (rev 198808)
</span><span class="lines">@@ -0,0 +1,48 @@
</span><ins>+// This file tests is concat spreadable.
+
+function arrayEq(a, b) {
+    if (a.length !== b.length)
+        return false;
+    for (let i = 0; i &lt; a.length; i++) {
+        if (a[i] !== b[i])
+            return false;
+    }
+    return true;
+}
+
+
+{
+    let o = {0:1, 1:2, 2:3, length:3};
+
+    // Test it works with proxies by default
+    for (let i = 0; i &lt; 100000; i++) {
+        if (!arrayEq(Array.prototype.concat.call(o,o), [o,o]))
+            throw &quot;failed normally with an object&quot;
+    }
+
+    // Test it works with spreadable true
+    o[Symbol.isConcatSpreadable] = true;
+    for (let i = 0; i &lt; 100000; i++) {
+        let result = Array.prototype.concat.call(o,o)
+        if (!arrayEq(result, [1,2,3,1,2,3]))
+            throw &quot;failed with spread got: &quot; + result;
+    }
+
+    // Test it works with many things
+    o[Symbol.isConcatSpreadable] = true;
+    let other = {}
+    for (let i = 0; i &lt; 100000; i++) {
+        let result = Array.prototype.concat.call(o,o,true,[1,2],other)
+        if (!arrayEq(result, [1,2,3,1,2,3,true,1,2,other]))
+            throw &quot;failed with spread got: &quot; + result;
+    }
+
+    // Test it works with strings
+    String.prototype[Symbol.isConcatSpreadable] = true;
+    for (let i = 0; i &lt; 100000; i++) {
+        let result = Array.prototype.concat.call(&quot;hi&quot;,&quot;hi&quot;)
+        // This is what the spec says is the correct answer... D:
+        if (!arrayEq(result, [&quot;h&quot;, &quot;i&quot;, &quot;hi&quot;]))
+            throw &quot;failed with string got: &quot; + result;
+    }
+}
</ins></span></pre></div>
<a id="trunkSourceJavaScriptCoretestsstressarrayconcatspreadproxyexceptioncheckjs"></a>
<div class="addfile"><h4>Added: trunk/Source/JavaScriptCore/tests/stress/array-concat-spread-proxy-exception-check.js (0 => 198808)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/tests/stress/array-concat-spread-proxy-exception-check.js                                (rev 0)
+++ trunk/Source/JavaScriptCore/tests/stress/array-concat-spread-proxy-exception-check.js        2016-03-29 22:57:01 UTC (rev 198808)
</span><span class="lines">@@ -0,0 +1,34 @@
</span><ins>+function arrayEq(a, b) {
+    if (a.length !== b.length)
+        return false;
+    for (let i = 0; i &lt; a.length; i++) {
+        if (a[i] !== b[i])
+            return false;
+    }
+    return true;
+}
+
+{
+    let concat = Array.prototype.concat;
+    noInline(concat);
+    let array = [1, 2, 3];
+    let {proxy:p, revoke} = Proxy.revocable(array, { get : function(o, k) { return o[k]; } });
+
+    concat.call(p,p);
+
+    for (let i = 0; i &lt; 100000; i++) {
+        if (!arrayEq(concat.call(p,p), [1,2,3,1,2,3]))
+            throw &quot;bad&quot;;
+    }
+    revoke();
+    failed = true;
+    try {
+        concat.call(p,p);
+    } catch (e) {
+        failed = false;
+    }
+
+    if (failed)
+        throw &quot;bad&quot;
+
+}
</ins></span></pre></div>
<a id="trunkSourceJavaScriptCoretestsstressarrayconcatspreadproxyjs"></a>
<div class="addfile"><h4>Added: trunk/Source/JavaScriptCore/tests/stress/array-concat-spread-proxy.js (0 => 198808)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/tests/stress/array-concat-spread-proxy.js                                (rev 0)
+++ trunk/Source/JavaScriptCore/tests/stress/array-concat-spread-proxy.js        2016-03-29 22:57:01 UTC (rev 198808)
</span><span class="lines">@@ -0,0 +1,39 @@
</span><ins>+// This file tests is concat spreadable.
+
+function arrayEq(a, b) {
+    if (a.length !== b.length)
+        return false;
+    for (let i = 0; i &lt; a.length; i++) {
+        if (a[i] !== b[i])
+            return false;
+    }
+    return true;
+}
+
+
+{
+    let array = [1,2,3];
+    let {proxy:p, revoke} = Proxy.revocable(array, { get : function(o, k) { return o[k]; } });
+
+    // Test it works with proxies by default
+    for (let i = 0; i &lt; 100000; i++) {
+        if (!arrayEq(Array.prototype.concat.call(p,p), [1,2,3,1,2,3]))
+            throw &quot;failed normally with a proxy&quot;
+    }
+
+    // Test it works with spreadable false.
+    p[Symbol.isConcatSpreadable] = false;
+    for (let i = 0; i &lt; 100000; i++) {
+        if (!arrayEq(Array.prototype.concat.call(p,p), [p,p]))
+            throw &quot;failed with no spread&quot;
+    }
+
+    p[Symbol.isConcatSpreadable] = undefined;
+    revoke();
+    passed = true;
+    try {
+        Array.prototype.concat.call(p,[]);
+        passed = false;
+    } catch (e) { }
+
+}
</ins></span></pre></div>
<a id="trunkSourceJavaScriptCoretestsstressarrayconcatwithslowindexingtypesjs"></a>
<div class="addfile"><h4>Added: trunk/Source/JavaScriptCore/tests/stress/array-concat-with-slow-indexingtypes.js (0 => 198808)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/tests/stress/array-concat-with-slow-indexingtypes.js                                (rev 0)
+++ trunk/Source/JavaScriptCore/tests/stress/array-concat-with-slow-indexingtypes.js        2016-03-29 22:57:01 UTC (rev 198808)
</span><span class="lines">@@ -0,0 +1,35 @@
</span><ins>+function arrayEq(a, b) {
+    if (a.length !== b.length)
+        return false;
+    for (let i = 0; i &lt; a.length; i++) {
+        if (a[i] !== b[i])
+            return false;
+    }
+    return true;
+}
+
+
+{
+
+    array = [1,2];
+    Object.defineProperty(array, 2, { get: () =&gt; { return 1; } });
+
+    for (let i = 0; i &lt; 100000; i++) {
+        if (!arrayEq(Array.prototype.concat.call(array,array), [1,2,1,1,2,1]))
+            throw &quot;failed normally with a getter&quot;
+        if (!arrayEq(Array.prototype.concat.call([],array), [1,2,1]))
+            throw &quot;failed with undecided and a getter&quot;
+    }
+
+    // Test with indexed types on prototype.
+    array = [1,2];
+    array.length = 3;
+    Array.prototype[2] = 1;
+
+    for (let i = 0; i &lt; 100000; i++) {
+        if (!arrayEq(Array.prototype.concat.call(array,array), [1,2,1,1,2,1]))
+            throw &quot;failed normally with an indexed prototype&quot;
+        if (!arrayEq(Array.prototype.concat.call([],array), [1,2,1]))
+            throw &quot;failed with undecided and an indexed prototype&quot;
+    }
+}
</ins></span></pre></div>
<a id="trunkSourceJavaScriptCoretestsstressarrayspeciesconfigarrayconstructorjs"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/tests/stress/array-species-config-array-constructor.js (198807 => 198808)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/tests/stress/array-species-config-array-constructor.js        2016-03-29 22:23:42 UTC (rev 198807)
+++ trunk/Source/JavaScriptCore/tests/stress/array-species-config-array-constructor.js        2016-03-29 22:57:01 UTC (rev 198808)
</span><span class="lines">@@ -16,6 +16,9 @@
</span><span class="cx"> 
</span><span class="cx"> Object.defineProperty(Array, Symbol.species, { value: Int32Array, configurable: true });
</span><span class="cx"> 
</span><ins>+// We can't write to the length property on a typed array by default.
+Object.defineProperty(Int32Array.prototype, &quot;length&quot;, { value: 0, writable: true });
+
</ins><span class="cx"> result = foo.concat([1]);
</span><span class="cx"> if (!(result instanceof Int32Array))
</span><span class="cx">     throw &quot;concat failed&quot;;
</span></span></pre></div>
<a id="trunkSourceWebCoreChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/ChangeLog (198807 => 198808)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/ChangeLog        2016-03-29 22:23:42 UTC (rev 198807)
+++ trunk/Source/WebCore/ChangeLog        2016-03-29 22:57:01 UTC (rev 198808)
</span><span class="lines">@@ -1,3 +1,15 @@
</span><ins>+2016-03-29  Keith Miller  &lt;keith_miller@apple.com&gt;
+
+        [ES6] Add support for Symbol.isConcatSpreadable.
+        https://bugs.webkit.org/show_bug.cgi?id=155351
+
+        Reviewed by Saam Barati.
+
+        Makes runtime arrays have the new ArrayType
+
+        * bridge/runtime_array.h:
+        (JSC::RuntimeArray::createStructure):
+
</ins><span class="cx"> 2016-03-29  Nan Wang  &lt;n_wang@apple.com&gt;
</span><span class="cx"> 
</span><span class="cx">         AX: VoiceOver: Navigating Numbered Lists Causes Number to be announced On Each Line of List
</span></span></pre></div>
<a id="trunkSourceWebCorebridgeruntime_arrayh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/bridge/runtime_array.h (198807 => 198808)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/bridge/runtime_array.h        2016-03-29 22:23:42 UTC (rev 198807)
+++ trunk/Source/WebCore/bridge/runtime_array.h        2016-03-29 22:57:01 UTC (rev 198808)
</span><span class="lines">@@ -75,7 +75,7 @@
</span><span class="cx"> 
</span><span class="cx">     static Structure* createStructure(VM&amp; vm, JSGlobalObject* globalObject, JSValue prototype)
</span><span class="cx">     {
</span><del>-        return Structure::create(vm, globalObject, prototype, TypeInfo(ObjectType, StructureFlags), info(), ArrayClass);
</del><ins>+        return Structure::create(vm, globalObject, prototype, TypeInfo(ArrayType, StructureFlags), info(), ArrayClass);
</ins><span class="cx">     }
</span><span class="cx"> 
</span><span class="cx"> protected:
</span></span></pre>
</div>
</div>

</body>
</html>