<!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>[165072] trunk/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/165072">165072</a></dd>
<dt>Author</dt> <dd>fpizlo@apple.com</dd>
<dt>Date</dt> <dd>2014-03-04 13:27:37 -0800 (Tue, 04 Mar 2014)</dd>
</dl>

<h3>Log Message</h3>
<pre>GetMyArgumentByVal in FTL
https://bugs.webkit.org/show_bug.cgi?id=128850

Reviewed by Oliver Hunt.
        
This would have been easy if the OSR exit compiler's arity checks hadn't been wrong.
They checked arity by doing &quot;exec-&gt;argumentCount == codeBlock-&gt;numParameters&quot;, which
caused it to think that the arity check had failed if the caller had passed more
arguments than needed. This would cause the call frame copying to sort of go into
reverse (because the amount-by-which-we-failed-arity would have opposite sign,
throwing off a bunch of math) and the stack would end up being corrupted.
        
The bug was revealed by two existing tests although as far as I could tell, neither
test was intending to cover this case directly. So, I added a new test.

* ftl/FTLCapabilities.cpp:
(JSC::FTL::canCompile):
* ftl/FTLLowerDFGToLLVM.cpp:
(JSC::FTL::LowerDFGToLLVM::compileNode):
(JSC::FTL::LowerDFGToLLVM::compileGetMyArgumentsLength):
(JSC::FTL::LowerDFGToLLVM::compileGetMyArgumentByVal):
(JSC::FTL::LowerDFGToLLVM::compileCheckArgumentsNotCreated):
(JSC::FTL::LowerDFGToLLVM::checkArgumentsNotCreated):
* ftl/FTLOSRExitCompiler.cpp:
(JSC::FTL::compileStub):
* ftl/FTLState.h:
* tests/stress/exit-from-ftl-when-caller-passed-extra-args-then-use-function-dot-arguments.js: Added.
* tests/stress/ftl-get-my-argument-by-val-inlined-and-not-inlined.js: Added.
* tests/stress/ftl-get-my-argument-by-val-inlined.js: Added.
* tests/stress/ftl-get-my-argument-by-val.js: Added.</pre>

<h3>Modified Paths</h3>
<ul>
<li><a href="#trunkSourceJavaScriptCoreChangeLog">trunk/Source/JavaScriptCore/ChangeLog</a></li>
<li><a href="#trunkSourceJavaScriptCoreftlFTLCapabilitiescpp">trunk/Source/JavaScriptCore/ftl/FTLCapabilities.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoreftlFTLLowerDFGToLLVMcpp">trunk/Source/JavaScriptCore/ftl/FTLLowerDFGToLLVM.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoreftlFTLOSRExitCompilercpp">trunk/Source/JavaScriptCore/ftl/FTLOSRExitCompiler.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoreftlFTLStateh">trunk/Source/JavaScriptCore/ftl/FTLState.h</a></li>
</ul>

<h3>Added Paths</h3>
<ul>
<li><a href="#trunkSourceJavaScriptCoretestsstressexitfromftlwhencallerpassedextraargsthenusefunctiondotargumentsjs">trunk/Source/JavaScriptCore/tests/stress/exit-from-ftl-when-caller-passed-extra-args-then-use-function-dot-arguments.js</a></li>
<li><a href="#trunkSourceJavaScriptCoretestsstressftlgetmyargumentbyvalinlinedandnotinlinedjs">trunk/Source/JavaScriptCore/tests/stress/ftl-get-my-argument-by-val-inlined-and-not-inlined.js</a></li>
<li><a href="#trunkSourceJavaScriptCoretestsstressftlgetmyargumentbyvalinlinedjs">trunk/Source/JavaScriptCore/tests/stress/ftl-get-my-argument-by-val-inlined.js</a></li>
<li><a href="#trunkSourceJavaScriptCoretestsstressftlgetmyargumentbyvaljs">trunk/Source/JavaScriptCore/tests/stress/ftl-get-my-argument-by-val.js</a></li>
</ul>

</div>
<div id="patch">
<h3>Diff</h3>
<a id="trunkSourceJavaScriptCoreChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/ChangeLog (165071 => 165072)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/ChangeLog        2014-03-04 21:08:14 UTC (rev 165071)
+++ trunk/Source/JavaScriptCore/ChangeLog        2014-03-04 21:27:37 UTC (rev 165072)
</span><span class="lines">@@ -1,3 +1,36 @@
</span><ins>+2014-03-02  Filip Pizlo  &lt;fpizlo@apple.com&gt;
+
+        GetMyArgumentByVal in FTL
+        https://bugs.webkit.org/show_bug.cgi?id=128850
+
+        Reviewed by Oliver Hunt.
+        
+        This would have been easy if the OSR exit compiler's arity checks hadn't been wrong.
+        They checked arity by doing &quot;exec-&gt;argumentCount == codeBlock-&gt;numParameters&quot;, which
+        caused it to think that the arity check had failed if the caller had passed more
+        arguments than needed. This would cause the call frame copying to sort of go into
+        reverse (because the amount-by-which-we-failed-arity would have opposite sign,
+        throwing off a bunch of math) and the stack would end up being corrupted.
+        
+        The bug was revealed by two existing tests although as far as I could tell, neither
+        test was intending to cover this case directly. So, I added a new test.
+
+        * ftl/FTLCapabilities.cpp:
+        (JSC::FTL::canCompile):
+        * ftl/FTLLowerDFGToLLVM.cpp:
+        (JSC::FTL::LowerDFGToLLVM::compileNode):
+        (JSC::FTL::LowerDFGToLLVM::compileGetMyArgumentsLength):
+        (JSC::FTL::LowerDFGToLLVM::compileGetMyArgumentByVal):
+        (JSC::FTL::LowerDFGToLLVM::compileCheckArgumentsNotCreated):
+        (JSC::FTL::LowerDFGToLLVM::checkArgumentsNotCreated):
+        * ftl/FTLOSRExitCompiler.cpp:
+        (JSC::FTL::compileStub):
+        * ftl/FTLState.h:
+        * tests/stress/exit-from-ftl-when-caller-passed-extra-args-then-use-function-dot-arguments.js: Added.
+        * tests/stress/ftl-get-my-argument-by-val-inlined-and-not-inlined.js: Added.
+        * tests/stress/ftl-get-my-argument-by-val-inlined.js: Added.
+        * tests/stress/ftl-get-my-argument-by-val.js: Added.
+
</ins><span class="cx"> 2014-03-04  Zan Dobersek  &lt;zdobersek@igalia.com&gt;
</span><span class="cx"> 
</span><span class="cx">         [GTK] Build the Udis86 disassembler
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreftlFTLCapabilitiescpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/ftl/FTLCapabilities.cpp (165071 => 165072)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/ftl/FTLCapabilities.cpp        2014-03-04 21:08:14 UTC (rev 165071)
+++ trunk/Source/JavaScriptCore/ftl/FTLCapabilities.cpp        2014-03-04 21:27:37 UTC (rev 165072)
</span><span class="lines">@@ -141,6 +141,7 @@
</span><span class="cx">     case MultiPutByOffset:
</span><span class="cx">     case ToPrimitive:
</span><span class="cx">     case PhantomArguments:
</span><ins>+    case GetMyArgumentByVal:
</ins><span class="cx">         // These are OK.
</span><span class="cx">         break;
</span><span class="cx">     case PutByIdDirect:
</span><span class="lines">@@ -296,6 +297,8 @@
</span><span class="cx">         // Need this because although we also don't support
</span><span class="cx">         // CreateActivation/TearOffActivation, we might not see those nodes in case of
</span><span class="cx">         // OSR entry.
</span><ins>+        // FIXME: Support activations.
+        // https://bugs.webkit.org/show_bug.cgi?id=129576
</ins><span class="cx">         if (verboseCapabilities())
</span><span class="cx">             dataLog(&quot;FTL rejecting &quot;, *graph.m_codeBlock, &quot; because it uses activations.\n&quot;);
</span><span class="cx">         return CannotCompile;
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreftlFTLLowerDFGToLLVMcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/ftl/FTLLowerDFGToLLVM.cpp (165071 => 165072)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/ftl/FTLLowerDFGToLLVM.cpp        2014-03-04 21:08:14 UTC (rev 165071)
+++ trunk/Source/JavaScriptCore/ftl/FTLLowerDFGToLLVM.cpp        2014-03-04 21:27:37 UTC (rev 165072)
</span><span class="lines">@@ -303,6 +303,9 @@
</span><span class="cx">         case GetMyArgumentsLength:
</span><span class="cx">             compileGetMyArgumentsLength();
</span><span class="cx">             break;
</span><ins>+        case GetMyArgumentByVal:
+            compileGetMyArgumentByVal();
+            break;
</ins><span class="cx">         case ZombieHint:
</span><span class="cx">             compileZombieHint();
</span><span class="cx">             break;
</span><span class="lines">@@ -1847,17 +1850,47 @@
</span><span class="cx">     
</span><span class="cx">     void compileGetMyArgumentsLength() 
</span><span class="cx">     {
</span><del>-        CodeOrigin codeLocation = m_node-&gt;origin.semantic;
-        if (!isEmptySpeculation(
-            m_state.variables().operand(
-                m_graph.argumentsRegisterFor(m_node-&gt;origin.semantic)).m_type)) {
-            VirtualRegister argsReg = m_graph.machineArgumentsRegisterFor(codeLocation);
-            speculate(ArgumentsEscaped, noValue(), 0, m_out.notZero64(m_out.load64(addressFor(argsReg))));
-        }
</del><ins>+        checkArgumentsNotCreated();
</ins><span class="cx"> 
</span><del>-        RELEASE_ASSERT(!codeLocation.inlineCallFrame);
</del><ins>+        RELEASE_ASSERT(!m_node-&gt;origin.semantic.inlineCallFrame);
</ins><span class="cx">         setInt32(m_out.add(m_out.load32NonNegative(payloadFor(JSStack::ArgumentCount)), m_out.constInt32(-1)));
</span><span class="cx">     }
</span><ins>+    
+    void compileGetMyArgumentByVal()
+    {
+        checkArgumentsNotCreated();
+        
+        CodeOrigin codeOrigin = m_node-&gt;origin.semantic;
+        
+        LValue zeroBasedIndex = lowInt32(m_node-&gt;child1());
+        LValue oneBasedIndex = m_out.add(zeroBasedIndex, m_out.int32One);
+        
+        LValue limit;
+        if (codeOrigin.inlineCallFrame)
+            limit = m_out.constInt32(codeOrigin.inlineCallFrame-&gt;arguments.size());
+        else
+            limit = m_out.load32(payloadFor(JSStack::ArgumentCount));
+        
+        speculate(Uncountable, noValue(), 0, m_out.aboveOrEqual(oneBasedIndex, limit));
+        
+        SymbolTable* symbolTable = m_graph.baselineCodeBlockFor(codeOrigin)-&gt;symbolTable();
+        if (symbolTable-&gt;slowArguments()) {
+            // FIXME: FTL should support activations.
+            // https://bugs.webkit.org/show_bug.cgi?id=129576
+            
+            RELEASE_ASSERT_NOT_REACHED();
+        }
+        
+        TypedPointer base;
+        if (codeOrigin.inlineCallFrame)
+            base = addressFor(codeOrigin.inlineCallFrame-&gt;arguments[1].virtualRegister());
+        else
+            base = addressFor(virtualRegisterForArgument(1));
+        
+        LValue pointer = m_out.baseIndex(
+            base.value(), m_out.zeroExt(zeroBasedIndex, m_out.intPtr), ScaleEight);
+        setJSValue(m_out.load64(TypedPointer(m_heaps.variables.atAnyIndex(), pointer)));
+    }
</ins><span class="cx"> 
</span><span class="cx">     void compileGetArrayLength()
</span><span class="cx">     {
</span><span class="lines">@@ -3686,8 +3719,7 @@
</span><span class="cx">             m_state.variables().operand(
</span><span class="cx">                 m_graph.argumentsRegisterFor(m_node-&gt;origin.semantic)).m_type));
</span><span class="cx">         
</span><del>-        VirtualRegister reg = m_graph.machineArgumentsRegisterFor(m_node-&gt;origin.semantic);
-        speculate(ArgumentsEscaped, noValue(), 0, m_out.notZero64(m_out.load64(addressFor(reg))));
</del><ins>+        checkArgumentsNotCreated();
</ins><span class="cx">     }
</span><span class="cx">     
</span><span class="cx">     void compileCountExecution()
</span><span class="lines">@@ -4430,6 +4462,19 @@
</span><span class="cx">         return m_out.phi(m_out.int32, fastResult, slowResult);
</span><span class="cx">     }
</span><span class="cx">     
</span><ins>+    void checkArgumentsNotCreated()
+    {
+        CodeOrigin codeOrigin = m_node-&gt;origin.semantic;
+        VirtualRegister argumentsRegister = m_graph.argumentsRegisterFor(codeOrigin);
+        if (isEmptySpeculation(m_state.variables().operand(argumentsRegister).m_type))
+            return;
+        
+        VirtualRegister argsReg = m_graph.machineArgumentsRegisterFor(codeOrigin);
+        speculate(
+            ArgumentsEscaped, noValue(), 0,
+            m_out.notZero64(m_out.load64(addressFor(argsReg))));
+    }
+    
</ins><span class="cx">     void speculate(
</span><span class="cx">         ExitKind kind, FormattedValue lowValue, Node* highValue, LValue failCondition)
</span><span class="cx">     {
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreftlFTLOSRExitCompilercpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/ftl/FTLOSRExitCompiler.cpp (165071 => 165072)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/ftl/FTLOSRExitCompiler.cpp        2014-03-04 21:08:14 UTC (rev 165071)
+++ trunk/Source/JavaScriptCore/ftl/FTLOSRExitCompiler.cpp        2014-03-04 21:27:37 UTC (rev 165072)
</span><span class="lines">@@ -249,7 +249,8 @@
</span><span class="cx">     jit.add32(
</span><span class="cx">         MacroAssembler::TrustedImm32(-codeBlock-&gt;numParameters()), GPRInfo::regT2,
</span><span class="cx">         GPRInfo::regT3);
</span><del>-    MacroAssembler::Jump arityIntact = jit.branchTest32(MacroAssembler::Zero, GPRInfo::regT3);
</del><ins>+    MacroAssembler::Jump arityIntact = jit.branch32(
+        MacroAssembler::GreaterThanOrEqual, GPRInfo::regT3, MacroAssembler::TrustedImm32(0));
</ins><span class="cx">     jit.neg32(GPRInfo::regT3);
</span><span class="cx">     jit.add32(MacroAssembler::TrustedImm32(1 + stackAlignmentRegisters() - 1), GPRInfo::regT3);
</span><span class="cx">     jit.and32(MacroAssembler::TrustedImm32(-stackAlignmentRegisters()), GPRInfo::regT3);
</span><span class="lines">@@ -303,8 +304,10 @@
</span><span class="cx">     
</span><span class="cx">     // We need to make sure that we return into the register restoration thunk. This works
</span><span class="cx">     // differently depending on whether or not we had arity issues.
</span><del>-    MacroAssembler::Jump arityIntactForReturnPC =
-        jit.branchTest32(MacroAssembler::Zero, GPRInfo::regT3);
</del><ins>+    MacroAssembler::Jump arityIntactForReturnPC = jit.branch32(
+        MacroAssembler::GreaterThanOrEqual,
+        CCallHelpers::payloadFor(JSStack::ArgumentCount),
+        MacroAssembler::TrustedImm32(codeBlock-&gt;numParameters()));
</ins><span class="cx">     
</span><span class="cx">     // The return PC in the call frame header points at exactly the right arity restoration
</span><span class="cx">     // thunk. We don't want to change that. But the arity restoration thunk's frame has a
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreftlFTLStateh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/ftl/FTLState.h (165071 => 165072)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/ftl/FTLState.h        2014-03-04 21:08:14 UTC (rev 165071)
+++ trunk/Source/JavaScriptCore/ftl/FTLState.h        2014-03-04 21:27:37 UTC (rev 165072)
</span><span class="lines">@@ -37,6 +37,7 @@
</span><span class="cx"> #include &quot;FTLJITFinalizer.h&quot;
</span><span class="cx"> #include &quot;FTLJSCall.h&quot;
</span><span class="cx"> #include &quot;FTLStackMaps.h&quot;
</span><ins>+#include &quot;FTLState.h&quot;
</ins><span class="cx"> #include &lt;wtf/Noncopyable.h&gt;
</span><span class="cx"> 
</span><span class="cx"> namespace JSC { namespace FTL {
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoretestsstressexitfromftlwhencallerpassedextraargsthenusefunctiondotargumentsjs"></a>
<div class="addfile"><h4>Added: trunk/Source/JavaScriptCore/tests/stress/exit-from-ftl-when-caller-passed-extra-args-then-use-function-dot-arguments.js (0 => 165072)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/tests/stress/exit-from-ftl-when-caller-passed-extra-args-then-use-function-dot-arguments.js                                (rev 0)
+++ trunk/Source/JavaScriptCore/tests/stress/exit-from-ftl-when-caller-passed-extra-args-then-use-function-dot-arguments.js        2014-03-04 21:27:37 UTC (rev 165072)
</span><span class="lines">@@ -0,0 +1,37 @@
</span><ins>+function foo(a, b) {
+    var result = a + b;
+    bar();
+    return result;
+}
+
+var capturedArgs;
+function bar() {
+    capturedArgs = foo.arguments;
+}
+
+noInline(foo);
+noInline(bar);
+
+function arraycmp(a, b) {
+    if (a.length != b.length)
+        return false;
+    for (var i = 0; i &lt; a.length; ++i) {
+        if (a[i] != b[i])
+            return false;
+    }
+    return true;
+}
+
+for (var i = 0; i &lt; 10000; ++i) {
+    var result = foo(1, 2, 3, 4, 5, 6);
+    if (result != 3)
+        throw &quot;Error: bad result in loop: &quot; + result;
+    if (!arraycmp(capturedArgs, [1, 2, 3, 4, 5, 6]))
+        throw &quot;Error: bad captured arguments in loop: &quot; + capturedArgs;
+}
+
+var result = foo(2000000000, 2000000000, 3, 4, 5, 6);
+if (result != 4000000000)
+    throw &quot;Error: bad result at end: &quot; + result;
+if (!arraycmp(capturedArgs, [2000000000, 2000000000, 3, 4, 5, 6]))
+    throw &quot;Error: bad captured arguments at end: &quot; + Array.prototype.join.apply(capturedArgs, &quot;,&quot;);
</ins></span></pre></div>
<a id="trunkSourceJavaScriptCoretestsstressftlgetmyargumentbyvalinlinedandnotinlinedjs"></a>
<div class="addfile"><h4>Added: trunk/Source/JavaScriptCore/tests/stress/ftl-get-my-argument-by-val-inlined-and-not-inlined.js (0 => 165072)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/tests/stress/ftl-get-my-argument-by-val-inlined-and-not-inlined.js                                (rev 0)
+++ trunk/Source/JavaScriptCore/tests/stress/ftl-get-my-argument-by-val-inlined-and-not-inlined.js        2014-03-04 21:27:37 UTC (rev 165072)
</span><span class="lines">@@ -0,0 +1,27 @@
</span><ins>+function foo(i) {
+    return arguments[i];
+}
+
+function bar(i) {
+    return [arguments[i], foo(i, &quot;one&quot;, 2, &quot;three&quot;), arguments[i]];
+}
+
+noInline(bar);
+
+function arraycmp(a, b) {
+    if (a.length != b.length)
+        return false;
+    for (var i = 0; i &lt; a.length; ++i) {
+        if (a[i] != b[i])
+            return false;
+    }
+    return true;
+}
+
+for (var i = 0; i &lt; 10000; ++i) {
+    var thingies = [i % 4, &quot;one&quot;, 2, &quot;three&quot;];
+    var otherThingies = [i % 4, &quot;five&quot;, 6, &quot;seven&quot;];
+    var result = bar(i % 4, &quot;five&quot;, 6, &quot;seven&quot;);
+    if (!arraycmp(result, [otherThingies[i % 4], thingies[i % 4], otherThingies[i % 4]]))
+        throw &quot;Error: bad result for i = &quot; + i + &quot;: &quot; + result;
+}
</ins></span></pre></div>
<a id="trunkSourceJavaScriptCoretestsstressftlgetmyargumentbyvalinlinedjs"></a>
<div class="addfile"><h4>Added: trunk/Source/JavaScriptCore/tests/stress/ftl-get-my-argument-by-val-inlined.js (0 => 165072)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/tests/stress/ftl-get-my-argument-by-val-inlined.js                                (rev 0)
+++ trunk/Source/JavaScriptCore/tests/stress/ftl-get-my-argument-by-val-inlined.js        2014-03-04 21:27:37 UTC (rev 165072)
</span><span class="lines">@@ -0,0 +1,16 @@
</span><ins>+function foo(i) {
+    return arguments[i];
+}
+
+function bar(i) {
+    return foo(i, &quot;one&quot;, 2, &quot;three&quot;);
+}
+
+noInline(bar);
+
+for (var i = 0; i &lt; 10000; ++i) {
+    var thingies = [i % 4, &quot;one&quot;, 2, &quot;three&quot;];
+    var result = bar(i % 4, &quot;five&quot;, 6, &quot;seven&quot;);
+    if (result != thingies[i % 4])
+        throw &quot;Error: bad result for i = &quot; + i + &quot;: &quot; + result;
+}
</ins></span></pre></div>
<a id="trunkSourceJavaScriptCoretestsstressftlgetmyargumentbyvaljs"></a>
<div class="addfile"><h4>Added: trunk/Source/JavaScriptCore/tests/stress/ftl-get-my-argument-by-val.js (0 => 165072)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/tests/stress/ftl-get-my-argument-by-val.js                                (rev 0)
+++ trunk/Source/JavaScriptCore/tests/stress/ftl-get-my-argument-by-val.js        2014-03-04 21:27:37 UTC (rev 165072)
</span><span class="lines">@@ -0,0 +1,12 @@
</span><ins>+function foo(i) {
+    return arguments[i];
+}
+
+noInline(foo);
+
+for (var i = 0; i &lt; 10000; ++i) {
+    var thingies = [i % 4, &quot;one&quot;, 2, &quot;three&quot;];
+    var result = foo(i % 4, &quot;one&quot;, 2, &quot;three&quot;);
+    if (result != thingies[i % 4])
+        throw &quot;Error: bad result for i = &quot; + i + &quot;: &quot; + result;
+}
</ins></span></pre>
</div>
</div>

</body>
</html>