<!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>[200426] 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/200426">200426</a></dd>
<dt>Author</dt> <dd>keith_miller@apple.com</dd>
<dt>Date</dt> <dd>2016-05-04 13:15:26 -0700 (Wed, 04 May 2016)</dd>
</dl>
<h3>Log Message</h3>
<pre>Unreviewed, reland <a href="http://trac.webkit.org/projects/webkit/changeset/200149">r200149</a> since the rollout had inconclusive PLT AB testing results.</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>
</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 (200425 => 200426)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/ChangeLog        2016-05-04 20:00:21 UTC (rev 200425)
+++ trunk/LayoutTests/ChangeLog        2016-05-04 20:15:26 UTC (rev 200426)
</span><span class="lines">@@ -1,3 +1,7 @@
</span><ins>+2016-05-04 Keith Miller <keith_miller@apple.com>
+
+ Unreviewed, reland r200149 since the rollout had inconclusive PLT AB testing results.
+
</ins><span class="cx"> 2016-05-04 Joseph Pecoraro <pecoraro@apple.com>
</span><span class="cx">
</span><span class="cx"> Web Inspector: GC Root Path sometimes does not go up to Window
</span></span></pre></div>
<a id="trunkLayoutTestsjsObjectgetOwnPropertyNamesexpectedtxt"></a>
<div class="modfile"><h4>Modified: trunk/LayoutTests/js/Object-getOwnPropertyNames-expected.txt (200425 => 200426)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/js/Object-getOwnPropertyNames-expected.txt        2016-05-04 20:00:21 UTC (rev 200425)
+++ trunk/LayoutTests/js/Object-getOwnPropertyNames-expected.txt        2016-05-04 20:15:26 UTC (rev 200426)
</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', 'replace', 'search', 'species', 'split', 'toPrimitive', 'toStringTag', 'unscopables']
</del><ins>+PASS getSortedOwnPropertyNames(Symbol) is ['for', 'hasInstance', 'isConcatSpreadable', 'iterator', 'keyFor', 'length', 'match', 'name', 'prototype', 'replace', 'search', 'species', 'split', '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 (200425 => 200426)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/js/dom/array-prototype-properties-expected.txt        2016-05-04 20:00:21 UTC (rev 200425)
+++ trunk/LayoutTests/js/dom/array-prototype-properties-expected.txt        2016-05-04 20:15:26 UTC (rev 200426)
</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 (200425 => 200426)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/js/script-tests/Object-getOwnPropertyNames.js        2016-05-04 20:00:21 UTC (rev 200425)
+++ trunk/LayoutTests/js/script-tests/Object-getOwnPropertyNames.js        2016-05-04 20:15:26 UTC (rev 200426)
</span><span class="lines">@@ -70,7 +70,7 @@
</span><span class="cx"> "Error.prototype": "['constructor', 'message', 'name', 'toString']",
</span><span class="cx"> "Math": "['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"> "JSON": "['parse', 'stringify']",
</span><del>- "Symbol": "['for', 'hasInstance', 'iterator', 'keyFor', 'length', 'match', 'name', 'prototype', 'replace', 'search', 'species', 'split', 'toPrimitive', 'toStringTag', 'unscopables']",
</del><ins>+ "Symbol": "['for', 'hasInstance', 'isConcatSpreadable', 'iterator', 'keyFor', 'length', 'match', 'name', 'prototype', 'replace', 'search', 'species', 'split', 'toPrimitive', 'toStringTag', 'unscopables']",
</ins><span class="cx"> "Symbol.prototype": "['constructor', 'toString', 'valueOf']",
</span><span class="cx"> "Map": "['length', 'name', 'prototype']",
</span><span class="cx"> "Map.prototype": "['clear', 'constructor', 'delete', 'entries', 'forEach', 'get', 'has', 'keys', 'set', 'size', 'values']",
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/ChangeLog (200425 => 200426)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/ChangeLog        2016-05-04 20:00:21 UTC (rev 200425)
+++ trunk/Source/JavaScriptCore/ChangeLog        2016-05-04 20:15:26 UTC (rev 200426)
</span><span class="lines">@@ -1,3 +1,7 @@
</span><ins>+2016-05-04 Keith Miller <keith_miller@apple.com>
+
+ Unreviewed, reland r200149 since the rollout had inconclusive PLT AB testing results.
+
</ins><span class="cx"> 2016-05-04 Mark Lam <mark.lam@apple.com>
</span><span class="cx">
</span><span class="cx"> ES6 Function.name inferred from property names of literal objects can break some websites.
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreJavaScriptCorexcodeprojprojectpbxproj"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj (200425 => 200426)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj        2016-05-04 20:00:21 UTC (rev 200425)
+++ trunk/Source/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj        2016-05-04 20:15:26 UTC (rev 200426)
</span><span class="lines">@@ -1183,6 +1183,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">@@ -3318,6 +3319,7 @@
</span><span class="cx">                 53917E7A1B7906E4000EBD33 /* JSGenericTypedArrayViewPrototypeFunctions.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JSGenericTypedArrayViewPrototypeFunctions.h; sourceTree = "<group>"; };
</span><span class="cx">                 53917E7C1B791106000EBD33 /* JSTypedArrayViewPrototype.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JSTypedArrayViewPrototype.h; sourceTree = "<group>"; };
</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 = "<group>"; };
</ins><span class="cx">                 53F256E11B87E28000B4B768 /* JSTypedArrayViewPrototype.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = JSTypedArrayViewPrototype.cpp; sourceTree = "<group>"; };
</span><span class="cx">                 53F6BF6C1C3F060A00F41E5D /* InternalFunctionAllocationProfile.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = InternalFunctionAllocationProfile.h; sourceTree = "<group>"; };
</span><span class="cx">                 593D43CCA0BBE06D89C59707 /* MapDataInlines.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MapDataInlines.h; sourceTree = "<group>"; };
</span><span class="lines">@@ -5678,6 +5680,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">@@ -7523,6 +7526,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 (200425 => 200426)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/builtins/ArrayPrototype.js        2016-05-04 20:00:21 UTC (rev 200425)
+++ trunk/Source/JavaScriptCore/builtins/ArrayPrototype.js        2016-05-04 20:15:26 UTC (rev 200426)
</span><span class="lines">@@ -690,6 +690,94 @@
</span><span class="cx"> return array;
</span><span class="cx"> }
</span><span class="cx">
</span><ins>+function concatSlowPath()
+{
+ "use strict";
+
+ 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) && currentElement[@symbolIsConcatSpreadable];
+ if ((spreadable == @undefined && @isArray(currentElement)) || spreadable) {
+ var length = @toLength(currentElement.length);
+ if (resultIsArray && @isJSArray(currentElement)
+ && @appendMemcpy(result, currentElement)) {
+
+ resultIndex += length;
+ } else {
+ if (length + resultIndex > @MAX_SAFE_INTEGER)
+ throw @TypeError("length exceeded the maximum safe integer");
+ for (var i = 0; i < length; i++) {
+ if (i in currentElement)
+ @putByValDirect(result, resultIndex, currentElement[i]);
+ resultIndex++;
+ }
+ }
+ } else {
+ if (resultIndex >= @MAX_SAFE_INTEGER)
+ throw @TypeError("length exceeded the maximum safe integer");
+ @putByValDirect(result, resultIndex++, currentElement);
+ }
+ currentElement = arguments[argIndex];
+ } while (argIndex++ < argCount);
+
+ result.length = resultIndex;
+ return result;
+}
+
+function concat(first)
+{
+ "use strict";
+
+ if (this == null) {
+ if (this === null)
+ throw new @TypeError("Array.prototype.concat requires that |this| not be null");
+ throw new @TypeError("Array.prototype.concat requires that |this| not be undefined");
+ }
+
+ 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) && @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
+ && constructor === @Array
+ && @isJSArray(array)
+ && @isJSArray(first)
+ // FIXME: these get_by_ids should be "in"s but using "in" here is a 10% regression.
+ // https://bugs.webkit.org/show_bug.cgi?id=155590
+ && array[@symbolIsConcatSpreadable] == @undefined
+ && 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"> "use strict";
</span></span></pre></div>
<a id="trunkSourceJavaScriptCorebytecodeBytecodeIntrinsicRegistrycpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/bytecode/BytecodeIntrinsicRegistry.cpp (200425 => 200426)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/bytecode/BytecodeIntrinsicRegistry.cpp        2016-05-04 20:00:21 UTC (rev 200425)
+++ trunk/Source/JavaScriptCore/bytecode/BytecodeIntrinsicRegistry.cpp        2016-05-04 20:15:26 UTC (rev 200426)
</span><span class="lines">@@ -51,9 +51,11 @@
</span><span class="cx"> m_arrayIterationKindValue.set(m_vm, jsNumber(ArrayIterateValue));
</span><span class="cx"> m_arrayIterationKindKeyValue.set(m_vm, jsNumber(ArrayIterateKeyValue));
</span><span class="cx"> m_MAX_STRING_LENGTH.set(m_vm, jsNumber(JSString::MaxLength));
</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<unsigned>(JSPromise::Status::Pending)));
</span><span class="cx"> m_promiseStateFulfilled.set(m_vm, jsNumber(static_cast<unsigned>(JSPromise::Status::Fulfilled)));
</span><span class="cx"> m_promiseStateRejected.set(m_vm, jsNumber(static_cast<unsigned>(JSPromise::Status::Rejected)));
</span><ins>+ m_symbolIsConcatSpreadable.set(m_vm, Symbol::create(m_vm, static_cast<SymbolImpl&>(*m_vm.propertyNames->isConcatSpreadableSymbol.impl())));
</ins><span class="cx"> m_symbolIterator.set(m_vm, Symbol::create(m_vm, static_cast<SymbolImpl&>(*m_vm.propertyNames->iteratorSymbol.impl())));
</span><span class="cx"> m_symbolMatch.set(m_vm, Symbol::create(m_vm, static_cast<SymbolImpl&>(*m_vm.propertyNames->matchSymbol.impl())));
</span><span class="cx"> m_symbolReplace.set(m_vm, Symbol::create(m_vm, static_cast<SymbolImpl&>(*m_vm.propertyNames->replaceSymbol.impl())));
</span></span></pre></div>
<a id="trunkSourceJavaScriptCorebytecodeBytecodeIntrinsicRegistryh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/bytecode/BytecodeIntrinsicRegistry.h (200425 => 200426)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/bytecode/BytecodeIntrinsicRegistry.h        2016-05-04 20:00:21 UTC (rev 200425)
+++ trunk/Source/JavaScriptCore/bytecode/BytecodeIntrinsicRegistry.h        2016-05-04 20:15:26 UTC (rev 200426)
</span><span class="lines">@@ -53,9 +53,11 @@
</span><span class="cx"> macro(arrayIterationKindValue) \
</span><span class="cx"> macro(arrayIterationKindKeyValue) \
</span><span class="cx"> macro(MAX_STRING_LENGTH) \
</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(symbolReplace) \
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoredfgDFGAbstractInterpreterInlinesh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/dfg/DFGAbstractInterpreterInlines.h (200425 => 200426)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/dfg/DFGAbstractInterpreterInlines.h        2016-05-04 20:00:21 UTC (rev 200425)
+++ trunk/Source/JavaScriptCore/dfg/DFGAbstractInterpreterInlines.h        2016-05-04 20:15:26 UTC (rev 200426)
</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 "ArrayConstructor.h"
</ins><span class="cx"> #include "DFGAbstractInterpreter.h"
</span><span class="cx"> #include "GetByIdStatus.h"
</span><span class="cx"> #include "GetterSetter.h"
</span><span class="lines">@@ -1026,6 +1027,9 @@
</span><span class="cx"> }
</span><span class="cx">
</span><span class="cx"> case IsEmpty:
</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">@@ -1038,6 +1042,28 @@
</span><span class="cx"> if (child.value()) {
</span><span class="cx"> bool constantWasSet = true;
</span><span class="cx"> switch (node->op()) {
</span><ins>+ case IsArrayObject:
+ if (child.value().isObject()) {
+ if (child.value().getObject()->type() == ArrayType) {
+ setConstant(node, jsBoolean(true));
+ break;
+ }
+
+ if (child.value().getObject()->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() && child.value().getObject()->type() == ArrayType));
+ break;
+ case IsArrayConstructor:
+ setConstant(node, jsBoolean(child.value().isObject() && child.value().getObject()->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">@@ -1106,6 +1132,22 @@
</span><span class="cx">
</span><span class="cx"> bool constantWasSet = false;
</span><span class="cx"> switch (node->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 & ~SpecArray)) {
+ setConstant(node, jsBoolean(true));
+ constantWasSet = true;
+ break;
+ }
+
+ if (!(child.m_type & SpecObject)) {
+ setConstant(node, jsBoolean(false));
+ constantWasSet = true;
+ break;
+ }
+
+ break;
</ins><span class="cx"> case IsEmpty: {
</span><span class="cx"> if (child.m_type && !(child.m_type & SpecEmpty)) {
</span><span class="cx"> setConstant(node, jsBoolean(false));
</span><span class="lines">@@ -1904,7 +1946,21 @@
</span><span class="cx"> ASSERT(node->structure());
</span><span class="cx"> forNode(node).set(m_graph, node->structure());
</span><span class="cx"> break;
</span><del>-
</del><ins>+
+ case CallObjectConstructor: {
+ AbstractValue& source = forNode(node->child1());
+ AbstractValue& destination = forNode(node);
+
+ if (!(source.m_type & ~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 (200425 => 200426)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/dfg/DFGByteCodeParser.cpp        2016-05-04 20:00:21 UTC (rev 200425)
+++ trunk/Source/JavaScriptCore/dfg/DFGByteCodeParser.cpp        2016-05-04 20:15:26 UTC (rev 200426)
</span><span class="lines">@@ -45,6 +45,7 @@
</span><span class="cx"> #include "JSLexicalEnvironment.h"
</span><span class="cx"> #include "JSCInlines.h"
</span><span class="cx"> #include "JSModuleEnvironment.h"
</span><ins>+#include "ObjectConstructor.h"
</ins><span class="cx"> #include "PreciseJumpTargets.h"
</span><span class="cx"> #include "PutByIdFlags.h"
</span><span class="cx"> #include "PutByIdStatus.h"
</span><span class="lines">@@ -2157,6 +2158,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">@@ -2633,7 +2662,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->classInfo() == ObjectConstructor::info() && 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 < 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 (200425 => 200426)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/dfg/DFGClobberize.h        2016-05-04 20:00:21 UTC (rev 200425)
+++ trunk/Source/JavaScriptCore/dfg/DFGClobberize.h        2016-05-04 20:15:26 UTC (rev 200426)
</span><span class="lines">@@ -153,6 +153,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 IsEmpty:
</span><span class="cx"> case IsUndefined:
</span><span class="cx"> case IsBoolean:
</span><span class="lines">@@ -194,7 +196,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">@@ -411,6 +414,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 (200425 => 200426)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/dfg/DFGDoesGC.cpp        2016-05-04 20:00:21 UTC (rev 200425)
+++ trunk/Source/JavaScriptCore/dfg/DFGDoesGC.cpp        2016-05-04 20:15:26 UTC (rev 200426)
</span><span class="lines">@@ -153,6 +153,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 IsEmpty:
</span><span class="cx"> case IsUndefined:
</span><span class="cx"> case IsBoolean:
</span><span class="lines">@@ -250,6 +253,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 (200425 => 200426)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/dfg/DFGFixupPhase.cpp        2016-05-04 20:00:21 UTC (rev 200425)
+++ trunk/Source/JavaScriptCore/dfg/DFGFixupPhase.cpp        2016-05-04 20:15:26 UTC (rev 200426)
</span><span class="lines">@@ -1060,7 +1060,18 @@
</span><span class="cx"> fixEdge<Int32Use>(node->child1());
</span><span class="cx"> break;
</span><span class="cx"> }
</span><del>-
</del><ins>+
+ case CallObjectConstructor: {
+ if (node->child1()->shouldSpeculateObject()) {
+ fixEdge<ObjectUse>(node->child1());
+ node->convertToIdentity();
+ break;
+ }
+
+ fixEdge<UntypedUse>(node->child1());
+ break;
+ }
+
</ins><span class="cx"> case ToThis: {
</span><span class="cx"> fixupToThis(node);
</span><span class="cx"> break;
</span><span class="lines">@@ -1530,6 +1541,9 @@
</span><span class="cx"> case ProfileWillCall:
</span><span class="cx"> case ProfileDidCall:
</span><span class="cx"> case DeleteById:
</span><ins>+ case IsArrayObject:
+ case IsJSArray:
+ case IsArrayConstructor:
</ins><span class="cx"> case IsEmpty:
</span><span class="cx"> case IsUndefined:
</span><span class="cx"> case IsBoolean:
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoredfgDFGNodeTypeh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/dfg/DFGNodeType.h (200425 => 200426)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/dfg/DFGNodeType.h        2016-05-04 20:00:21 UTC (rev 200425)
+++ trunk/Source/JavaScriptCore/dfg/DFGNodeType.h        2016-05-04 20:15:26 UTC (rev 200426)
</span><span class="lines">@@ -303,6 +303,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(IsEmpty, NodeResultBoolean) \
</span><span class="cx"> macro(IsUndefined, NodeResultBoolean) \
</span><span class="cx"> macro(IsBoolean, NodeResultBoolean) \
</span><span class="lines">@@ -316,6 +321,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 (200425 => 200426)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/dfg/DFGOperations.cpp        2016-05-04 20:00:21 UTC (rev 200425)
+++ trunk/Source/JavaScriptCore/dfg/DFGOperations.cpp        2016-05-04 20:15:26 UTC (rev 200426)
</span><span class="lines">@@ -26,6 +26,7 @@
</span><span class="cx"> #include "config.h"
</span><span class="cx"> #include "DFGOperations.h"
</span><span class="cx">
</span><ins>+#include "ArrayConstructor.h"
</ins><span class="cx"> #include "ButterflyInlines.h"
</span><span class="cx"> #include "ClonedArguments.h"
</span><span class="cx"> #include "CodeBlock.h"
</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 = &exec->vm();
+ NativeCallFrameTracer tracer(vm, exec);
+
+ JSValue value = JSValue::decode(encodedTarget);
+ ASSERT(!value.isObject());
+
+ if (value.isUndefinedOrNull())
+ return constructEmptyObject(exec, globalObject->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 = &exec->vm();
</span><span class="lines">@@ -710,6 +724,22 @@
</span><span class="cx"> return asRegExpObject(base)->test(exec, globalObject, input);
</span><span class="cx"> }
</span><span class="cx">
</span><ins>+size_t JIT_OPERATION operationIsArrayConstructor(ExecState* exec, EncodedJSValue encodedTarget)
+{
+ VM& vm = exec->vm();
+ NativeCallFrameTracer tracer(&vm, exec);
+
+ return isArrayConstructor(JSValue::decode(encodedTarget));
+}
+
+size_t JIT_OPERATION operationIsArrayObject(ExecState* exec, EncodedJSValue encodedTarget)
+{
+ VM& vm = exec->vm();
+ NativeCallFrameTracer tracer(&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 = &exec->vm();
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoredfgDFGOperationsh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/dfg/DFGOperations.h (200425 => 200426)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/dfg/DFGOperations.h        2016-05-04 20:00:21 UTC (rev 200425)
+++ trunk/Source/JavaScriptCore/dfg/DFGOperations.h        2016-05-04 20:15:26 UTC (rev 200426)
</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 (200425 => 200426)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/dfg/DFGPredictionPropagationPhase.cpp        2016-05-04 20:00:21 UTC (rev 200425)
+++ trunk/Source/JavaScriptCore/dfg/DFGPredictionPropagationPhase.cpp        2016-05-04 20:15:26 UTC (rev 200426)
</span><span class="lines">@@ -762,6 +762,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 IsEmpty:
</span><span class="cx"> case IsUndefined:
</span><span class="cx"> case IsBoolean:
</span><span class="lines">@@ -787,6 +790,10 @@
</span><span class="cx"> break;
</span><span class="cx"> }
</span><span class="cx">
</span><ins>+ case CallObjectConstructor: {
+ setPrediction(SpecObject);
+ break;
+ }
</ins><span class="cx"> case SkipScope:
</span><span class="cx"> case GetGlobalObject: {
</span><span class="cx"> setPrediction(SpecObjectOther);
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoredfgDFGSafeToExecuteh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/dfg/DFGSafeToExecute.h (200425 => 200426)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/dfg/DFGSafeToExecute.h        2016-05-04 20:00:21 UTC (rev 200425)
+++ trunk/Source/JavaScriptCore/dfg/DFGSafeToExecute.h        2016-05-04 20:15:26 UTC (rev 200426)
</span><span class="lines">@@ -253,6 +253,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 IsEmpty:
</span><span class="cx"> case IsUndefined:
</span><span class="cx"> case IsBoolean:
</span><span class="lines">@@ -264,6 +267,7 @@
</span><span class="cx"> case IsRegExpObject:
</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 (200425 => 200426)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/dfg/DFGSpeculativeJIT.cpp        2016-05-04 20:00:21 UTC (rev 200425)
+++ trunk/Source/JavaScriptCore/dfg/DFGSpeculativeJIT.cpp        2016-05-04 20:15:26 UTC (rev 200426)
</span><span class="lines">@@ -1617,7 +1617,7 @@
</span><span class="cx"> dataLog("\n");
</span><span class="cx"> }
</span><span class="cx">
</span><del>- if (Options::validateDFGExceptionHandling() && mayExit(m_jit.graph(), m_currentNode) != DoesNotExit)
</del><ins>+ if (Options::validateDFGExceptionHandling() && (mayExit(m_jit.graph(), m_currentNode) != DoesNotExit || m_currentNode->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">@@ -3372,6 +3372,76 @@
</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->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(&m_jit);
+ moveFalseTo(resultGPR);
+
+ done.link(&m_jit);
+ blessedBooleanResult(resultGPR, node);
+}
+
+void SpeculativeJIT::compileIsArrayObject(Node* node)
+{
+ JSValueOperand value(this, node->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(&m_jit);
+ silentSpillAllRegisters(resultGPR);
+ callOperation(operationIsArrayObject, resultGPR, valueRegs);
+ silentFillAllRegisters(resultGPR);
+ m_jit.exceptionCheck();
+ done.append(m_jit.jump());
+
+ isNotCell.link(&m_jit);
+ m_jit.move(TrustedImm32(false), resultGPR);
+
+ done.link(&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->child1());
+ GPRFlushedCallResult result(this);
+
+ JSValueRegs valueRegs = value.jsValueRegs();
+ GPRReg resultGPR = result.gpr();
+
+ flushRegisters();
+ callOperation(operationIsArrayConstructor, resultGPR, valueRegs);
+ unblessedBooleanResult(resultGPR, node);
+}
+
</ins><span class="cx"> void SpeculativeJIT::compileIsRegExpObject(Node* node)
</span><span class="cx"> {
</span><span class="cx"> JSValueOperand value(this, node->child1());
</span><span class="lines">@@ -3396,6 +3466,28 @@
</span><span class="cx"> blessedBooleanResult(resultGPR, node);
</span><span class="cx"> }
</span><span class="cx">
</span><ins>+void SpeculativeJIT::compileCallObjectConstructor(Node* node)
+{
+ RELEASE_ASSERT(node->child1().useKind() == UntypedUse);
+ JSValueOperand value(this, node->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->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->binaryUseKind()) {
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoredfgDFGSpeculativeJITh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/dfg/DFGSpeculativeJIT.h (200425 => 200426)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/dfg/DFGSpeculativeJIT.h        2016-05-04 20:00:21 UTC (rev 200425)
+++ trunk/Source/JavaScriptCore/dfg/DFGSpeculativeJIT.h        2016-05-04 20:15:26 UTC (rev 200426)
</span><span class="lines">@@ -735,8 +735,11 @@
</span><span class="cx"> void compileInstanceOf(Node*);
</span><span class="cx"> void compileInstanceOfCustom(Node*);
</span><span class="cx">
</span><ins>+ void compileIsJSArray(Node*);
+ void compileIsArrayConstructor(Node*);
+ void compileIsArrayObject(Node*);
</ins><span class="cx"> void compileIsRegExpObject(Node*);
</span><del>-
</del><ins>+
</ins><span class="cx"> void emitCall(Node*);
</span><span class="cx">
</span><span class="cx"> // Called once a node has completed code generation but prior to setting
</span><span class="lines">@@ -1426,6 +1429,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">@@ -1466,10 +1480,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">@@ -1868,6 +1890,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.tagGPR(), arg1.payloadGPR());
+ }
+
</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">@@ -1892,6 +1925,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_EJI operation, GPRReg result, GPRReg arg1Tag, GPRReg arg1Payload, UniquedStringImpl* uid)
</span><span class="cx"> {
</span><span class="cx"> m_jit.setupArgumentsWithExecState(EABI_32BIT_DUMMY_ARG arg1Payload, arg1Tag, TrustedImmPtr(uid));
</span><span class="lines">@@ -2478,6 +2516,7 @@
</span><span class="cx"> void compileLazyJSConstant(Node*);
</span><span class="cx"> void compileMaterializeNewObject(Node*);
</span><span class="cx"> void compileRecordRegExpCachedResult(Node*);
</span><ins>+ void compileCallObjectConstructor(Node*);
</ins><span class="cx"> void compileResolveScope(Node*);
</span><span class="cx"> void compileGetDynamicVar(Node*);
</span><span class="cx"> void compilePutDynamicVar(Node*);
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoredfgDFGSpeculativeJIT32_64cpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/dfg/DFGSpeculativeJIT32_64.cpp (200425 => 200426)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/dfg/DFGSpeculativeJIT32_64.cpp        2016-05-04 20:00:21 UTC (rev 200425)
+++ trunk/Source/JavaScriptCore/dfg/DFGSpeculativeJIT32_64.cpp        2016-05-04 20:15:26 UTC (rev 200426)
</span><span class="lines">@@ -3830,6 +3830,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->child1().useKind() == UntypedUse);
</span><span class="lines">@@ -4500,6 +4505,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->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 (200425 => 200426)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/dfg/DFGSpeculativeJIT64.cpp        2016-05-04 20:00:21 UTC (rev 200425)
+++ trunk/Source/JavaScriptCore/dfg/DFGSpeculativeJIT64.cpp        2016-05-04 20:15:26 UTC (rev 200426)
</span><span class="lines">@@ -3888,7 +3888,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->child1().useKind() == UntypedUse);
</span><span class="cx"> JSValueOperand thisValue(this, node->child1());
</span><span class="lines">@@ -4529,6 +4534,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->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 (200425 => 200426)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/ftl/FTLCapabilities.cpp        2016-05-04 20:00:21 UTC (rev 200425)
+++ trunk/Source/JavaScriptCore/ftl/FTLCapabilities.cpp        2016-05-04 20:15:26 UTC (rev 200426)
</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">@@ -175,6 +176,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 IsEmpty:
</span><span class="cx"> case IsUndefined:
</span><span class="cx"> case IsBoolean:
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreftlFTLLowerDFGToB3cpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/ftl/FTLLowerDFGToB3.cpp (200425 => 200426)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/ftl/FTLLowerDFGToB3.cpp        2016-05-04 20:00:21 UTC (rev 200425)
+++ trunk/Source/JavaScriptCore/ftl/FTLLowerDFGToB3.cpp        2016-05-04 20:15:26 UTC (rev 200426)
</span><span class="lines">@@ -482,6 +482,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">@@ -854,6 +857,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">@@ -1431,6 +1443,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->child1());
+
+ LBasicBlock isCellCase = m_out.newBlock();
+ LBasicBlock slowCase = m_out.newBlock();
+ LBasicBlock continuation = m_out.newBlock();
+
+ m_out.branch(isCell(value, provenType(m_node->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">@@ -5842,6 +5876,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->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->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->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->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->child1())), unsure(isCellCase), unsure(continuation));
+
+ LBasicBlock lastNext = m_out.appendTo(isCellCase, continuation);
+ ValueFromBlock cellResult = m_out.anchor(isArray(value, provenType(m_node->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->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->child1());
</span><span class="lines">@@ -9960,6 +10043,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 & 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 (200425 => 200426)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/jit/JITOperations.h        2016-05-04 20:00:21 UTC (rev 200425)
+++ trunk/Source/JavaScriptCore/jit/JITOperations.h        2016-05-04 20:15:26 UTC (rev 200426)
</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 (200425 => 200426)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/jsc.cpp        2016-05-04 20:00:21 UTC (rev 200425)
+++ trunk/Source/JavaScriptCore/jsc.cpp        2016-05-04 20:15:26 UTC (rev 200426)
</span><span class="lines">@@ -567,6 +567,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">@@ -738,7 +739,8 @@
</span><span class="cx"> void finishCreation(VM& vm, const Vector<String>& arguments)
</span><span class="cx"> {
</span><span class="cx"> Base::finishCreation(vm);
</span><del>-
</del><ins>+
+ addFunction(vm, "dataLogValue", functionDataLogValue, 1);
</ins><span class="cx"> addFunction(vm, "debug", functionDebug, 1);
</span><span class="cx"> addFunction(vm, "describe", functionDescribe, 1);
</span><span class="cx"> addFunction(vm, "describeArray", functionDescribeArray, 1);
</span><span class="lines">@@ -842,6 +844,7 @@
</span><span class="cx"> }
</span><span class="cx">
</span><span class="cx"> putDirect(vm, Identifier::fromString(globalExec(), "console"), jsUndefined());
</span><ins>+ putDirect(vm, vm.propertyNames->printPrivateName, JSFunction::create(vm, this, 1, vm.propertyNames->printPrivateName.string(), functionPrint));
</ins><span class="cx"> }
</span><span class="cx">
</span><span class="cx"> void addFunction(VM& vm, const char* name, NativeFunction function, unsigned arguments)
</span><span class="lines">@@ -1141,6 +1144,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("value is: ", exec->argument(0), "\n");
+ 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->argumentCount() < 1)
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreruntimeArrayConstructorcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/runtime/ArrayConstructor.cpp (200425 => 200426)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/runtime/ArrayConstructor.cpp        2016-05-04 20:00:21 UTC (rev 200425)
+++ trunk/Source/JavaScriptCore/runtime/ArrayConstructor.cpp        2016-05-04 20:15:26 UTC (rev 200426)
</span><span class="lines">@@ -68,7 +68,7 @@
</span><span class="cx"> putDirectWithoutTransition(vm, vm.propertyNames->prototype, arrayPrototype, DontEnum | DontDelete | ReadOnly);
</span><span class="cx"> putDirectWithoutTransition(vm, vm.propertyNames->length, jsNumber(1), ReadOnly | DontEnum | DontDelete);
</span><span class="cx"> putDirectNonIndexAccessor(vm, vm.propertyNames->speciesSymbol, speciesSymbol, Accessor | ReadOnly | DontEnum);
</span><del>- JSC_NATIVE_FUNCTION_WITHOUT_TRANSITION(vm.propertyNames->isArray, arrayConstructorIsArray, DontEnum, 1);
</del><ins>+ JSC_NATIVE_INTRINSIC_FUNCTION_WITHOUT_TRANSITION(vm.propertyNames->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 &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<ArrayConstructor*>(exec->uncheckedArgument(0))));
</del><ins>+ return JSValue::encode(jsBoolean(isArrayConstructor(exec->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 (200425 => 200426)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/runtime/ArrayConstructor.h        2016-05-04 20:00:21 UTC (rev 200425)
+++ trunk/Source/JavaScriptCore/runtime/ArrayConstructor.h        2016-05-04 20:15:26 UTC (rev 200426)
</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<JSObject*>(argumentValue)->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 (200425 => 200426)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/runtime/ArrayPrototype.cpp        2016-05-04 20:00:21 UTC (rev 200425)
+++ trunk/Source/JavaScriptCore/runtime/ArrayPrototype.cpp        2016-05-04 20:15:26 UTC (rev 200426)
</span><span class="lines">@@ -34,6 +34,7 @@
</span><span class="cx"> #include "Error.h"
</span><span class="cx"> #include "Interpreter.h"
</span><span class="cx"> #include "JIT.h"
</span><ins>+#include "JSArrayInlines.h"
</ins><span class="cx"> #include "JSArrayIterator.h"
</span><span class="cx"> #include "JSCBuiltins.h"
</span><span class="cx"> #include "JSCInlines.h"
</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">@@ -91,7 +91,7 @@
</span><span class="cx">
</span><span class="cx"> JSC_NATIVE_FUNCTION_WITHOUT_TRANSITION(vm.propertyNames->toString, arrayProtoFuncToString, DontEnum, 0);
</span><span class="cx"> JSC_NATIVE_FUNCTION_WITHOUT_TRANSITION(vm.propertyNames->toLocaleString, arrayProtoFuncToLocaleString, DontEnum, 0);
</span><del>- JSC_NATIVE_FUNCTION_WITHOUT_TRANSITION("concat", arrayProtoFuncConcat, DontEnum, 1);
</del><ins>+ JSC_BUILTIN_FUNCTION_WITHOUT_TRANSITION("concat", arrayPrototypeConcatCodeGenerator, DontEnum);
</ins><span class="cx"> JSC_BUILTIN_FUNCTION_WITHOUT_TRANSITION("fill", arrayPrototypeFillCodeGenerator, DontEnum);
</span><span class="cx"> JSC_NATIVE_FUNCTION_WITHOUT_TRANSITION(vm.propertyNames->join, arrayProtoFuncJoin, DontEnum, 1);
</span><span class="cx"> JSC_NATIVE_INTRINSIC_FUNCTION_WITHOUT_TRANSITION("pop", arrayProtoFuncPop, DontEnum, 0, ArrayPopIntrinsic);
</span><span class="lines">@@ -588,87 +588,6 @@
</span><span class="cx"> return JSValue::encode(join(*exec, thisObject, separator->view(exec).get()));
</span><span class="cx"> }
</span><span class="cx">
</span><del>-EncodedJSValue JSC_HOST_CALL arrayProtoFuncConcat(ExecState* exec)
-{
- JSValue thisValue = exec->thisValue().toThis(exec, StrictMode);
- unsigned argCount = exec->argumentCount();
- JSValue curArg = thisValue.toObject(exec);
- if (!curArg)
- return JSValue::encode(JSValue());
- Checked<unsigned, RecordOverflow> finalArraySize = 0;
-
- // We need to do species construction before geting the rest of the elements.
- std::pair<SpeciesConstructResult, JSObject*> 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<JSArray*>(curArg);
- if (currentArray) {
- // Can't use JSArray::length here because this might be a RuntimeArray!
- finalArraySize += getLength(exec, currentArray);
- if (exec->hadException())
- return JSValue::encode(jsUndefined());
- } else
- ++finalArraySize;
- if (i == argCount)
- break;
- curArg = exec->uncheckedArgument(i);
- }
-
- if (finalArraySize.hasOverflowed())
- return JSValue::encode(throwOutOfMemoryError(exec));
-
- if (speciesResult.first == SpeciesConstructResult::FastPath && argCount == 1 && previousArray && currentArray && finalArraySize.unsafeGet() < MIN_SPARSE_ARRAY_INDEX) {
- IndexingType type = JSArray::fastConcatType(exec->vm(), *previousArray, *currentArray);
- if (type != NonArray)
- return previousArray->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->hadException())
- return JSValue::encode(jsUndefined());
- }
-
- curArg = thisValue.toObject(exec);
- ASSERT(!exec->hadException());
- unsigned n = 0;
- for (unsigned i = 0; ; ++i) {
- if (JSArray* currentArray = jsDynamicCast<JSArray*>(curArg)) {
- // Can't use JSArray::length here because this might be a RuntimeArray!
- unsigned length = getLength(exec, currentArray);
- if (exec->hadException())
- return JSValue::encode(jsUndefined());
- for (unsigned k = 0; k < length; ++k) {
- JSValue v = getProperty(exec, currentArray, k);
- if (exec->hadException())
- return JSValue::encode(jsUndefined());
- if (v)
- result->putDirectIndex(exec, n, v);
- n++;
- }
- } else {
- result->putDirectIndex(exec, n, curArg);
- n++;
- }
- if (i == argCount)
- break;
- curArg = exec->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->thisValue().toThis(exec, StrictMode);
</span><span class="lines">@@ -1069,6 +988,92 @@
</span><span class="cx"> return JSValue::encode(jsNumber(-1));
</span><span class="cx"> }
</span><span class="cx">
</span><ins>+EncodedJSValue JSC_HOST_CALL arrayProtoPrivateFuncIsJSArray(ExecState* exec)
+{
+ JSValue value = exec->uncheckedArgument(0);
+ if (value.isObject())
+ return JSValue::encode(jsBoolean(value.getObject()->type() == ArrayType));
+ return JSValue::encode(jsBoolean(false));
+}
+
+inline bool moveElements(ExecState* exec, VM& vm, JSArray* target, unsigned targetOffset, JSArray* source, unsigned sourceLength)
+{
+ ASSERT(!hasAnyArrayStorage(source->indexingType()));
+ for (unsigned i = 0; i < sourceLength; ++i) {
+ JSValue value = getProperty(exec, source, i);
+ if (vm.exception())
+ return false;
+ if (value) {
+ target->putDirectIndex(exec, targetOffset + i, value);
+ if (vm.exception())
+ return false;
+ }
+ }
+ return true;
+}
+
+EncodedJSValue JSC_HOST_CALL arrayProtoPrivateFuncConcatMemcpy(ExecState* exec)
+{
+ ASSERT(exec->argumentCount() == 2);
+ VM& vm = exec->vm();
+
+ JSArray* firstArray = jsCast<JSArray*>(exec->uncheckedArgument(0));
+ JSArray* secondArray = jsCast<JSArray*>(exec->uncheckedArgument(1));
+
+ if (!firstArray->canFastCopy(vm, secondArray))
+ return JSValue::encode(jsNull());
+
+ Butterfly* firstButterfly = firstArray->butterfly();
+ Butterfly* secondButterfly = secondArray->butterfly();
+
+ unsigned firstArraySize = firstButterfly->publicLength();
+ unsigned secondArraySize = secondButterfly->publicLength();
+
+ IndexingType type = firstArray->memCopyWithIndexingType(secondArray->indexingType());
+ if (type == NonArray || firstArraySize + secondArraySize >= 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->lexicalGlobalObject()->arrayStructureForIndexingTypeDuringAllocation(type);
+ JSArray* result = JSArray::tryCreateUninitialized(vm, resultStructure, firstArraySize + secondArraySize);
+ if (!result)
+ return JSValue::encode(throwOutOfMemoryError(exec));
+
+ if (type == ArrayWithDouble) {
+ double* buffer = result->butterfly()->contiguousDouble().data();
+ memcpy(buffer, firstButterfly->contiguousDouble().data(), sizeof(JSValue) * firstArraySize);
+ memcpy(buffer + firstArraySize, secondButterfly->contiguousDouble().data(), sizeof(JSValue) * secondArraySize);
+ } else if (type != ArrayWithUndecided) {
+ WriteBarrier<Unknown>* buffer = result->butterfly()->contiguous().data();
+ memcpy(buffer, firstButterfly->contiguous().data(), sizeof(JSValue) * firstArraySize);
+ memcpy(buffer + firstArraySize, secondButterfly->contiguous().data(), sizeof(JSValue) * secondArraySize);
+ }
+
+ result->butterfly()->setPublicLength(firstArraySize + secondArraySize);
+ return JSValue::encode(result);
+}
+
+EncodedJSValue JSC_HOST_CALL arrayProtoPrivateFuncAppendMemcpy(ExecState* exec)
+{
+ ASSERT(exec->argumentCount() == 2);
+
+ JSArray* resultArray = jsCast<JSArray*>(exec->uncheckedArgument(0));
+ JSArray* otherArray = jsCast<JSArray*>(exec->uncheckedArgument(1));
+
+ return JSValue::encode(jsBoolean(resultArray->appendMemcpy(exec, exec->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 (200425 => 200426)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/runtime/ArrayPrototype.h        2016-05-04 20:00:21 UTC (rev 200425)
+++ trunk/Source/JavaScriptCore/runtime/ArrayPrototype.h        2016-05-04 20:15:26 UTC (rev 200426)
</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 (200425 => 200426)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/runtime/CommonIdentifiers.h        2016-05-04 20:00:21 UTC (rev 200425)
+++ trunk/Source/JavaScriptCore/runtime/CommonIdentifiers.h        2016-05-04 20:15:26 UTC (rev 200426)
</span><span class="lines">@@ -309,11 +309,11 @@
</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">
</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(replace) \
</span><span class="lines">@@ -415,9 +415,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><span class="cx"> macro(isConstructor) \
</span><span class="cx"> macro(isRegExpObject) \
</span><ins>+ macro(concatMemcpy) \
+ macro(appendMemcpy) \
</ins><span class="cx"> macro(predictFinalLengthFromArgumunts) \
</span><span class="cx"> macro(print) \
</span><span class="cx"> macro(isSet) \
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreruntimeIntrinsich"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/runtime/Intrinsic.h (200425 => 200426)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/runtime/Intrinsic.h        2016-05-04 20:00:21 UTC (rev 200425)
+++ trunk/Source/JavaScriptCore/runtime/Intrinsic.h        2016-05-04 20:15:26 UTC (rev 200426)
</span><span class="lines">@@ -59,6 +59,9 @@
</span><span class="cx"> RandomIntrinsic,
</span><span class="cx"> FRoundIntrinsic,
</span><span class="cx"> TruncIntrinsic,
</span><ins>+ IsArrayIntrinsic,
+ IsArrayConstructorIntrinsic,
+ IsJSArrayIntrinsic,
</ins><span class="cx"> IsRegExpObjectIntrinsic,
</span><span class="cx"> BoundThisNoArgsFunctionCallIntrinsic,
</span><span class="cx">
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreruntimeJSArraycpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/runtime/JSArray.cpp (200425 => 200426)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/runtime/JSArray.cpp        2016-05-04 20:00:21 UTC (rev 200425)
+++ trunk/Source/JavaScriptCore/runtime/JSArray.cpp        2016-05-04 20:15:26 UTC (rev 200426)
</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& vm, JSC::JSArray* otherArray)
+{
+ if (!canFastCopy(vm, otherArray))
+ return false;
+
+ IndexingType type = indexingType();
+ if (type != memCopyWithIndexingType(otherArray->indexingType()))
+ return false;
+
+ unsigned oldLength = length();
+ unsigned otherLength = otherArray->length();
+ unsigned newLength = oldLength + otherLength;
+ if (newLength >= 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()->contiguousDouble().data() + oldLength, otherArray->butterfly()->contiguousDouble().data(), sizeof(JSValue) * otherLength);
+ else
+ memcpy(butterfly()->contiguous().data() + oldLength, otherArray->butterfly()->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& exec, JSArray& otherArray)
-{
- auto newArrayType = indexingType();
-
- VM& vm = exec.vm();
- ASSERT(newArrayType == fastConcatType(vm, *this, otherArray));
-
- unsigned thisArraySize = m_butterfly.get()->publicLength();
- unsigned otherArraySize = otherArray.m_butterfly.get()->publicLength();
- ASSERT(thisArraySize + otherArraySize < MIN_SPARSE_ARRAY_INDEX);
-
- Structure* resultStructure = exec.lexicalGlobalObject()->arrayStructureForIndexingTypeDuringAllocation(newArrayType);
- JSArray* resultArray = JSArray::tryCreateUninitialized(vm, resultStructure, thisArraySize + otherArraySize);
- if (!resultArray)
- return JSValue::encode(throwOutOfMemoryError(&exec));
-
- auto& resultButterfly = *resultArray->butterfly();
- auto& otherButterfly = *otherArray.butterfly();
- if (newArrayType == ArrayWithDouble) {
- auto buffer = resultButterfly.contiguousDouble().data();
- memcpy(buffer, m_butterfly.get()->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()->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& vm, unsigned startIndex, unsigned count, ArrayStorage* storage)
</span><span class="cx"> {
</span><span class="cx"> unsigned oldLength = storage->length();
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreruntimeJSArrayh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/runtime/JSArray.h (200425 => 200426)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/runtime/JSArray.h        2016-05-04 20:00:21 UTC (rev 200425)
+++ trunk/Source/JavaScriptCore/runtime/JSArray.h        2016-05-04 20:15:26 UTC (rev 200426)
</span><span class="lines">@@ -23,6 +23,7 @@
</span><span class="cx">
</span><span class="cx"> #include "ArrayConventions.h"
</span><span class="cx"> #include "ButterflyInlines.h"
</span><ins>+#include "JSCellInlines.h"
</ins><span class="cx"> #include "JSObject.h"
</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&, unsigned startIndex, unsigned count);
</span><span class="cx">
</span><del>- static IndexingType fastConcatType(VM& vm, JSArray& firstArray, JSArray& secondArray)
- {
- IndexingType type = firstArray.indexingType();
- if (type != secondArray.indexingType())
- return NonArray;
- if (type != ArrayWithDouble && type != ArrayWithInt32 && type != ArrayWithContiguous)
- return NonArray;
- if (firstArray.structure(vm)->holesMustForwardToPrototype(vm)
- || secondArray.structure(vm)->holesMustForwardToPrototype(vm))
- return NonArray;
- return type;
- }
- EncodedJSValue fastConcatWith(ExecState&, JSArray&);
</del><ins>+ bool canFastCopy(VM&, JSArray* otherArray);
+ // This function returns NonArray if the indexing types are not compatable for memcpying.
+ IndexingType memCopyWithIndexingType(IndexingType other);
+ bool appendMemcpy(ExecState*, VM&, 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& 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 class="lines">@@ -297,7 +289,8 @@
</span><span class="cx">
</span><span class="cx"> inline bool isJSArray(JSCell* cell)
</span><span class="cx"> {
</span><del>- return cell->classInfo() == JSArray::info();
</del><ins>+ ASSERT((cell->classInfo() == JSArray::info()) == (cell->type() == ArrayType));
+ return cell->type() == ArrayType;
</ins><span class="cx"> }
</span><span class="cx">
</span><span class="cx"> inline bool isJSArray(JSValue v) { return v.isCell() && isJSArray(v.asCell()); }
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreruntimeJSArrayInlinesh"></a>
<div class="addfile"><h4>Added: trunk/Source/JavaScriptCore/runtime/JSArrayInlines.h (0 => 200426)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/runtime/JSArrayInlines.h         (rev 0)
+++ trunk/Source/JavaScriptCore/runtime/JSArrayInlines.h        2016-05-04 20:15:26 UTC (rev 200426)
</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 "JSArray.h"
+#include "JSCellInlines.h"
+#include "Structure.h"
+
+namespace JSC {
+
+IndexingType JSArray::memCopyWithIndexingType(IndexingType other)
+{
+ IndexingType type = indexingType();
+ if (!(type & IsArray && other & 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)
+ && (other == ArrayWithInt32 || other == ArrayWithContiguous)) {
+ if (other == ArrayWithContiguous)
+ return other;
+ return type;
+ }
+
+ if (type != other)
+ return NonArray;
+
+ return type;
+}
+
+bool JSArray::canFastCopy(VM& vm, JSArray* otherArray)
+{
+ if (hasAnyArrayStorage(this->indexingType()) || hasAnyArrayStorage(otherArray->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->structure(vm)->holesMustForwardToPrototype(vm)
+ || otherArray->structure(vm)->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 (200425 => 200426)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/runtime/JSGlobalObject.cpp        2016-05-04 20:00:21 UTC (rev 200425)
+++ trunk/Source/JavaScriptCore/runtime/JSGlobalObject.cpp        2016-05-04 20:15:26 UTC (rev 200426)
</span><span class="lines">@@ -528,6 +528,8 @@
</span><span class="cx"> putDirectWithoutTransition(vm, vm.propertyNames->Uint32ArrayPrivateName, m_typedArrays[toIndex(TypeUint32)].constructor.get(), DontEnum);
</span><span class="cx"> putDirectWithoutTransition(vm, vm.propertyNames->Float32ArrayPrivateName, m_typedArrays[toIndex(TypeFloat32)].constructor.get(), DontEnum);
</span><span class="cx"> putDirectWithoutTransition(vm, vm.propertyNames->Float64ArrayPrivateName, m_typedArrays[toIndex(TypeFloat64)].constructor.get(), DontEnum);
</span><ins>+ putDirectWithoutTransition(vm, vm.propertyNames->ObjectPrivateName, objectConstructor, DontEnum | DontDelete | ReadOnly);
+ putDirectWithoutTransition(vm, vm.propertyNames->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">@@ -552,7 +554,11 @@
</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><span class="cx"> JSFunction* privateFuncThisNumberValue = JSFunction::create(vm, this, 0, String(), numberProtoFuncValueOf);
</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"> JSObject* arrayIteratorPrototype = ArrayIteratorPrototype::create(vm, this, ArrayIteratorPrototype::createStructure(vm, this, m_iteratorPrototype.get()));
</span><span class="cx"> JSFunction* privateFuncCreateArrayIterator = JSFunction::createBuiltinFunction(vm, arrayPrototypeCreateArrayIteratorConstructorCodeGenerator(vm), this);
</span><span class="lines">@@ -580,7 +586,6 @@
</span><span class="cx"> GlobalPropertyInfo(vm.propertyNames->NaN, jsNaN(), DontEnum | DontDelete | ReadOnly),
</span><span class="cx"> GlobalPropertyInfo(vm.propertyNames->Infinity, jsNumber(std::numeric_limits<double>::infinity()), DontEnum | DontDelete | ReadOnly),
</span><span class="cx"> GlobalPropertyInfo(vm.propertyNames->undefinedKeyword, jsUndefined(), DontEnum | DontDelete | ReadOnly),
</span><del>- GlobalPropertyInfo(vm.propertyNames->ObjectPrivateName, objectConstructor, DontEnum | DontDelete | ReadOnly),
</del><span class="cx"> GlobalPropertyInfo(vm.propertyNames->ownEnumerablePropertyKeysPrivateName, JSFunction::create(vm, this, 0, String(), ownEnumerablePropertyKeys), DontEnum | DontDelete | ReadOnly),
</span><span class="cx"> GlobalPropertyInfo(vm.propertyNames->getTemplateObjectPrivateName, privateFuncGetTemplateObject, DontEnum | DontDelete | ReadOnly),
</span><span class="cx"> GlobalPropertyInfo(vm.propertyNames->enqueueJobPrivateName, JSFunction::create(vm, this, 0, String(), enqueueJob), DontEnum | DontDelete | ReadOnly),
</span><span class="lines">@@ -594,7 +599,6 @@
</span><span class="cx"> GlobalPropertyInfo(vm.propertyNames->hasInstanceBoundFunctionPrivateName, privateFuncHasInstanceBoundFunction, DontEnum | DontDelete | ReadOnly),
</span><span class="cx"> GlobalPropertyInfo(vm.propertyNames->instanceOfPrivateName, privateFuncInstanceOf, DontEnum | DontDelete | ReadOnly),
</span><span class="cx"> GlobalPropertyInfo(vm.propertyNames->BuiltinLogPrivateName, builtinLog, DontEnum | DontDelete | ReadOnly),
</span><del>- GlobalPropertyInfo(vm.propertyNames->ArrayPrivateName, arrayConstructor, DontEnum | DontDelete | ReadOnly),
</del><span class="cx"> GlobalPropertyInfo(vm.propertyNames->NumberPrivateName, numberConstructor, DontEnum | DontDelete | ReadOnly),
</span><span class="cx"> GlobalPropertyInfo(vm.propertyNames->RegExpPrivateName, m_regExpConstructor.get(), DontEnum | DontDelete | ReadOnly),
</span><span class="cx"> GlobalPropertyInfo(vm.propertyNames->StringPrivateName, stringConstructor, DontEnum | DontDelete | ReadOnly),
</span><span class="lines">@@ -617,6 +621,10 @@
</span><span class="cx"> GlobalPropertyInfo(vm.propertyNames->isMapPrivateName, JSFunction::create(vm, this, 1, String(), privateFuncIsMap), DontEnum | DontDelete | ReadOnly),
</span><span class="cx"> GlobalPropertyInfo(vm.propertyNames->isArrayPrivateName, arrayConstructor->getDirect(vm, vm.propertyNames->isArray), DontEnum | DontDelete | ReadOnly),
</span><span class="cx"> GlobalPropertyInfo(vm.propertyNames->isArrayConstructorPrivateName, privateFuncIsArrayConstructor, DontEnum | DontDelete | ReadOnly),
</span><ins>+ GlobalPropertyInfo(vm.propertyNames->isJSArrayPrivateName, privateFuncIsJSArray, DontEnum | DontDelete | ReadOnly),
+ GlobalPropertyInfo(vm.propertyNames->concatMemcpyPrivateName, privateFuncConcatMemcpy, DontEnum | DontDelete | ReadOnly),
+ GlobalPropertyInfo(vm.propertyNames->appendMemcpyPrivateName, privateFuncAppendMemcpy, DontEnum | DontDelete | ReadOnly),
+ GlobalPropertyInfo(vm.propertyNames->builtinNames().concatSlowPathPrivateName(), privateFuncConcatSlowPath, DontEnum | DontDelete | ReadOnly),
</ins><span class="cx"> GlobalPropertyInfo(vm.propertyNames->MapIteratorPrivateName, JSFunction::create(vm, this, 1, String(), privateFuncMapIterator), DontEnum | DontDelete | ReadOnly),
</span><span class="cx"> GlobalPropertyInfo(vm.propertyNames->mapIteratorNextPrivateName, JSFunction::create(vm, this, 0, String(), privateFuncMapIteratorNext), DontEnum | DontDelete | ReadOnly),
</span><span class="cx"> GlobalPropertyInfo(vm.propertyNames->builtinNames().arrayIteratorValueNextPrivateName(), privateFuncArrayIteratorValueNext, DontEnum | DontDelete | ReadOnly),
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreruntimeJSTypeh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/runtime/JSType.h (200425 => 200426)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/runtime/JSType.h        2016-05-04 20:00:21 UTC (rev 200425)
+++ trunk/Source/JavaScriptCore/runtime/JSType.h        2016-05-04 20:15:26 UTC (rev 200426)
</span><span class="lines">@@ -60,6 +60,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 (200425 => 200426)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/runtime/ObjectConstructor.h        2016-05-04 20:00:21 UTC (rev 200425)
+++ trunk/Source/JavaScriptCore/runtime/ObjectConstructor.h        2016-05-04 20:15:26 UTC (rev 200426)
</span><span class="lines">@@ -91,6 +91,13 @@
</span><span class="cx"> return constructEmptyObject(exec, exec->lexicalGlobalObject()->objectStructureForObjectConstructor());
</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->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& descriptor)
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoretestses6yaml"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/tests/es6.yaml (200425 => 200426)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/tests/es6.yaml        2016-05-04 20:00:21 UTC (rev 200425)
+++ trunk/Source/JavaScriptCore/tests/es6.yaml        2016-05-04 20:15:26 UTC (rev 200426)
</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 => 200426)</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-05-04 20:15:26 UTC (rev 200426)
</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 < 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 < 100000; i++) {
+ if (!arrayEq(Array.prototype.concat.call(o,o), [o,o]))
+ throw "failed normally with an object"
+ }
+
+ // Test it works with spreadable true
+ o[Symbol.isConcatSpreadable] = true;
+ for (let i = 0; i < 100000; i++) {
+ let result = Array.prototype.concat.call(o,o)
+ if (!arrayEq(result, [1,2,3,1,2,3]))
+ throw "failed with spread got: " + result;
+ }
+
+ // Test it works with many things
+ o[Symbol.isConcatSpreadable] = true;
+ let other = {}
+ for (let i = 0; i < 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 "failed with spread got: " + result;
+ }
+
+ // Test it works with strings
+ String.prototype[Symbol.isConcatSpreadable] = true;
+ for (let i = 0; i < 100000; i++) {
+ let result = Array.prototype.concat.call("hi","hi")
+ // This is what the spec says is the correct answer... D:
+ if (!arrayEq(result, ["h", "i", "hi"]))
+ throw "failed with string got: " + result + " on iteration " + i;
+ }
+}
</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 => 200426)</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-05-04 20:15:26 UTC (rev 200426)
</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 < 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 < 100000; i++) {
+ if (!arrayEq(concat.call(p,p), [1,2,3,1,2,3]))
+ throw "bad";
+ }
+ revoke();
+ failed = true;
+ try {
+ concat.call(p,p);
+ } catch (e) {
+ failed = false;
+ }
+
+ if (failed)
+ throw "bad"
+
+}
</ins></span></pre></div>
<a id="trunkSourceJavaScriptCoretestsstressarrayconcatspreadproxyjs"></a>
<div class="addfile"><h4>Added: trunk/Source/JavaScriptCore/tests/stress/array-concat-spread-proxy.js (0 => 200426)</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-05-04 20:15:26 UTC (rev 200426)
</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 < 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 < 100000; i++) {
+ if (!arrayEq(Array.prototype.concat.call(p,p), [1,2,3,1,2,3]))
+ throw "failed normally with a proxy"
+ }
+
+ // Test it works with spreadable false.
+ p[Symbol.isConcatSpreadable] = false;
+ for (let i = 0; i < 100000; i++) {
+ if (!arrayEq(Array.prototype.concat.call(p,p), [p,p]))
+ throw "failed with no spread"
+ }
+
+ 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 => 200426)</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-05-04 20:15:26 UTC (rev 200426)
</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 < a.length; i++) {
+ if (a[i] !== b[i])
+ return false;
+ }
+ return true;
+}
+
+
+{
+
+ array = [1,2];
+ Object.defineProperty(array, 2, { get: () => { return 1; } });
+
+ for (let i = 0; i < 100000; i++) {
+ if (!arrayEq(Array.prototype.concat.call(array,array), [1,2,1,1,2,1]))
+ throw "failed normally with a getter"
+ if (!arrayEq(Array.prototype.concat.call([],array), [1,2,1]))
+ throw "failed with undecided and a getter"
+ }
+
+ // Test with indexed types on prototype.
+ array = [1,2];
+ array.length = 3;
+ Array.prototype[2] = 1;
+
+ for (let i = 0; i < 100000; i++) {
+ if (!arrayEq(Array.prototype.concat.call(array,array), [1,2,1,1,2,1]))
+ throw "failed normally with an indexed prototype"
+ if (!arrayEq(Array.prototype.concat.call([],array), [1,2,1]))
+ throw "failed with undecided and an indexed prototype"
+ }
+}
</ins></span></pre></div>
<a id="trunkSourceJavaScriptCoretestsstressarrayspeciesconfigarrayconstructorjs"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/tests/stress/array-species-config-array-constructor.js (200425 => 200426)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/tests/stress/array-species-config-array-constructor.js        2016-05-04 20:00:21 UTC (rev 200425)
+++ trunk/Source/JavaScriptCore/tests/stress/array-species-config-array-constructor.js        2016-05-04 20:15:26 UTC (rev 200426)
</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, "length", { 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 "concat failed";
</span></span></pre>
</div>
</div>
</body>
</html>