<!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>[181182] branches/safari-600.1.4.15-branch/Source/JavaScriptCore</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/181182">181182</a></dd>
<dt>Author</dt> <dd>lforschler@apple.com</dd>
<dt>Date</dt> <dd>2015-03-06 14:29:10 -0800 (Fri, 06 Mar 2015)</dd>
</dl>

<h3>Log Message</h3>
<pre>Merged <a href="http://trac.webkit.org/projects/webkit/changeset/180234">r180234</a>.  rdar://problem/20057246</pre>

<h3>Modified Paths</h3>
<ul>
<li><a href="#branchessafari6001415branchSourceJavaScriptCoreChangeLog">branches/safari-600.1.4.15-branch/Source/JavaScriptCore/ChangeLog</a></li>
<li><a href="#branchessafari6001415branchSourceJavaScriptCorejitJITOpcodescpp">branches/safari-600.1.4.15-branch/Source/JavaScriptCore/jit/JITOpcodes.cpp</a></li>
<li><a href="#branchessafari6001415branchSourceJavaScriptCorellintLowLevelInterpreterasm">branches/safari-600.1.4.15-branch/Source/JavaScriptCore/llint/LowLevelInterpreter.asm</a></li>
<li><a href="#branchessafari6001415branchSourceJavaScriptCorellintLowLevelInterpreter64asm">branches/safari-600.1.4.15-branch/Source/JavaScriptCore/llint/LowLevelInterpreter64.asm</a></li>
</ul>

<h3>Added Paths</h3>
<ul>
<li><a href="#branchessafari6001415branchSourceJavaScriptCoretestsstressthrowfromftlcallicslowpathcellsjs">branches/safari-600.1.4.15-branch/Source/JavaScriptCore/tests/stress/throw-from-ftl-call-ic-slow-path-cells.js</a></li>
<li><a href="#branchessafari6001415branchSourceJavaScriptCoretestsstressthrowfromftlcallicslowpathundefinedjs">branches/safari-600.1.4.15-branch/Source/JavaScriptCore/tests/stress/throw-from-ftl-call-ic-slow-path-undefined.js</a></li>
<li><a href="#branchessafari6001415branchSourceJavaScriptCoretestsstressthrowfromftlcallicslowpathjs">branches/safari-600.1.4.15-branch/Source/JavaScriptCore/tests/stress/throw-from-ftl-call-ic-slow-path.js</a></li>
</ul>

</div>
<div id="patch">
<h3>Diff</h3>
<a id="branchessafari6001415branchSourceJavaScriptCoreChangeLog"></a>
<div class="modfile"><h4>Modified: branches/safari-600.1.4.15-branch/Source/JavaScriptCore/ChangeLog (181181 => 181182)</h4>
<pre class="diff"><span>
<span class="info">--- branches/safari-600.1.4.15-branch/Source/JavaScriptCore/ChangeLog        2015-03-06 22:25:05 UTC (rev 181181)
+++ branches/safari-600.1.4.15-branch/Source/JavaScriptCore/ChangeLog        2015-03-06 22:29:10 UTC (rev 181182)
</span><span class="lines">@@ -1,5 +1,29 @@
</span><span class="cx"> 2015-03-06  Lucas Forschler  &lt;lforschler@apple.com&gt;
</span><span class="cx"> 
</span><ins>+        Merge r180234
+
+    2015-02-17  Filip Pizlo  &lt;fpizlo@apple.com&gt;
+
+            Throwing from an FTL call IC slow path may result in tag registers being clobbered on 64-bit CPUs
+            https://bugs.webkit.org/show_bug.cgi?id=141717
+            rdar://problem/19863382
+
+            Reviewed by Geoffrey Garen.
+
+            The best solution is to ensure that the engine catching an exception restores tag registers.
+
+            Each of these new test cases reliably crashed prior to this patch and they don't crash at all now.
+
+            * jit/JITOpcodes.cpp:
+            (JSC::JIT::emit_op_catch):
+            * llint/LowLevelInterpreter.asm:
+            * llint/LowLevelInterpreter64.asm:
+            * tests/stress/throw-from-ftl-call-ic-slow-path-cells.js: Added.
+            * tests/stress/throw-from-ftl-call-ic-slow-path-undefined.js: Added.
+            * tests/stress/throw-from-ftl-call-ic-slow-path.js: Added.
+
+2015-03-06  Lucas Forschler  &lt;lforschler@apple.com&gt;
+
</ins><span class="cx">         Merge r181030
</span><span class="cx"> 
</span><span class="cx">     2015-03-04  Filip Pizlo  &lt;fpizlo@apple.com&gt;
</span></span></pre></div>
<a id="branchessafari6001415branchSourceJavaScriptCorejitJITOpcodescpp"></a>
<div class="modfile"><h4>Modified: branches/safari-600.1.4.15-branch/Source/JavaScriptCore/jit/JITOpcodes.cpp (181181 => 181182)</h4>
<pre class="diff"><span>
<span class="info">--- branches/safari-600.1.4.15-branch/Source/JavaScriptCore/jit/JITOpcodes.cpp        2015-03-06 22:25:05 UTC (rev 181181)
+++ branches/safari-600.1.4.15-branch/Source/JavaScriptCore/jit/JITOpcodes.cpp        2015-03-06 22:29:10 UTC (rev 181182)
</span><span class="lines">@@ -626,6 +626,11 @@
</span><span class="cx"> 
</span><span class="cx"> void JIT::emit_op_catch(Instruction* currentInstruction)
</span><span class="cx"> {
</span><ins>+    // Gotta restore the tag registers. We could be throwing from FTL, which may
+    // clobber them.
+    move(TrustedImm64(TagTypeNumber), tagTypeNumberRegister);
+    move(TrustedImm64(TagMask), tagMaskRegister);
+    
</ins><span class="cx">     move(TrustedImmPtr(m_vm), regT3);
</span><span class="cx">     load64(Address(regT3, VM::callFrameForThrowOffset()), callFrameRegister);
</span><span class="cx"> 
</span></span></pre></div>
<a id="branchessafari6001415branchSourceJavaScriptCorellintLowLevelInterpreterasm"></a>
<div class="modfile"><h4>Modified: branches/safari-600.1.4.15-branch/Source/JavaScriptCore/llint/LowLevelInterpreter.asm (181181 => 181182)</h4>
<pre class="diff"><span>
<span class="info">--- branches/safari-600.1.4.15-branch/Source/JavaScriptCore/llint/LowLevelInterpreter.asm        2015-03-06 22:25:05 UTC (rev 181181)
+++ branches/safari-600.1.4.15-branch/Source/JavaScriptCore/llint/LowLevelInterpreter.asm        2015-03-06 22:29:10 UTC (rev 181182)
</span><span class="lines">@@ -63,6 +63,8 @@
</span><span class="cx"> const ValueTrue       = TagBitTypeOther | TagBitBool | 1
</span><span class="cx"> const ValueUndefined  = TagBitTypeOther | TagBitUndefined
</span><span class="cx"> const ValueNull       = TagBitTypeOther
</span><ins>+    const TagTypeNumber   = 0xffff000000000000
+    const TagMask         = TagTypeNumber | TagBitTypeOther
</ins><span class="cx"> else
</span><span class="cx"> const Int32Tag = -1
</span><span class="cx"> const BooleanTag = -2
</span></span></pre></div>
<a id="branchessafari6001415branchSourceJavaScriptCorellintLowLevelInterpreter64asm"></a>
<div class="modfile"><h4>Modified: branches/safari-600.1.4.15-branch/Source/JavaScriptCore/llint/LowLevelInterpreter64.asm (181181 => 181182)</h4>
<pre class="diff"><span>
<span class="info">--- branches/safari-600.1.4.15-branch/Source/JavaScriptCore/llint/LowLevelInterpreter64.asm        2015-03-06 22:25:05 UTC (rev 181181)
+++ branches/safari-600.1.4.15-branch/Source/JavaScriptCore/llint/LowLevelInterpreter64.asm        2015-03-06 22:29:10 UTC (rev 181182)
</span><span class="lines">@@ -1978,6 +1978,11 @@
</span><span class="cx"> 
</span><span class="cx"> 
</span><span class="cx"> _llint_op_catch:
</span><ins>+    # Gotta restore the tag registers. We could be throwing from FTL, which may
+    # clobber them.
+    move TagTypeNumber, tagTypeNumber
+    move TagMask, tagMask
+    
</ins><span class="cx">     # This is where we end up from the JIT's throw trampoline (because the
</span><span class="cx">     # machine code return address will be set to _llint_op_catch), and from
</span><span class="cx">     # the interpreter's throw trampoline (see _llint_throw_trampoline).
</span></span></pre></div>
<a id="branchessafari6001415branchSourceJavaScriptCoretestsstressthrowfromftlcallicslowpathcellsjsfromrev180234trunkSourceJavaScriptCoretestsstressthrowfromftlcallicslowpathcellsjs"></a>
<div class="copfile"><h4>Copied: branches/safari-600.1.4.15-branch/Source/JavaScriptCore/tests/stress/throw-from-ftl-call-ic-slow-path-cells.js (from rev 180234, trunk/Source/JavaScriptCore/tests/stress/throw-from-ftl-call-ic-slow-path-cells.js) (0 => 181182)</h4>
<pre class="diff"><span>
<span class="info">--- branches/safari-600.1.4.15-branch/Source/JavaScriptCore/tests/stress/throw-from-ftl-call-ic-slow-path-cells.js                                (rev 0)
+++ branches/safari-600.1.4.15-branch/Source/JavaScriptCore/tests/stress/throw-from-ftl-call-ic-slow-path-cells.js        2015-03-06 22:29:10 UTC (rev 181182)
</span><span class="lines">@@ -0,0 +1,192 @@
</span><ins>+// Attempts to induce a crash resulting from the FTL emitting code that clobbers the tag registers and then
+// throwing an exception without restoring those tag registers' values.
+
+function ftlFunction(array, callee) {
+    // Gotta use lots of gprs.
+    var x0 = array[0];
+    var x1 = array[1];
+    var x2 = array[2];
+    var x3 = array[3];
+    var x4 = array[4];
+    var x5 = array[5];
+    var x6 = array[6];
+    var x7 = array[7];
+    var x8 = array[8];
+    var x9 = array[9];
+    var x10 = array[10];
+    var x11 = array[11];
+    var x12 = array[12];
+    var x13 = array[13];
+    var x14 = array[14];
+    var x15 = array[15];
+    var x16 = array[16];
+    var x17 = array[17];
+    var x18 = array[18];
+    var x19 = array[19];
+    var x20 = array[20];
+    var x21 = array[21];
+    var x22 = array[22];
+    var x23 = array[23];
+    var x24 = array[24];
+    var x25 = array[25];
+    var x26 = array[26];
+    var x27 = array[27];
+    var x28 = array[28];
+    var x29 = array[29];
+    var x30 = array[30];
+    var x31 = array[31];
+    var x32 = array[32];
+    var x33 = array[33];
+    var x34 = array[34];
+    var x35 = array[35];
+    var x36 = array[36];
+    var x37 = array[37];
+    var x38 = array[38];
+    var x39 = array[39];
+    var x40 = array[40];
+    var x41 = array[41];
+    var x42 = array[42];
+    var x43 = array[43];
+    var x44 = array[44];
+    var x45 = array[45];
+    var x46 = array[46];
+    var x47 = array[47];
+    var x48 = array[48];
+    var x49 = array[49];
+    var x50 = array[50];
+    var x51 = array[51];
+    var x52 = array[52];
+    var x53 = array[53];
+    var x54 = array[54];
+    var x55 = array[55];
+    var x56 = array[56];
+    var x57 = array[57];
+    var x58 = array[58];
+    var x59 = array[59];
+    var x60 = array[60];
+    var x61 = array[61];
+    var x62 = array[62];
+    var x63 = array[63];
+    
+    // Make a call that will throw, when we ask it to.
+    callee(&quot;hello&quot;);
+    
+    // Use all of those crazy values.
+    return [x0, x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, x11, x12, x13, x14, x15, x16, x17, x18, x19, x20, x21, x22, x23, x24, x25, x26, x27, x28, x29, x30, x31, x32, x33, x34, x35, x36, x37, x38, x39, x40, x41, x42, x43, x44, x45, x46, x47, x48, x49, x50, x51, x52, x53, x54, x55, x56, x57, x58, x59, x60, x61, x62, x63]
+}
+
+noInline(ftlFunction);
+
+// Create some callees that are too crazy to get inlined or devirtualized, but that don't have effects.
+
+function happyCallee0() { return 0 };
+function happyCallee1() { return 1 };
+function happyCallee2() { return 2 };
+function happyCallee3() { return 3 };
+function happyCallee4() { return 4 };
+function happyCallee5() { return 5 };
+function happyCallee6() { return 6 };
+function happyCallee7() { return 7 };
+function happyCallee8() { return 8 };
+function happyCallee9() { return 9 };
+function happyCallee10() { return 10 };
+function happyCallee11() { return 11 };
+function happyCallee12() { return 12 };
+function happyCallee13() { return 13 };
+function happyCallee14() { return 14 };
+function happyCallee15() { return 15 };
+function happyCallee16() { return 16 };
+function happyCallee17() { return 17 };
+function happyCallee18() { return 18 };
+function happyCallee19() { return 19 };
+function happyCallee20() { return 20 };
+function happyCallee21() { return 21 };
+function happyCallee22() { return 22 };
+function happyCallee23() { return 23 };
+function happyCallee24() { return 24 };
+function happyCallee25() { return 25 };
+function happyCallee26() { return 26 };
+function happyCallee27() { return 27 };
+function happyCallee28() { return 28 };
+function happyCallee29() { return 29 };
+function happyCallee30() { return 30 };
+function happyCallee31() { return 31 };
+function happyCallee32() { return 32 };
+function happyCallee33() { return 33 };
+function happyCallee34() { return 34 };
+function happyCallee35() { return 35 };
+function happyCallee36() { return 36 };
+function happyCallee37() { return 37 };
+function happyCallee38() { return 38 };
+function happyCallee39() { return 39 };
+function happyCallee40() { return 40 };
+function happyCallee41() { return 41 };
+function happyCallee42() { return 42 };
+function happyCallee43() { return 43 };
+function happyCallee44() { return 44 };
+function happyCallee45() { return 45 };
+function happyCallee46() { return 46 };
+function happyCallee47() { return 47 };
+function happyCallee48() { return 48 };
+function happyCallee49() { return 49 };
+function happyCallee50() { return 50 };
+function happyCallee51() { return 51 };
+function happyCallee52() { return 52 };
+function happyCallee53() { return 53 };
+function happyCallee54() { return 54 };
+function happyCallee55() { return 55 };
+function happyCallee56() { return 56 };
+function happyCallee57() { return 57 };
+function happyCallee58() { return 58 };
+function happyCallee59() { return 59 };
+function happyCallee60() { return 60 };
+function happyCallee61() { return 61 };
+function happyCallee62() { return 62 };
+function happyCallee63() { return 63 };
+
+var happyCallees = [happyCallee0, happyCallee1, happyCallee2, happyCallee3, happyCallee4, happyCallee5, happyCallee6, happyCallee7, happyCallee8, happyCallee9, happyCallee10, happyCallee11, happyCallee12, happyCallee13, happyCallee14, happyCallee15, happyCallee16, happyCallee17, happyCallee18, happyCallee19, happyCallee20, happyCallee21, happyCallee22, happyCallee23, happyCallee24, happyCallee25, happyCallee26, happyCallee27, happyCallee28, happyCallee29, happyCallee30, happyCallee31, happyCallee32, happyCallee33, happyCallee34, happyCallee35, happyCallee36, happyCallee37, happyCallee38, happyCallee39, happyCallee40, happyCallee41, happyCallee42, happyCallee43, happyCallee44, happyCallee45, happyCallee46, happyCallee47, happyCallee48, happyCallee49, happyCallee50, happyCallee51, happyCallee52, happyCallee53, happyCallee54, happyCallee55, happyCallee56, happyCallee57, happyCallee58, happyCallee59, happyCallee60, happyCallee61, happyCallee62, happyCallee63];
+
+for (var i = 0; i &lt; happyCallees.length; ++i)
+    noInline(happyCallees[i]);
+
+// Unlike the other test (throw-from-ftl-call-ic-slow-path.js), we want to populate the registers with cells in
+// this test.
+var array = new Array();
+for (var i = 0; i &lt; 64; ++i)
+    array[i] = new Object();
+
+// Now, do some warming up.
+for (var i = 0; i &lt; 100000; ++i) {
+    var result = ftlFunction(array, happyCallees[i % happyCallees.length]);
+    if (result.length != array.length)
+        throw &quot;Error: bad length: &quot; + result;
+    for (var j = 0; j &lt; result.length; ++j) {
+        if (result[j] != array[j])
+            throw &quot;Error: bad entry at j = &quot; + j + &quot;: &quot; + result;
+    }
+}
+
+// Finally, attempt to trigger the bug.
+var notACell = 42;
+for (var i = 0; i &lt; 100; ++i) {
+    try {
+        ftlFunction(array, Int8Array);
+    } catch (e) {
+        if (e.message.indexOf(&quot;not a function&quot;) &lt; 0)
+            throw &quot;Error: bad exception message: &quot; + e.message;
+        var result = notACell.f;
+        if (result !== void 0) {
+            print(&quot;Bad outcome of accessing f on notACell.&quot;);
+            print(&quot;Here's notACell:&quot;, notACell, describe(notACell));
+            print(&quot;Here's the result:&quot;, result, describe(result));
+            throw &quot;Error: bad outcome of accessing f on &quot; + notACell + &quot;: &quot; + result;
+        }
+        var result2 = result + 5;
+        var result3 = notACell + 5;
+        if (&quot;&quot; + result2 != &quot;NaN&quot;)
+            throw &quot;Error: bad outcome of adding 5 to result: &quot; + result2;
+        if (result3 != 47)
+            throw &quot;Error: bad outcome of adding 5 to 42: &quot; + result3;
+    }
+}
+
</ins></span></pre></div>
<a id="branchessafari6001415branchSourceJavaScriptCoretestsstressthrowfromftlcallicslowpathundefinedjsfromrev180234trunkSourceJavaScriptCoretestsstressthrowfromftlcallicslowpathundefinedjs"></a>
<div class="copfile"><h4>Copied: branches/safari-600.1.4.15-branch/Source/JavaScriptCore/tests/stress/throw-from-ftl-call-ic-slow-path-undefined.js (from rev 180234, trunk/Source/JavaScriptCore/tests/stress/throw-from-ftl-call-ic-slow-path-undefined.js) (0 => 181182)</h4>
<pre class="diff"><span>
<span class="info">--- branches/safari-600.1.4.15-branch/Source/JavaScriptCore/tests/stress/throw-from-ftl-call-ic-slow-path-undefined.js                                (rev 0)
+++ branches/safari-600.1.4.15-branch/Source/JavaScriptCore/tests/stress/throw-from-ftl-call-ic-slow-path-undefined.js        2015-03-06 22:29:10 UTC (rev 181182)
</span><span class="lines">@@ -0,0 +1,192 @@
</span><ins>+// Attempts to induce a crash resulting from the FTL emitting code that clobbers the tag registers and then
+// throwing an exception without restoring those tag registers' values.
+
+function ftlFunction(array, callee) {
+    // Gotta use lots of gprs.
+    var x0 = array[0];
+    var x1 = array[1];
+    var x2 = array[2];
+    var x3 = array[3];
+    var x4 = array[4];
+    var x5 = array[5];
+    var x6 = array[6];
+    var x7 = array[7];
+    var x8 = array[8];
+    var x9 = array[9];
+    var x10 = array[10];
+    var x11 = array[11];
+    var x12 = array[12];
+    var x13 = array[13];
+    var x14 = array[14];
+    var x15 = array[15];
+    var x16 = array[16];
+    var x17 = array[17];
+    var x18 = array[18];
+    var x19 = array[19];
+    var x20 = array[20];
+    var x21 = array[21];
+    var x22 = array[22];
+    var x23 = array[23];
+    var x24 = array[24];
+    var x25 = array[25];
+    var x26 = array[26];
+    var x27 = array[27];
+    var x28 = array[28];
+    var x29 = array[29];
+    var x30 = array[30];
+    var x31 = array[31];
+    var x32 = array[32];
+    var x33 = array[33];
+    var x34 = array[34];
+    var x35 = array[35];
+    var x36 = array[36];
+    var x37 = array[37];
+    var x38 = array[38];
+    var x39 = array[39];
+    var x40 = array[40];
+    var x41 = array[41];
+    var x42 = array[42];
+    var x43 = array[43];
+    var x44 = array[44];
+    var x45 = array[45];
+    var x46 = array[46];
+    var x47 = array[47];
+    var x48 = array[48];
+    var x49 = array[49];
+    var x50 = array[50];
+    var x51 = array[51];
+    var x52 = array[52];
+    var x53 = array[53];
+    var x54 = array[54];
+    var x55 = array[55];
+    var x56 = array[56];
+    var x57 = array[57];
+    var x58 = array[58];
+    var x59 = array[59];
+    var x60 = array[60];
+    var x61 = array[61];
+    var x62 = array[62];
+    var x63 = array[63];
+    
+    // Make a call that will throw, when we ask it to.
+    callee(&quot;hello&quot;);
+    
+    // Use all of those crazy values.
+    return [x0, x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, x11, x12, x13, x14, x15, x16, x17, x18, x19, x20, x21, x22, x23, x24, x25, x26, x27, x28, x29, x30, x31, x32, x33, x34, x35, x36, x37, x38, x39, x40, x41, x42, x43, x44, x45, x46, x47, x48, x49, x50, x51, x52, x53, x54, x55, x56, x57, x58, x59, x60, x61, x62, x63]
+}
+
+noInline(ftlFunction);
+
+// Create some callees that are too crazy to get inlined or devirtualized, but that don't have effects.
+
+function happyCallee0() { return 0 };
+function happyCallee1() { return 1 };
+function happyCallee2() { return 2 };
+function happyCallee3() { return 3 };
+function happyCallee4() { return 4 };
+function happyCallee5() { return 5 };
+function happyCallee6() { return 6 };
+function happyCallee7() { return 7 };
+function happyCallee8() { return 8 };
+function happyCallee9() { return 9 };
+function happyCallee10() { return 10 };
+function happyCallee11() { return 11 };
+function happyCallee12() { return 12 };
+function happyCallee13() { return 13 };
+function happyCallee14() { return 14 };
+function happyCallee15() { return 15 };
+function happyCallee16() { return 16 };
+function happyCallee17() { return 17 };
+function happyCallee18() { return 18 };
+function happyCallee19() { return 19 };
+function happyCallee20() { return 20 };
+function happyCallee21() { return 21 };
+function happyCallee22() { return 22 };
+function happyCallee23() { return 23 };
+function happyCallee24() { return 24 };
+function happyCallee25() { return 25 };
+function happyCallee26() { return 26 };
+function happyCallee27() { return 27 };
+function happyCallee28() { return 28 };
+function happyCallee29() { return 29 };
+function happyCallee30() { return 30 };
+function happyCallee31() { return 31 };
+function happyCallee32() { return 32 };
+function happyCallee33() { return 33 };
+function happyCallee34() { return 34 };
+function happyCallee35() { return 35 };
+function happyCallee36() { return 36 };
+function happyCallee37() { return 37 };
+function happyCallee38() { return 38 };
+function happyCallee39() { return 39 };
+function happyCallee40() { return 40 };
+function happyCallee41() { return 41 };
+function happyCallee42() { return 42 };
+function happyCallee43() { return 43 };
+function happyCallee44() { return 44 };
+function happyCallee45() { return 45 };
+function happyCallee46() { return 46 };
+function happyCallee47() { return 47 };
+function happyCallee48() { return 48 };
+function happyCallee49() { return 49 };
+function happyCallee50() { return 50 };
+function happyCallee51() { return 51 };
+function happyCallee52() { return 52 };
+function happyCallee53() { return 53 };
+function happyCallee54() { return 54 };
+function happyCallee55() { return 55 };
+function happyCallee56() { return 56 };
+function happyCallee57() { return 57 };
+function happyCallee58() { return 58 };
+function happyCallee59() { return 59 };
+function happyCallee60() { return 60 };
+function happyCallee61() { return 61 };
+function happyCallee62() { return 62 };
+function happyCallee63() { return 63 };
+
+var happyCallees = [happyCallee0, happyCallee1, happyCallee2, happyCallee3, happyCallee4, happyCallee5, happyCallee6, happyCallee7, happyCallee8, happyCallee9, happyCallee10, happyCallee11, happyCallee12, happyCallee13, happyCallee14, happyCallee15, happyCallee16, happyCallee17, happyCallee18, happyCallee19, happyCallee20, happyCallee21, happyCallee22, happyCallee23, happyCallee24, happyCallee25, happyCallee26, happyCallee27, happyCallee28, happyCallee29, happyCallee30, happyCallee31, happyCallee32, happyCallee33, happyCallee34, happyCallee35, happyCallee36, happyCallee37, happyCallee38, happyCallee39, happyCallee40, happyCallee41, happyCallee42, happyCallee43, happyCallee44, happyCallee45, happyCallee46, happyCallee47, happyCallee48, happyCallee49, happyCallee50, happyCallee51, happyCallee52, happyCallee53, happyCallee54, happyCallee55, happyCallee56, happyCallee57, happyCallee58, happyCallee59, happyCallee60, happyCallee61, happyCallee62, happyCallee63];
+
+for (var i = 0; i &lt; happyCallees.length; ++i)
+    noInline(happyCallees[i]);
+
+// Unlike the other test (throw-from-ftl-call-ic-slow-path.js), we want to populate the registers with undefined
+// in this test.
+var array = new Array();
+for (var i = 0; i &lt; 64; ++i)
+    array[i] = void 0;
+
+// Now, do some warming up.
+for (var i = 0; i &lt; 100000; ++i) {
+    var result = ftlFunction(array, happyCallees[i % happyCallees.length]);
+    if (result.length != array.length)
+        throw &quot;Error: bad length: &quot; + result;
+    for (var j = 0; j &lt; result.length; ++j) {
+        if (result[j] != array[j])
+            throw &quot;Error: bad entry at j = &quot; + j + &quot;: &quot; + result;
+    }
+}
+
+// Finally, attempt to trigger the bug.
+var notACell = 42;
+for (var i = 0; i &lt; 100; ++i) {
+    try {
+        ftlFunction(array, Int8Array);
+    } catch (e) {
+        if (e.message.indexOf(&quot;not a function&quot;) &lt; 0)
+            throw &quot;Error: bad exception message: &quot; + e.message;
+        var result = notACell.f;
+        if (result !== void 0) {
+            print(&quot;Bad outcome of accessing f on notACell.&quot;);
+            print(&quot;Here's notACell:&quot;, notACell, describe(notACell));
+            print(&quot;Here's the result:&quot;, result, describe(result));
+            throw &quot;Error: bad outcome of accessing f on &quot; + notACell + &quot;: &quot; + result;
+        }
+        var result2 = result + 5;
+        var result3 = notACell + 5;
+        if (&quot;&quot; + result2 != &quot;NaN&quot;)
+            throw &quot;Error: bad outcome of adding 5 to result: &quot; + result2;
+        if (result3 != 47)
+            throw &quot;Error: bad outcome of adding 5 to 42: &quot; + result3;
+    }
+}
+
</ins></span></pre></div>
<a id="branchessafari6001415branchSourceJavaScriptCoretestsstressthrowfromftlcallicslowpathjsfromrev180234trunkSourceJavaScriptCoretestsstressthrowfromftlcallicslowpathjs"></a>
<div class="copfile"><h4>Copied: branches/safari-600.1.4.15-branch/Source/JavaScriptCore/tests/stress/throw-from-ftl-call-ic-slow-path.js (from rev 180234, trunk/Source/JavaScriptCore/tests/stress/throw-from-ftl-call-ic-slow-path.js) (0 => 181182)</h4>
<pre class="diff"><span>
<span class="info">--- branches/safari-600.1.4.15-branch/Source/JavaScriptCore/tests/stress/throw-from-ftl-call-ic-slow-path.js                                (rev 0)
+++ branches/safari-600.1.4.15-branch/Source/JavaScriptCore/tests/stress/throw-from-ftl-call-ic-slow-path.js        2015-03-06 22:29:10 UTC (rev 181182)
</span><span class="lines">@@ -0,0 +1,192 @@
</span><ins>+// Attempts to induce a crash resulting from the FTL emitting code that clobbers the tag registers and then
+// throwing an exception without restoring those tag registers' values.
+
+function ftlFunction(array, callee) {
+    // Gotta use lots of gprs.
+    var x0 = array[0];
+    var x1 = array[1];
+    var x2 = array[2];
+    var x3 = array[3];
+    var x4 = array[4];
+    var x5 = array[5];
+    var x6 = array[6];
+    var x7 = array[7];
+    var x8 = array[8];
+    var x9 = array[9];
+    var x10 = array[10];
+    var x11 = array[11];
+    var x12 = array[12];
+    var x13 = array[13];
+    var x14 = array[14];
+    var x15 = array[15];
+    var x16 = array[16];
+    var x17 = array[17];
+    var x18 = array[18];
+    var x19 = array[19];
+    var x20 = array[20];
+    var x21 = array[21];
+    var x22 = array[22];
+    var x23 = array[23];
+    var x24 = array[24];
+    var x25 = array[25];
+    var x26 = array[26];
+    var x27 = array[27];
+    var x28 = array[28];
+    var x29 = array[29];
+    var x30 = array[30];
+    var x31 = array[31];
+    var x32 = array[32];
+    var x33 = array[33];
+    var x34 = array[34];
+    var x35 = array[35];
+    var x36 = array[36];
+    var x37 = array[37];
+    var x38 = array[38];
+    var x39 = array[39];
+    var x40 = array[40];
+    var x41 = array[41];
+    var x42 = array[42];
+    var x43 = array[43];
+    var x44 = array[44];
+    var x45 = array[45];
+    var x46 = array[46];
+    var x47 = array[47];
+    var x48 = array[48];
+    var x49 = array[49];
+    var x50 = array[50];
+    var x51 = array[51];
+    var x52 = array[52];
+    var x53 = array[53];
+    var x54 = array[54];
+    var x55 = array[55];
+    var x56 = array[56];
+    var x57 = array[57];
+    var x58 = array[58];
+    var x59 = array[59];
+    var x60 = array[60];
+    var x61 = array[61];
+    var x62 = array[62];
+    var x63 = array[63];
+    
+    // Make a call that will throw, when we ask it to.
+    callee(&quot;hello&quot;);
+    
+    // Use all of those crazy values.
+    return [x0, x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, x11, x12, x13, x14, x15, x16, x17, x18, x19, x20, x21, x22, x23, x24, x25, x26, x27, x28, x29, x30, x31, x32, x33, x34, x35, x36, x37, x38, x39, x40, x41, x42, x43, x44, x45, x46, x47, x48, x49, x50, x51, x52, x53, x54, x55, x56, x57, x58, x59, x60, x61, x62, x63]
+}
+
+noInline(ftlFunction);
+
+// Create some callees that are too crazy to get inlined or devirtualized, but that don't have effects.
+
+function happyCallee0() { return 0 };
+function happyCallee1() { return 1 };
+function happyCallee2() { return 2 };
+function happyCallee3() { return 3 };
+function happyCallee4() { return 4 };
+function happyCallee5() { return 5 };
+function happyCallee6() { return 6 };
+function happyCallee7() { return 7 };
+function happyCallee8() { return 8 };
+function happyCallee9() { return 9 };
+function happyCallee10() { return 10 };
+function happyCallee11() { return 11 };
+function happyCallee12() { return 12 };
+function happyCallee13() { return 13 };
+function happyCallee14() { return 14 };
+function happyCallee15() { return 15 };
+function happyCallee16() { return 16 };
+function happyCallee17() { return 17 };
+function happyCallee18() { return 18 };
+function happyCallee19() { return 19 };
+function happyCallee20() { return 20 };
+function happyCallee21() { return 21 };
+function happyCallee22() { return 22 };
+function happyCallee23() { return 23 };
+function happyCallee24() { return 24 };
+function happyCallee25() { return 25 };
+function happyCallee26() { return 26 };
+function happyCallee27() { return 27 };
+function happyCallee28() { return 28 };
+function happyCallee29() { return 29 };
+function happyCallee30() { return 30 };
+function happyCallee31() { return 31 };
+function happyCallee32() { return 32 };
+function happyCallee33() { return 33 };
+function happyCallee34() { return 34 };
+function happyCallee35() { return 35 };
+function happyCallee36() { return 36 };
+function happyCallee37() { return 37 };
+function happyCallee38() { return 38 };
+function happyCallee39() { return 39 };
+function happyCallee40() { return 40 };
+function happyCallee41() { return 41 };
+function happyCallee42() { return 42 };
+function happyCallee43() { return 43 };
+function happyCallee44() { return 44 };
+function happyCallee45() { return 45 };
+function happyCallee46() { return 46 };
+function happyCallee47() { return 47 };
+function happyCallee48() { return 48 };
+function happyCallee49() { return 49 };
+function happyCallee50() { return 50 };
+function happyCallee51() { return 51 };
+function happyCallee52() { return 52 };
+function happyCallee53() { return 53 };
+function happyCallee54() { return 54 };
+function happyCallee55() { return 55 };
+function happyCallee56() { return 56 };
+function happyCallee57() { return 57 };
+function happyCallee58() { return 58 };
+function happyCallee59() { return 59 };
+function happyCallee60() { return 60 };
+function happyCallee61() { return 61 };
+function happyCallee62() { return 62 };
+function happyCallee63() { return 63 };
+
+var happyCallees = [happyCallee0, happyCallee1, happyCallee2, happyCallee3, happyCallee4, happyCallee5, happyCallee6, happyCallee7, happyCallee8, happyCallee9, happyCallee10, happyCallee11, happyCallee12, happyCallee13, happyCallee14, happyCallee15, happyCallee16, happyCallee17, happyCallee18, happyCallee19, happyCallee20, happyCallee21, happyCallee22, happyCallee23, happyCallee24, happyCallee25, happyCallee26, happyCallee27, happyCallee28, happyCallee29, happyCallee30, happyCallee31, happyCallee32, happyCallee33, happyCallee34, happyCallee35, happyCallee36, happyCallee37, happyCallee38, happyCallee39, happyCallee40, happyCallee41, happyCallee42, happyCallee43, happyCallee44, happyCallee45, happyCallee46, happyCallee47, happyCallee48, happyCallee49, happyCallee50, happyCallee51, happyCallee52, happyCallee53, happyCallee54, happyCallee55, happyCallee56, happyCallee57, happyCallee58, happyCallee59, happyCallee60, happyCallee61, happyCallee62, happyCallee63];
+
+for (var i = 0; i &lt; happyCallees.length; ++i)
+    noInline(happyCallees[i]);
+
+// We want the input array to have an easy-to-deal-with type that isn't exactly the same as the type that
+// ftlFunction will return.
+var array = new Int32Array(64);
+for (var i = 0; i &lt; array.length; ++i)
+    array[i] = i;
+
+// Now, do some warming up.
+for (var i = 0; i &lt; 100000; ++i) {
+    var result = ftlFunction(array, happyCallees[i % happyCallees.length]);
+    if (result.length != array.length)
+        throw &quot;Error: bad length: &quot; + result;
+    for (var j = 0; j &lt; result.length; ++j) {
+        if (result[j] != array[j])
+            throw &quot;Error: bad entry at j = &quot; + j + &quot;: &quot; + result;
+    }
+}
+
+// Finally, attempt to trigger the bug.
+var notACell = 42;
+for (var i = 0; i &lt; 100; ++i) {
+    try {
+        ftlFunction(array, Int8Array);
+    } catch (e) {
+        if (e.message.indexOf(&quot;not a function&quot;) &lt; 0)
+            throw &quot;Error: bad exception message: &quot; + e.message;
+        var result = notACell.f;
+        if (result !== void 0) {
+            print(&quot;Bad outcome of accessing f on notACell.&quot;);
+            print(&quot;Here's notACell:&quot;, notACell, describe(notACell));
+            print(&quot;Here's the result:&quot;, result, describe(result));
+            throw &quot;Error: bad outcome of accessing f on &quot; + notACell + &quot;: &quot; + result;
+        }
+        var result2 = result + 5;
+        var result3 = notACell + 5;
+        if (&quot;&quot; + result2 != &quot;NaN&quot;)
+            throw &quot;Error: bad outcome of adding 5 to result: &quot; + result2;
+        if (result3 != 47)
+            throw &quot;Error: bad outcome of adding 5 to 42: &quot; + result3;
+    }
+}
+
</ins></span></pre>
</div>
</div>

</body>
</html>