<!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>[37160] 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/37160">37160</a></dd>
<dt>Author</dt> <dd>cwzwarich@webkit.org</dd>
<dt>Date</dt> <dd>2008-10-01 15:18:50 -0700 (Wed, 01 Oct 2008)</dd>
</dl>

<h3>Log Message</h3>
<pre>2008-10-01  Cameron Zwarich  &lt;zwarich@apple.com&gt;

        Reviewed by Darin Adler.

        Bug 21123: using &quot;arguments&quot; in a function should not force creation of an activation object
        &lt;https://bugs.webkit.org/show_bug.cgi?id=21123&gt;

        Make the 'arguments' object not require a JSActivation. We store the
        'arguments' object in the OptionalCalleeArguments call frame slot. We
        need to be able to get the original 'arguments' object to tear it off
        when returning from a function, but 'arguments' may be assigned to in a
        number of ways.

        Therefore, we use the OptionalCalleeArguments slot when we want to get
        the original activation or we know that 'arguments' was not assigned a
        different value. When 'arguments' may have been assigned a new value,
        we use a new local variable that is initialized with 'arguments'. Since
        a function parameter named 'arguments' may overwrite the value of
        'arguments', we also need to be careful to look up 'arguments' in the
        symbol table, so we get the parameter named 'arguments' instead of the
        local variable that we have added for holding the 'arguments' object.

        This is a 19.1% win on the V8 Raytrace benchmark using the SunSpider
        harness, and a 20.7% win using the V8 harness. This amounts to a 6.5%
        total speedup on the V8 benchmark suite using the V8 harness.

        JavaScriptCore:

        * VM/CTI.cpp:
        (JSC::CTI::privateCompileMainPass):
        * VM/CodeBlock.h:
        * VM/CodeGenerator.cpp:
        (JSC::CodeGenerator::CodeGenerator):
        * VM/Machine.cpp:
        (JSC::Machine::unwindCallFrame):
        (JSC::Machine::privateExecute):
        (JSC::Machine::retrieveArguments):
        (JSC::Machine::cti_op_init_arguments):
        (JSC::Machine::cti_op_ret_activation_arguments):
        * VM/Machine.h:
        * VM/RegisterFile.h:
        (JSC::RegisterFile::):
        * kjs/Arguments.cpp:
        (JSC::Arguments::mark):
        (JSC::Arguments::fillArgList):
        (JSC::Arguments::getOwnPropertySlot):
        (JSC::Arguments::put):
        * kjs/Arguments.h:
        (JSC::Arguments::setRegisters):
        (JSC::Arguments::init):
        (JSC::Arguments::Arguments):
        (JSC::Arguments::copyRegisters):
        (JSC::JSActivation::copyRegisters):
        * kjs/JSActivation.cpp:
        (JSC::JSActivation::argumentsGetter):
        * kjs/JSActivation.h:
        (JSC::JSActivation::JSActivationData::JSActivationData):
        * kjs/grammar.y:
        * kjs/nodes.h:
        (JSC::ScopeNode::setUsesArguments):
        * masm/X86Assembler.h:
        (JSC::X86Assembler::):
        (JSC::X86Assembler::orl_mr):

        LayoutTests:

        * fast/js/arguments-expected.txt:
        * fast/js/function-dot-arguments-expected.txt:
        * fast/js/resources/arguments.js:
        * fast/js/resources/function-dot-arguments.js:</pre>

<h3>Modified Paths</h3>
<ul>
<li><a href="#trunkJavaScriptCoreChangeLog">trunk/JavaScriptCore/ChangeLog</a></li>
<li><a href="#trunkJavaScriptCoreVMCTIcpp">trunk/JavaScriptCore/VM/CTI.cpp</a></li>
<li><a href="#trunkJavaScriptCoreVMCodeBlockh">trunk/JavaScriptCore/VM/CodeBlock.h</a></li>
<li><a href="#trunkJavaScriptCoreVMCodeGeneratorcpp">trunk/JavaScriptCore/VM/CodeGenerator.cpp</a></li>
<li><a href="#trunkJavaScriptCoreVMMachinecpp">trunk/JavaScriptCore/VM/Machine.cpp</a></li>
<li><a href="#trunkJavaScriptCoreVMMachineh">trunk/JavaScriptCore/VM/Machine.h</a></li>
<li><a href="#trunkJavaScriptCoreVMRegisterFileh">trunk/JavaScriptCore/VM/RegisterFile.h</a></li>
<li><a href="#trunkJavaScriptCorekjsArgumentscpp">trunk/JavaScriptCore/kjs/Arguments.cpp</a></li>
<li><a href="#trunkJavaScriptCorekjsArgumentsh">trunk/JavaScriptCore/kjs/Arguments.h</a></li>
<li><a href="#trunkJavaScriptCorekjsJSActivationcpp">trunk/JavaScriptCore/kjs/JSActivation.cpp</a></li>
<li><a href="#trunkJavaScriptCorekjsJSActivationh">trunk/JavaScriptCore/kjs/JSActivation.h</a></li>
<li><a href="#trunkJavaScriptCorekjsgrammary">trunk/JavaScriptCore/kjs/grammar.y</a></li>
<li><a href="#trunkJavaScriptCorekjsnodesh">trunk/JavaScriptCore/kjs/nodes.h</a></li>
<li><a href="#trunkJavaScriptCoremasmX86Assemblerh">trunk/JavaScriptCore/masm/X86Assembler.h</a></li>
<li><a href="#trunkLayoutTestsChangeLog">trunk/LayoutTests/ChangeLog</a></li>
<li><a href="#trunkLayoutTestsfastjsargumentsexpectedtxt">trunk/LayoutTests/fast/js/arguments-expected.txt</a></li>
<li><a href="#trunkLayoutTestsfastjsfunctiondotargumentsexpectedtxt">trunk/LayoutTests/fast/js/function-dot-arguments-expected.txt</a></li>
<li><a href="#trunkLayoutTestsfastjsresourcesargumentsjs">trunk/LayoutTests/fast/js/resources/arguments.js</a></li>
<li><a href="#trunkLayoutTestsfastjsresourcesfunctiondotargumentsjs">trunk/LayoutTests/fast/js/resources/function-dot-arguments.js</a></li>
</ul>

</div>
<div id="patch">
<h3>Diff</h3>
<a id="trunkJavaScriptCoreChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/JavaScriptCore/ChangeLog (37159 => 37160)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/JavaScriptCore/ChangeLog        2008-10-01 22:12:23 UTC (rev 37159)
+++ trunk/JavaScriptCore/ChangeLog        2008-10-01 22:18:50 UTC (rev 37160)
</span><span class="lines">@@ -1,3 +1,65 @@
</span><ins>+2008-10-01  Cameron Zwarich  &lt;zwarich@apple.com&gt;
+
+        Reviewed by Darin Adler.
+
+        Bug 21123: using &quot;arguments&quot; in a function should not force creation of an activation object
+        &lt;https://bugs.webkit.org/show_bug.cgi?id=21123&gt;
+
+        Make the 'arguments' object not require a JSActivation. We store the
+        'arguments' object in the OptionalCalleeArguments call frame slot. We
+        need to be able to get the original 'arguments' object to tear it off
+        when returning from a function, but 'arguments' may be assigned to in a
+        number of ways.
+
+        Therefore, we use the OptionalCalleeArguments slot when we want to get
+        the original activation or we know that 'arguments' was not assigned a
+        different value. When 'arguments' may have been assigned a new value,
+        we use a new local variable that is initialized with 'arguments'. Since
+        a function parameter named 'arguments' may overwrite the value of
+        'arguments', we also need to be careful to look up 'arguments' in the
+        symbol table, so we get the parameter named 'arguments' instead of the
+        local variable that we have added for holding the 'arguments' object.
+
+        This is a 19.1% win on the V8 Raytrace benchmark using the SunSpider
+        harness, and a 20.7% win using the V8 harness. This amounts to a 6.5%
+        total speedup on the V8 benchmark suite using the V8 harness.
+
+        * VM/CTI.cpp:
+        (JSC::CTI::privateCompileMainPass):
+        * VM/CodeBlock.h:
+        * VM/CodeGenerator.cpp:
+        (JSC::CodeGenerator::CodeGenerator):
+        * VM/Machine.cpp:
+        (JSC::Machine::unwindCallFrame):
+        (JSC::Machine::privateExecute):
+        (JSC::Machine::retrieveArguments):
+        (JSC::Machine::cti_op_init_arguments):
+        (JSC::Machine::cti_op_ret_activation_arguments):
+        * VM/Machine.h:
+        * VM/RegisterFile.h:
+        (JSC::RegisterFile::):
+        * kjs/Arguments.cpp:
+        (JSC::Arguments::mark):
+        (JSC::Arguments::fillArgList):
+        (JSC::Arguments::getOwnPropertySlot):
+        (JSC::Arguments::put):
+        * kjs/Arguments.h:
+        (JSC::Arguments::setRegisters):
+        (JSC::Arguments::init):
+        (JSC::Arguments::Arguments):
+        (JSC::Arguments::copyRegisters):
+        (JSC::JSActivation::copyRegisters):
+        * kjs/JSActivation.cpp:
+        (JSC::JSActivation::argumentsGetter):
+        * kjs/JSActivation.h:
+        (JSC::JSActivation::JSActivationData::JSActivationData):
+        * kjs/grammar.y:
+        * kjs/nodes.h:
+        (JSC::ScopeNode::setUsesArguments):
+        * masm/X86Assembler.h:
+        (JSC::X86Assembler::):
+        (JSC::X86Assembler::orl_mr):
+
</ins><span class="cx"> 2008-10-01  Kevin McCullough  &lt;kmccullough@apple.com&gt;
</span><span class="cx"> 
</span><span class="cx">         Rubberstamped by Geoff .
</span></span></pre></div>
<a id="trunkJavaScriptCoreVMCTIcpp"></a>
<div class="modfile"><h4>Modified: trunk/JavaScriptCore/VM/CTI.cpp (37159 => 37160)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/JavaScriptCore/VM/CTI.cpp        2008-10-01 22:12:23 UTC (rev 37159)
+++ trunk/JavaScriptCore/VM/CTI.cpp        2008-10-01 22:18:50 UTC (rev 37160)
</span><span class="lines">@@ -1190,8 +1190,11 @@
</span><span class="cx">             break;
</span><span class="cx">         }
</span><span class="cx">         case op_ret: {
</span><del>-            // Check for an activation - if there is one, jump to the hook below.
-            m_jit.cmpl_i32m(0, RegisterFile::OptionalCalleeActivation * static_cast&lt;int&gt;(sizeof(Register)), X86::edi);
</del><ins>+            // If there is an activation or an 'arguments' object, we tear it
+            // off by jumping to the hook below.
+            m_jit.movl_mr(RegisterFile::OptionalCalleeActivation * static_cast&lt;int&gt;(sizeof(Register)), X86::edi, X86::eax);
+            m_jit.orl_mr(RegisterFile::OptionalCalleeArguments * static_cast&lt;int&gt;(sizeof(Register)), X86::edi, X86::eax);
+            m_jit.cmpl_i32r(0, X86::eax);
</ins><span class="cx">             X86Assembler::JmpSrc activation = m_jit.emitUnlinkedJne();
</span><span class="cx">             X86Assembler::JmpDst activated = m_jit.label();
</span><span class="cx"> 
</span><span class="lines">@@ -1221,9 +1224,9 @@
</span><span class="cx">             m_jit.pushl_r(X86::edx);
</span><span class="cx">             m_jit.ret();
</span><span class="cx"> 
</span><del>-            // Activation hook
</del><ins>+            // Activation and 'arguments' hook
</ins><span class="cx">             m_jit.link(activation, m_jit.label());
</span><del>-            emitCall(i, Machine::cti_op_ret_activation);
</del><ins>+            emitCall(i, Machine::cti_op_ret_activation_arguments);
</ins><span class="cx">             m_jit.link(m_jit.emitUnlinkedJmp(), activated);
</span><span class="cx"> 
</span><span class="cx">             // Profiling hook
</span></span></pre></div>
<a id="trunkJavaScriptCoreVMCodeBlockh"></a>
<div class="modfile"><h4>Modified: trunk/JavaScriptCore/VM/CodeBlock.h (37159 => 37160)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/JavaScriptCore/VM/CodeBlock.h        2008-10-01 22:12:23 UTC (rev 37159)
+++ trunk/JavaScriptCore/VM/CodeBlock.h        2008-10-01 22:18:50 UTC (rev 37160)
</span><span class="lines">@@ -241,6 +241,7 @@
</span><span class="cx">         int thisRegister;
</span><span class="cx">         bool needsFullScopeChain;
</span><span class="cx">         bool usesEval;
</span><ins>+        bool usesArguments;
</ins><span class="cx">         CodeType codeType;
</span><span class="cx">         RefPtr&lt;SourceProvider&gt; source;
</span><span class="cx">         unsigned sourceOffset;
</span></span></pre></div>
<a id="trunkJavaScriptCoreVMCodeGeneratorcpp"></a>
<div class="modfile"><h4>Modified: trunk/JavaScriptCore/VM/CodeGenerator.cpp (37159 => 37160)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/JavaScriptCore/VM/CodeGenerator.cpp        2008-10-01 22:12:23 UTC (rev 37159)
+++ trunk/JavaScriptCore/VM/CodeGenerator.cpp        2008-10-01 22:18:50 UTC (rev 37160)
</span><span class="lines">@@ -292,11 +292,12 @@
</span><span class="cx">     emitOpcode(op_init);
</span><span class="cx">     codeBlock-&gt;globalData = m_globalData;
</span><span class="cx"> 
</span><del>-    if (functionBody-&gt;usesArguments()) {
</del><ins>+    bool usesArguments = functionBody-&gt;usesArguments();
+    codeBlock-&gt;usesArguments = usesArguments;
+    if (usesArguments) {
</ins><span class="cx">         emitOpcode(op_init_arguments);
</span><del>-        m_codeBlock-&gt;needsFullScopeChain = true;
</del><span class="cx">         m_argumentsRegister.setIndex(RegisterFile::OptionalCalleeArguments);
</span><del>-        symbolTable-&gt;add(propertyNames().arguments.ustring().rep(), SymbolTableEntry(RegisterFile::OptionalCalleeArguments));
</del><ins>+        addVar(propertyNames().arguments, false);
</ins><span class="cx">     }
</span><span class="cx"> 
</span><span class="cx">     const Node::FunctionStack&amp; functionStack = functionBody-&gt;functionStack();
</span></span></pre></div>
<a id="trunkJavaScriptCoreVMMachinecpp"></a>
<div class="modfile"><h4>Modified: trunk/JavaScriptCore/VM/Machine.cpp (37159 => 37160)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/JavaScriptCore/VM/Machine.cpp        2008-10-01 22:12:23 UTC (rev 37159)
+++ trunk/JavaScriptCore/VM/Machine.cpp        2008-10-01 22:18:50 UTC (rev 37160)
</span><span class="lines">@@ -801,10 +801,13 @@
</span><span class="cx">     if (oldCodeBlock-&gt;needsFullScopeChain)
</span><span class="cx">         scopeChain-&gt;deref();
</span><span class="cx"> 
</span><del>-    // If this call frame created an activation, tear it off.
-    if (JSActivation* activation = static_cast&lt;JSActivation*&gt;(r[RegisterFile::OptionalCalleeActivation].jsValue(exec))) {
</del><ins>+    // If this call frame created an activation or an 'arguments' object, tear it off.
+    if (JSActivation* activation = static_cast&lt;JSActivation*&gt;(r[RegisterFile::OptionalCalleeActivation].getJSValue())) {
</ins><span class="cx">         ASSERT(activation-&gt;isObject(&amp;JSActivation::info));
</span><del>-        activation-&gt;copyRegisters();
</del><ins>+        activation-&gt;copyRegisters(r[RegisterFile::OptionalCalleeArguments].getJSValue());
+    } else if (Arguments* arguments = static_cast&lt;Arguments*&gt;(r[RegisterFile::OptionalCalleeArguments].getJSValue())) {
+        ASSERT(arguments-&gt;isObject(&amp;Arguments::info));
+        arguments-&gt;copyRegisters();
</ins><span class="cx">     }
</span><span class="cx">     
</span><span class="cx">     void* returnPC = r[RegisterFile::ReturnPC].v();
</span><span class="lines">@@ -3360,10 +3363,14 @@
</span><span class="cx">            
</span><span class="cx">         int result = (++vPC)-&gt;u.operand;
</span><span class="cx"> 
</span><del>-        if (JSActivation* activation = static_cast&lt;JSActivation*&gt;(r[RegisterFile::OptionalCalleeActivation].jsValue(exec))) {
</del><ins>+        // If this call frame created an activation or an 'arguments' object, tear it off.
+        if (JSActivation* activation = static_cast&lt;JSActivation*&gt;(r[RegisterFile::OptionalCalleeActivation].getJSValue())) {
</ins><span class="cx">             ASSERT(!codeBlock(r)-&gt;needsFullScopeChain || scopeChain(r)-&gt;object == activation);
</span><span class="cx">             ASSERT(activation-&gt;isObject(&amp;JSActivation::info));
</span><del>-            activation-&gt;copyRegisters();
</del><ins>+            activation-&gt;copyRegisters(r[RegisterFile::OptionalCalleeArguments].getJSValue());
+        } else if (Arguments* arguments = static_cast&lt;Arguments*&gt;(r[RegisterFile::OptionalCalleeArguments].getJSValue())) {
+            ASSERT(arguments-&gt;isObject(&amp;Arguments::info));
+            arguments-&gt;copyRegisters();
</ins><span class="cx">         }
</span><span class="cx"> 
</span><span class="cx">         if (*enabledProfilerReference)
</span><span class="lines">@@ -3417,8 +3424,16 @@
</span><span class="cx">         NEXT_OPCODE;
</span><span class="cx">     }
</span><span class="cx">     BEGIN_OPCODE(op_init_arguments) {
</span><del>-        JSActivation* activation = static_cast&lt;JSActivation*&gt;(r[RegisterFile::OptionalCalleeActivation].getJSValue());
-        r[RegisterFile::OptionalCalleeArguments] = activation-&gt;createArgumentsObject(exec);
</del><ins>+        JSValue* activation = r[RegisterFile::OptionalCalleeActivation].getJSValue();
+        Arguments* arguments;
+        if (activation) {
+            ASSERT(activation-&gt;isObject(&amp;JSActivation::info));
+            arguments = new (exec) Arguments(exec, static_cast&lt;JSActivation*&gt;(activation));
+        } else
+            arguments = new (exec) Arguments(exec, r);
+        r[RegisterFile::OptionalCalleeArguments] = arguments;
+        r[RegisterFile::ArgumentsRegister] = arguments;
+        
</ins><span class="cx">         ++vPC;
</span><span class="cx">         NEXT_OPCODE;
</span><span class="cx">     }
</span><span class="lines">@@ -3848,16 +3863,24 @@
</span><span class="cx">     if (!r)
</span><span class="cx">         return jsNull();
</span><span class="cx"> 
</span><del>-    Arguments* arguments = static_cast&lt;Arguments*&gt;(r[RegisterFile::OptionalCalleeArguments].jsValue(exec));
-    if (!arguments) {
-        JSActivation* activation = static_cast&lt;JSActivation*&gt;(r[RegisterFile::OptionalCalleeActivation].getJSValue());
-        if (!activation) {
-            activation = new (exec) JSActivation(exec, function-&gt;m_body, r);
-            r[RegisterFile::OptionalCalleeActivation] = activation;
</del><ins>+    JSValue* arguments;
+    CodeBlock* codeBlock = Machine::codeBlock(r);
+    if (codeBlock-&gt;usesArguments) {
+        ASSERT(codeBlock-&gt;codeType == FunctionCode);
+        SymbolTable&amp; symbolTable = static_cast&lt;FunctionBodyNode*&gt;(codeBlock-&gt;ownerNode)-&gt;symbolTable();
+        int argumentsIndex = symbolTable.get(exec-&gt;propertyNames().arguments.ustring().rep()).getIndex();
+        arguments = r[argumentsIndex].jsValue(exec);
+    } else {
+        arguments = r[RegisterFile::OptionalCalleeArguments].getJSValue();
+        if (!arguments) {
+            JSActivation* activation = static_cast&lt;JSActivation*&gt;(r[RegisterFile::OptionalCalleeActivation].getJSValue());
+            if (activation)
+                arguments = new (exec) Arguments(exec, activation);
+            else
+                arguments = new (exec) Arguments(exec, r);
+            r[RegisterFile::OptionalCalleeArguments] = arguments;
</ins><span class="cx">         }
</span><del>-
-        arguments = activation-&gt;createArgumentsObject(exec);
-        r[RegisterFile::OptionalCalleeArguments] = arguments;
</del><ins>+        ASSERT(arguments-&gt;isObject(&amp;Arguments::info));
</ins><span class="cx">     }
</span><span class="cx"> 
</span><span class="cx">     return arguments;
</span><span class="lines">@@ -4599,21 +4622,31 @@
</span><span class="cx"> {
</span><span class="cx">     ExecState* exec = ARG_exec;
</span><span class="cx">     Register* r = ARG_r;
</span><del>-    JSActivation* activation = static_cast&lt;JSActivation*&gt;(r[RegisterFile::OptionalCalleeActivation].getJSValue());
-    r[RegisterFile::OptionalCalleeArguments] = activation-&gt;createArgumentsObject(exec);
</del><ins>+
+    JSValue* activation = r[RegisterFile::OptionalCalleeActivation].getJSValue();
+    Arguments* arguments;
+    if (activation) {
+        ASSERT(activation-&gt;isObject(&amp;JSActivation::info));
+        arguments = new (exec) Arguments(exec, static_cast&lt;JSActivation*&gt;(activation));
+    } else
+        arguments = new (exec) Arguments(exec, r);
+    r[RegisterFile::OptionalCalleeArguments] = arguments;
+    r[RegisterFile::ArgumentsRegister] = arguments;
</ins><span class="cx"> }
</span><span class="cx"> 
</span><del>-void Machine::cti_op_ret_activation(CTI_ARGS)
</del><ins>+void Machine::cti_op_ret_activation_arguments(CTI_ARGS)
</ins><span class="cx"> {
</span><del>-    ExecState* exec = ARG_exec;
</del><span class="cx">     Register* r = ARG_r;
</span><span class="cx"> 
</span><del>-    JSActivation* activation = static_cast&lt;JSActivation*&gt;(r[RegisterFile::OptionalCalleeActivation].jsValue(exec));
-    ASSERT(activation);
-
-    ASSERT(!codeBlock(r)-&gt;needsFullScopeChain || scopeChain(r)-&gt;object == activation);
-    ASSERT(activation-&gt;isObject(&amp;JSActivation::info));
-    activation-&gt;copyRegisters();
</del><ins>+    // If this call frame created an activation or an 'arguments' object, tear it off.
+    if (JSActivation* activation = static_cast&lt;JSActivation*&gt;(r[RegisterFile::OptionalCalleeActivation].getJSValue())) {
+        ASSERT(!codeBlock(r)-&gt;needsFullScopeChain || scopeChain(r)-&gt;object == activation);
+        ASSERT(activation-&gt;isObject(&amp;JSActivation::info));
+        activation-&gt;copyRegisters(r[RegisterFile::OptionalCalleeArguments].getJSValue());
+    } else if (Arguments* arguments = static_cast&lt;Arguments*&gt;(r[RegisterFile::OptionalCalleeArguments].getJSValue())) {
+        ASSERT(arguments-&gt;isObject(&amp;Arguments::info));
+        arguments-&gt;copyRegisters();
+    }
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> void Machine::cti_op_ret_profiler(CTI_ARGS)
</span></span></pre></div>
<a id="trunkJavaScriptCoreVMMachineh"></a>
<div class="modfile"><h4>Modified: trunk/JavaScriptCore/VM/Machine.h (37159 => 37160)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/JavaScriptCore/VM/Machine.h        2008-10-01 22:12:23 UTC (rev 37159)
+++ trunk/JavaScriptCore/VM/Machine.h        2008-10-01 22:18:50 UTC (rev 37160)
</span><span class="lines">@@ -163,7 +163,7 @@
</span><span class="cx">         static void* SFX_CALL cti_op_call_JSFunction(CTI_ARGS);
</span><span class="cx">         static JSValue* SFX_CALL cti_op_call_NotJSFunction(CTI_ARGS);
</span><span class="cx">         static void SFX_CALL cti_op_init_arguments(CTI_ARGS);
</span><del>-        static void SFX_CALL cti_op_ret_activation(CTI_ARGS);
</del><ins>+        static void SFX_CALL cti_op_ret_activation_arguments(CTI_ARGS);
</ins><span class="cx">         static void SFX_CALL cti_op_ret_profiler(CTI_ARGS);
</span><span class="cx">         static void SFX_CALL cti_op_ret_scopeChain(CTI_ARGS);
</span><span class="cx">         static JSValue* SFX_CALL cti_op_new_array(CTI_ARGS);
</span></span></pre></div>
<a id="trunkJavaScriptCoreVMRegisterFileh"></a>
<div class="modfile"><h4>Modified: trunk/JavaScriptCore/VM/RegisterFile.h (37159 => 37160)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/JavaScriptCore/VM/RegisterFile.h        2008-10-01 22:12:23 UTC (rev 37159)
+++ trunk/JavaScriptCore/VM/RegisterFile.h        2008-10-01 22:18:50 UTC (rev 37160)
</span><span class="lines">@@ -104,6 +104,7 @@
</span><span class="cx">         };
</span><span class="cx"> 
</span><span class="cx">         enum { ProgramCodeThisRegister = -CallFrameHeaderSize - 1 };
</span><ins>+        enum { ArgumentsRegister = 0 };
</ins><span class="cx"> 
</span><span class="cx">         enum { DefaultCapacity = 2 * 1024 * 1024 / sizeof(Register) };
</span><span class="cx">         enum { DefaultMaxGlobals = 8 * 1024 };
</span></span></pre></div>
<a id="trunkJavaScriptCorekjsArgumentscpp"></a>
<div class="modfile"><h4>Modified: trunk/JavaScriptCore/kjs/Arguments.cpp (37159 => 37160)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/JavaScriptCore/kjs/Arguments.cpp        2008-10-01 22:12:23 UTC (rev 37159)
+++ trunk/JavaScriptCore/kjs/Arguments.cpp        2008-10-01 22:18:50 UTC (rev 37160)
</span><span class="lines">@@ -37,53 +37,6 @@
</span><span class="cx"> 
</span><span class="cx"> const ClassInfo Arguments::info = { &quot;Arguments&quot;, 0, 0, 0 };
</span><span class="cx"> 
</span><del>-struct ArgumentsData : Noncopyable {
-    ArgumentsData(JSActivation* activation, unsigned numParameters, int firstParameterIndex, unsigned numArguments, JSFunction* callee)
-        : activation(activation)
-        , numParameters(numParameters)
-        , firstParameterIndex(firstParameterIndex)
-        , numArguments(numArguments)
-        , extraArguments(0)
-        , callee(callee)
-        , overrodeLength(false)
-        , overrodeCallee(false)
-    {
-    }
-
-    JSActivation* activation;
-
-    unsigned numParameters;
-    int firstParameterIndex;
-    unsigned numArguments;
-    Register* extraArguments;
-    OwnArrayPtr&lt;bool&gt; deletedArguments;
-    Register extraArgumentsFixedBuffer[4];
-
-    JSFunction* callee;
-    bool overrodeLength : 1;
-    bool overrodeCallee : 1;
-};
-
-// ECMA 10.1.8
-Arguments::Arguments(ExecState* exec, JSFunction* function, JSActivation* activation, int firstParameterIndex, Register* argv, int argc)
-    : JSObject(exec-&gt;lexicalGlobalObject()-&gt;argumentsStructure())
-    , d(new ArgumentsData(activation, function-&gt;numParameters(), firstParameterIndex, argc, function))
-{
-    ASSERT(activation);
-  
-    if (d-&gt;numArguments &gt; d-&gt;numParameters) {
-        unsigned numExtraArguments = d-&gt;numArguments - d-&gt;numParameters;
-        Register* extraArguments;
-        if (numExtraArguments &gt; sizeof(d-&gt;extraArgumentsFixedBuffer) / sizeof(Register))
-            extraArguments = new Register[numExtraArguments];
-        else
-            extraArguments = d-&gt;extraArgumentsFixedBuffer;
-        for (unsigned i = 0; i &lt; numExtraArguments; ++i)
-            extraArguments[i] = argv[d-&gt;numParameters + i];
-        d-&gt;extraArguments = extraArguments;
-    }
-}
-
</del><span class="cx"> Arguments::~Arguments()
</span><span class="cx"> {
</span><span class="cx">     if (d-&gt;extraArguments != d-&gt;extraArgumentsFixedBuffer)
</span><span class="lines">@@ -94,6 +47,11 @@
</span><span class="cx"> {
</span><span class="cx">     JSObject::mark();
</span><span class="cx"> 
</span><ins>+    for (unsigned i = 0; i &lt; d-&gt;numParameters; ++i) {
+        if (!d-&gt;registers[i].marked())
+            d-&gt;registers[i].mark();
+    }
+
</ins><span class="cx">     if (d-&gt;extraArguments) {
</span><span class="cx">         unsigned numExtraArguments = d-&gt;numArguments - d-&gt;numParameters;
</span><span class="cx">         for (unsigned i = 0; i &lt; numExtraArguments; ++i) {
</span><span class="lines">@@ -105,7 +63,7 @@
</span><span class="cx">     if (!d-&gt;callee-&gt;marked())
</span><span class="cx">         d-&gt;callee-&gt;mark();
</span><span class="cx"> 
</span><del>-    if (!d-&gt;activation-&gt;marked())
</del><ins>+    if (d-&gt;activation &amp;&amp; !d-&gt;activation-&gt;marked())
</ins><span class="cx">         d-&gt;activation-&gt;mark();
</span><span class="cx"> }
</span><span class="cx"> 
</span><span class="lines">@@ -118,16 +76,16 @@
</span><span class="cx">         }
</span><span class="cx"> 
</span><span class="cx">         if (d-&gt;numParameters == d-&gt;numArguments) {
</span><del>-            args.initialize(&amp;d-&gt;activation-&gt;registerAt(d-&gt;firstParameterIndex), d-&gt;numArguments);
</del><ins>+            args.initialize(&amp;d-&gt;registers[d-&gt;firstParameterIndex], d-&gt;numArguments);
</ins><span class="cx">             return;
</span><span class="cx">         }
</span><span class="cx"> 
</span><span class="cx">         unsigned parametersLength = min(d-&gt;numParameters, d-&gt;numArguments);
</span><span class="cx">         unsigned i = 0;
</span><span class="cx">         for (; i &lt; parametersLength; ++i)
</span><del>-            args.append(d-&gt;activation-&gt;uncheckedSymbolTableGetValue(d-&gt;firstParameterIndex + i));
</del><ins>+            args.append(d-&gt;registers[d-&gt;firstParameterIndex + i].jsValue(exec));
</ins><span class="cx">         for (; i &lt; d-&gt;numArguments; ++i)
</span><del>-            args.append(d-&gt;extraArguments[i - d-&gt;numParameters].getJSValue());
</del><ins>+            args.append(d-&gt;extraArguments[i - d-&gt;numParameters].jsValue(exec));
</ins><span class="cx">         return;
</span><span class="cx">     }
</span><span class="cx"> 
</span><span class="lines">@@ -135,13 +93,13 @@
</span><span class="cx">     unsigned i = 0;
</span><span class="cx">     for (; i &lt; parametersLength; ++i) {
</span><span class="cx">         if (!d-&gt;deletedArguments[i])
</span><del>-            args.append(d-&gt;activation-&gt;uncheckedSymbolTableGetValue(d-&gt;firstParameterIndex + i));
</del><ins>+            args.append(d-&gt;registers[d-&gt;firstParameterIndex + i].jsValue(exec));
</ins><span class="cx">         else
</span><span class="cx">             args.append(get(exec, i));
</span><span class="cx">     }
</span><span class="cx">     for (; i &lt; d-&gt;numArguments; ++i) {
</span><span class="cx">         if (!d-&gt;deletedArguments[i])
</span><del>-            args.append(d-&gt;extraArguments[i - d-&gt;numParameters].getJSValue());
</del><ins>+            args.append(d-&gt;extraArguments[i - d-&gt;numParameters].jsValue(exec));
</ins><span class="cx">         else
</span><span class="cx">             args.append(get(exec, i));
</span><span class="cx">     }
</span><span class="lines">@@ -151,9 +109,9 @@
</span><span class="cx"> {
</span><span class="cx">     if (i &lt; d-&gt;numArguments &amp;&amp; (!d-&gt;deletedArguments || !d-&gt;deletedArguments[i])) {
</span><span class="cx">         if (i &lt; d-&gt;numParameters)
</span><del>-            d-&gt;activation-&gt;uncheckedSymbolTableGet(d-&gt;firstParameterIndex + i, slot);
</del><ins>+            slot.setRegisterSlot(&amp;d-&gt;registers[d-&gt;firstParameterIndex + i]);
</ins><span class="cx">         else
</span><del>-            slot.setValue(d-&gt;extraArguments[i - d-&gt;numParameters].getJSValue());
</del><ins>+            slot.setValue(d-&gt;extraArguments[i - d-&gt;numParameters].jsValue(exec));
</ins><span class="cx">         return true;
</span><span class="cx">     }
</span><span class="cx"> 
</span><span class="lines">@@ -166,9 +124,9 @@
</span><span class="cx">     unsigned i = propertyName.toArrayIndex(&amp;isArrayIndex);
</span><span class="cx">     if (isArrayIndex &amp;&amp; i &lt; d-&gt;numArguments &amp;&amp; (!d-&gt;deletedArguments || !d-&gt;deletedArguments[i])) {
</span><span class="cx">         if (i &lt; d-&gt;numParameters)
</span><del>-            d-&gt;activation-&gt;uncheckedSymbolTableGet(d-&gt;firstParameterIndex + i, slot);
</del><ins>+            slot.setRegisterSlot(&amp;d-&gt;registers[d-&gt;firstParameterIndex + i]);
</ins><span class="cx">         else
</span><del>-            slot.setValue(d-&gt;extraArguments[i - d-&gt;numParameters].getJSValue());
</del><ins>+            slot.setValue(d-&gt;extraArguments[i - d-&gt;numParameters].jsValue(exec));
</ins><span class="cx">         return true;
</span><span class="cx">     }
</span><span class="cx"> 
</span><span class="lines">@@ -189,7 +147,7 @@
</span><span class="cx"> {
</span><span class="cx">     if (i &lt; d-&gt;numArguments &amp;&amp; (!d-&gt;deletedArguments || !d-&gt;deletedArguments[i])) {
</span><span class="cx">         if (i &lt; d-&gt;numParameters)
</span><del>-            d-&gt;activation-&gt;uncheckedSymbolTablePut(d-&gt;firstParameterIndex + i, value);
</del><ins>+            d-&gt;registers[d-&gt;firstParameterIndex + i] = value;
</ins><span class="cx">         else
</span><span class="cx">             d-&gt;extraArguments[i - d-&gt;numParameters] = value;
</span><span class="cx">         return;
</span><span class="lines">@@ -204,7 +162,7 @@
</span><span class="cx">     unsigned i = propertyName.toArrayIndex(&amp;isArrayIndex);
</span><span class="cx">     if (isArrayIndex &amp;&amp; i &lt; d-&gt;numArguments &amp;&amp; (!d-&gt;deletedArguments || !d-&gt;deletedArguments[i])) {
</span><span class="cx">         if (i &lt; d-&gt;numParameters)
</span><del>-            d-&gt;activation-&gt;uncheckedSymbolTablePut(d-&gt;firstParameterIndex + i, value);
</del><ins>+            d-&gt;registers[d-&gt;firstParameterIndex + i] = value;
</ins><span class="cx">         else
</span><span class="cx">             d-&gt;extraArguments[i - d-&gt;numParameters] = value;
</span><span class="cx">         return;
</span></span></pre></div>
<a id="trunkJavaScriptCorekjsArgumentsh"></a>
<div class="modfile"><h4>Modified: trunk/JavaScriptCore/kjs/Arguments.h (37159 => 37160)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/JavaScriptCore/kjs/Arguments.h        2008-10-01 22:12:23 UTC (rev 37159)
+++ trunk/JavaScriptCore/kjs/Arguments.h        2008-10-01 22:18:50 UTC (rev 37160)
</span><span class="lines">@@ -24,19 +24,37 @@
</span><span class="cx"> #ifndef Arguments_h
</span><span class="cx"> #define Arguments_h
</span><span class="cx"> 
</span><del>-#include &quot;JSObject.h&quot;
</del><ins>+#include &quot;JSActivation.h&quot;
+#include &quot;JSFunction.h&quot;
+#include &quot;JSGlobalObject.h&quot;
+#include &quot;Machine.h&quot;
</ins><span class="cx"> 
</span><span class="cx"> namespace JSC {
</span><span class="cx"> 
</span><del>-    class JSActivation;
-    class JSFunction;
-    class Register;
</del><ins>+    struct ArgumentsData : Noncopyable {
+        JSActivation* activation;
</ins><span class="cx"> 
</span><del>-    struct ArgumentsData;
</del><ins>+        unsigned numParameters;
+        int firstParameterIndex;
+        unsigned numArguments;
</ins><span class="cx"> 
</span><ins>+        Register* registers;
+        OwnArrayPtr&lt;Register&gt; registerArray;
+
+        Register* extraArguments;
+        OwnArrayPtr&lt;bool&gt; deletedArguments;
+        Register extraArgumentsFixedBuffer[4];
+
+        JSFunction* callee;
+        bool overrodeLength : 1;
+        bool overrodeCallee : 1;
+    };
+
+
</ins><span class="cx">     class Arguments : public JSObject {
</span><span class="cx">     public:
</span><del>-        Arguments(ExecState*, JSFunction*, JSActivation*, int firstArgumentIndex, Register* argv, int argc);
</del><ins>+        Arguments(ExecState*, Register* callFrame);
+        Arguments(ExecState*, JSActivation*);
</ins><span class="cx">         virtual ~Arguments();
</span><span class="cx"> 
</span><span class="cx">         static const ClassInfo info;
</span><span class="lines">@@ -45,6 +63,9 @@
</span><span class="cx"> 
</span><span class="cx">         void fillArgList(ExecState*, ArgList&amp;);
</span><span class="cx"> 
</span><ins>+        void copyRegisters();
+        void setRegisters(Register* registers) { d-&gt;registers = registers; }
+
</ins><span class="cx">     private:
</span><span class="cx">         virtual bool getOwnPropertySlot(ExecState*, const Identifier&amp; propertyName, PropertySlot&amp;);
</span><span class="cx">         virtual bool getOwnPropertySlot(ExecState*, unsigned propertyName, PropertySlot&amp;);
</span><span class="lines">@@ -55,9 +76,104 @@
</span><span class="cx"> 
</span><span class="cx">         virtual const ClassInfo* classInfo() const { return &amp;info; }
</span><span class="cx"> 
</span><ins>+        void init(ExecState*, Register* callFrame);
+
</ins><span class="cx">         OwnPtr&lt;ArgumentsData&gt; d;
</span><span class="cx">     };
</span><span class="cx"> 
</span><ins>+    inline void Arguments::init(ExecState* exec, Register* callFrame)
+    {
+        JSFunction* callee;
+        int firstParameterIndex;
+        Register* argv;
+        int numArguments;
+        exec-&gt;machine()-&gt;getArgumentsData(callFrame, callee, firstParameterIndex, argv, numArguments);
+
+        d-&gt;numParameters = callee-&gt;numParameters();
+        d-&gt;firstParameterIndex = firstParameterIndex;
+        d-&gt;numArguments = numArguments;
+
+        d-&gt;registers = callFrame;
+
+        Register* extraArguments;
+        if (d-&gt;numArguments &lt;= d-&gt;numParameters)
+            extraArguments = 0;
+        else {
+            unsigned numExtraArguments = d-&gt;numArguments - d-&gt;numParameters;
+            if (numExtraArguments &gt; sizeof(d-&gt;extraArgumentsFixedBuffer) / sizeof(Register))
+                extraArguments = new Register[numExtraArguments];
+            else
+                extraArguments = d-&gt;extraArgumentsFixedBuffer;
+            for (unsigned i = 0; i &lt; numExtraArguments; ++i)
+                extraArguments[i] = argv[d-&gt;numParameters + i];
+        }
+
+        d-&gt;extraArguments = extraArguments;
+
+        d-&gt;callee = callee;
+        d-&gt;overrodeLength = false;
+        d-&gt;overrodeCallee = false;
+    }
+
+    inline Arguments::Arguments(ExecState* exec, Register* callFrame)
+        : JSObject(exec-&gt;lexicalGlobalObject()-&gt;argumentsStructure())
+        , d(new ArgumentsData)
+    {
+        d-&gt;activation = 0;
+        init(exec, callFrame);
+    }
+
+    inline Arguments::Arguments(ExecState* exec, JSActivation* activation)
+        : JSObject(exec-&gt;lexicalGlobalObject()-&gt;argumentsStructure())
+        , d(new ArgumentsData)
+    {
+        ASSERT(activation);
+        d-&gt;activation = activation;
+        init(exec, &amp;activation-&gt;registerAt(0));
+    }
+
+    inline void Arguments::copyRegisters()
+    {
+        ASSERT(!d-&gt;activation);
+        ASSERT(!d-&gt;registerArray);
+
+        size_t numParametersMinusThis = d-&gt;callee-&gt;m_body-&gt;generatedByteCode().numParameters - 1;
+
+        if (!numParametersMinusThis)
+            return;
+
+        int registerOffset = numParametersMinusThis + RegisterFile::CallFrameHeaderSize;
+        size_t registerArraySize = numParametersMinusThis;
+
+        Register* registerArray = new Register[registerArraySize];
+        memcpy(registerArray, d-&gt;registers - registerOffset, registerArraySize * sizeof(Register));
+        d-&gt;registerArray.set(registerArray);
+        d-&gt;registers = registerArray + registerOffset;
+    }
+
+    // This JSActivation function is defined here so it can get at Arguments::setRegisters.
+    inline void JSActivation::copyRegisters(JSValue* arguments)
+    {
+        ASSERT(!d()-&gt;registerArray);
+
+        size_t numParametersMinusThis = d()-&gt;functionBody-&gt;generatedByteCode().numParameters - 1;
+        size_t numVars = d()-&gt;functionBody-&gt;generatedByteCode().numVars;
+        size_t numLocals = numVars + numParametersMinusThis;
+
+        if (!numLocals)
+            return;
+
+        int registerOffset = numParametersMinusThis + RegisterFile::CallFrameHeaderSize;
+        size_t registerArraySize = numLocals + RegisterFile::CallFrameHeaderSize;
+
+        Register* registerArray = copyRegisterArray(d()-&gt;registers - registerOffset, registerArraySize);
+        setRegisters(registerArray + registerOffset, registerArray);
+        if (arguments) {
+            ASSERT(arguments-&gt;isObject(&amp;Arguments::info));
+            static_cast&lt;Arguments*&gt;(arguments)-&gt;setRegisters(registerArray + registerOffset);
+        }
+    }
+
</ins><span class="cx"> } // namespace JSC
</span><span class="cx"> 
</span><span class="cx"> #endif // Arguments_h
</span></span></pre></div>
<a id="trunkJavaScriptCorekjsJSActivationcpp"></a>
<div class="modfile"><h4>Modified: trunk/JavaScriptCore/kjs/JSActivation.cpp (37159 => 37160)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/JavaScriptCore/kjs/JSActivation.cpp        2008-10-01 22:12:23 UTC (rev 37159)
+++ trunk/JavaScriptCore/kjs/JSActivation.cpp        2008-10-01 22:18:50 UTC (rev 37160)
</span><span class="lines">@@ -155,10 +155,18 @@
</span><span class="cx"> {
</span><span class="cx">     JSActivation* thisObj = static_cast&lt;JSActivation*&gt;(slot.slotBase());
</span><span class="cx"> 
</span><del>-    Arguments* arguments = static_cast&lt;Arguments*&gt;(thisObj-&gt;d()-&gt;registers[RegisterFile::OptionalCalleeArguments].jsValue(exec));
-    if (!arguments) {
-        arguments = thisObj-&gt;createArgumentsObject(exec);
-        thisObj-&gt;d()-&gt;registers[RegisterFile::OptionalCalleeArguments] = arguments;
</del><ins>+    JSValue* arguments;
+    if (thisObj-&gt;d()-&gt;functionBody-&gt;usesArguments()) {
+        PropertySlot slot;
+        thisObj-&gt;symbolTableGet(exec-&gt;propertyNames().arguments, slot);
+        arguments = slot.getValue(exec, exec-&gt;propertyNames().arguments);
+    } else {
+        arguments = thisObj-&gt;d()-&gt;registers[RegisterFile::OptionalCalleeArguments].getJSValue();
+        if (!arguments) {
+            arguments = new (exec) Arguments(exec, thisObj);
+            thisObj-&gt;d()-&gt;registers[RegisterFile::OptionalCalleeArguments] = arguments;
+        }
+        ASSERT(arguments-&gt;isObject(&amp;Arguments::info));
</ins><span class="cx">     }
</span><span class="cx"> 
</span><span class="cx">     return arguments;
</span><span class="lines">@@ -172,15 +180,4 @@
</span><span class="cx">     return argumentsGetter;
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-Arguments* JSActivation::createArgumentsObject(ExecState* exec)
-{
-    JSFunction* function;
-    Register* argv;
-    int argc;
-    int firstParameterIndex;
-    exec-&gt;machine()-&gt;getArgumentsData(d()-&gt;registers, function, firstParameterIndex, argv, argc);
-
-    return new (exec) Arguments(exec, function, this, firstParameterIndex, argv, argc);
-}
-
</del><span class="cx"> } // namespace JSC
</span></span></pre></div>
<a id="trunkJavaScriptCorekjsJSActivationh"></a>
<div class="modfile"><h4>Modified: trunk/JavaScriptCore/kjs/JSActivation.h (37159 => 37160)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/JavaScriptCore/kjs/JSActivation.h        2008-10-01 22:12:23 UTC (rev 37159)
+++ trunk/JavaScriptCore/kjs/JSActivation.h        2008-10-01 22:18:50 UTC (rev 37160)
</span><span class="lines">@@ -43,53 +43,36 @@
</span><span class="cx">     class JSActivation : public JSVariableObject {
</span><span class="cx">         typedef JSVariableObject Base;
</span><span class="cx">     public:
</span><del>-        JSActivation(ExecState* exec, PassRefPtr&lt;FunctionBodyNode&gt;, Register*);
</del><ins>+        JSActivation(ExecState*, PassRefPtr&lt;FunctionBodyNode&gt;, Register*);
</ins><span class="cx">         virtual ~JSActivation();
</span><del>-        
</del><ins>+
</ins><span class="cx">         virtual void mark();
</span><span class="cx"> 
</span><span class="cx">         virtual bool isDynamicScope() const;
</span><span class="cx"> 
</span><span class="cx">         virtual bool getOwnPropertySlot(ExecState*, const Identifier&amp;, PropertySlot&amp;);
</span><span class="cx"> 
</span><del>-        inline void uncheckedSymbolTableGet(int index, PropertySlot&amp; slot)
-        {
-            slot.setRegisterSlot(&amp;registerAt(index));
-        }
-
-        inline JSValue* uncheckedSymbolTableGetValue(int index)
-        {
-            return registerAt(index).getJSValue();
-        }
-
</del><span class="cx">         virtual void put(ExecState*, const Identifier&amp;, JSValue*, PutPropertySlot&amp;);
</span><span class="cx"> 
</span><del>-        inline void uncheckedSymbolTablePut(int index, JSValue* value)
-        {
-            registerAt(index) = value;
-        }
-
</del><span class="cx">         virtual void putWithAttributes(ExecState*, const Identifier&amp;, JSValue*, unsigned attributes);
</span><span class="cx">         virtual bool deleteProperty(ExecState*, const Identifier&amp; propertyName);
</span><span class="cx"> 
</span><span class="cx">         virtual JSObject* toThisObject(ExecState*) const;
</span><span class="cx"> 
</span><del>-        void copyRegisters();
</del><ins>+        void copyRegisters(JSValue* arguments);
</ins><span class="cx">         
</span><span class="cx">         virtual const ClassInfo* classInfo() const { return &amp;info; }
</span><span class="cx">         static const ClassInfo info;
</span><span class="cx"> 
</span><del>-        NEVER_INLINE Arguments* createArgumentsObject(ExecState*);
-
</del><span class="cx">     private:
</span><span class="cx">         struct JSActivationData : public JSVariableObjectData {
</span><del>-            JSActivationData(PassRefPtr&lt;FunctionBodyNode&gt; functionBody_, Register* registers)
-                : JSVariableObjectData(&amp;functionBody_-&gt;symbolTable(), registers)
-                , functionBody(functionBody_)
</del><ins>+            JSActivationData(PassRefPtr&lt;FunctionBodyNode&gt; functionBody, Register* registers)
+                : JSVariableObjectData(&amp;functionBody-&gt;symbolTable(), registers)
+                , functionBody(functionBody)
</ins><span class="cx">             {
</span><span class="cx">             }
</span><span class="cx"> 
</span><del>-            RefPtr&lt;FunctionBodyNode&gt; functionBody; // Owns the symbol table and code block
</del><ins>+            RefPtr&lt;FunctionBodyNode&gt; functionBody;
</ins><span class="cx">         };
</span><span class="cx">         
</span><span class="cx">         static JSValue* argumentsGetter(ExecState*, const Identifier&amp;, const PropertySlot&amp;);
</span><span class="lines">@@ -98,24 +81,6 @@
</span><span class="cx">         JSActivationData* d() const { return static_cast&lt;JSActivationData*&gt;(JSVariableObject::d); }
</span><span class="cx">     };
</span><span class="cx">     
</span><del>-    inline void JSActivation::copyRegisters()
-    {
-        ASSERT(!d()-&gt;registerArray);
-
-        size_t numParametersMinusThis = d()-&gt;functionBody-&gt;generatedByteCode().numParameters - 1;
-        size_t numVars = d()-&gt;functionBody-&gt;generatedByteCode().numVars;
-        size_t numLocals = numVars + numParametersMinusThis;
-
-        if (!numLocals)
-            return;
-
-        int registerOffset = numParametersMinusThis + RegisterFile::CallFrameHeaderSize;
-        size_t registerArraySize = numLocals + RegisterFile::CallFrameHeaderSize;
-
-        Register* registerArray = copyRegisterArray(d()-&gt;registers - registerOffset, registerArraySize);
-        setRegisters(registerArray + registerOffset, registerArray);
-    }
-
</del><span class="cx"> } // namespace JSC
</span><span class="cx"> 
</span><span class="cx"> #endif // JSActivation_h
</span></span></pre></div>
<a id="trunkJavaScriptCorekjsgrammary"></a>
<div class="modfile"><h4>Modified: trunk/JavaScriptCore/kjs/grammar.y (37159 => 37160)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/JavaScriptCore/kjs/grammar.y        2008-10-01 22:12:23 UTC (rev 37159)
+++ trunk/JavaScriptCore/kjs/grammar.y        2008-10-01 22:18:50 UTC (rev 37160)
</span><span class="lines">@@ -314,7 +314,7 @@
</span><span class="cx">   | NUMBER ':' AssignmentExpr           { $$ = createNodeFeatureInfo&lt;PropertyNode*&gt;(new PropertyNode(GLOBAL_DATA, Identifier(GLOBAL_DATA, UString::from($1)), $3.m_node, PropertyNode::Constant), $3.m_featureInfo, $3.m_numConstants); }
</span><span class="cx">   | IDENT IDENT '(' ')' OPENBRACE FunctionBody CLOSEBRACE    { $$ = createNodeFeatureInfo&lt;PropertyNode*&gt;(makeGetterOrSetterPropertyNode(globalPtr, *$1, *$2, 0, $6, LEXER-&gt;sourceRange($5, $7)), ClosureFeature, 0); DBG($6, @5, @7); if (!$$.m_node) YYABORT; }
</span><span class="cx">   | IDENT IDENT '(' FormalParameterList ')' OPENBRACE FunctionBody CLOSEBRACE
</span><del>-                                        { $$ = createNodeFeatureInfo&lt;PropertyNode*&gt;(makeGetterOrSetterPropertyNode(globalPtr, *$1, *$2, $4.m_node.head, $7, LEXER-&gt;sourceRange($6, $8)), $4.m_featureInfo | ClosureFeature, 0); DBG($7, @6, @8); if (!$$.m_node) YYABORT; }
</del><ins>+                                        { $$ = createNodeFeatureInfo&lt;PropertyNode*&gt;(makeGetterOrSetterPropertyNode(globalPtr, *$1, *$2, $4.m_node.head, $7, LEXER-&gt;sourceRange($6, $8)), $4.m_featureInfo | ClosureFeature, 0); $7-&gt;setUsesArguments($7-&gt;usesArguments() | ($4.m_featureInfo &amp; ArgumentsFeature)); DBG($7, @6, @8); if (!$$.m_node) YYABORT; }
</ins><span class="cx"> ;
</span><span class="cx"> 
</span><span class="cx"> PropertyList:
</span><span class="lines">@@ -1159,14 +1159,14 @@
</span><span class="cx"> FunctionDeclaration:
</span><span class="cx">     FUNCTION IDENT '(' ')' OPENBRACE FunctionBody CLOSEBRACE { $$ = createNodeFeatureInfo(new FuncDeclNode(GLOBAL_DATA, *$2, $6, LEXER-&gt;sourceRange($5, $7)), ((*$2 == GLOBAL_DATA-&gt;propertyNames-&gt;arguments) ? ArgumentsFeature : 0) | ClosureFeature, 0); DBG($6, @5, @7); }
</span><span class="cx">   | FUNCTION IDENT '(' FormalParameterList ')' OPENBRACE FunctionBody CLOSEBRACE
</span><del>-      { $$ = createNodeFeatureInfo(new FuncDeclNode(GLOBAL_DATA, *$2, $7, LEXER-&gt;sourceRange($6, $8), $4.m_node.head), ((*$2 == GLOBAL_DATA-&gt;propertyNames-&gt;arguments) ? ArgumentsFeature : 0) | $4.m_featureInfo | ClosureFeature, 0); DBG($7, @6, @8); }
</del><ins>+      { $$ = createNodeFeatureInfo(new FuncDeclNode(GLOBAL_DATA, *$2, $7, LEXER-&gt;sourceRange($6, $8), $4.m_node.head), ((*$2 == GLOBAL_DATA-&gt;propertyNames-&gt;arguments) ? ArgumentsFeature : 0) | $4.m_featureInfo | ClosureFeature, 0); $7-&gt;setUsesArguments($7-&gt;usesArguments() | ($4.m_featureInfo &amp; ArgumentsFeature)); DBG($7, @6, @8); }
</ins><span class="cx"> ;
</span><span class="cx"> 
</span><span class="cx"> FunctionExpr:
</span><span class="cx">     FUNCTION '(' ')' OPENBRACE FunctionBody CLOSEBRACE { $$ = createNodeFeatureInfo(new FuncExprNode(GLOBAL_DATA, GLOBAL_DATA-&gt;propertyNames-&gt;nullIdentifier, $5, LEXER-&gt;sourceRange($4, $6)), ClosureFeature, 0); DBG($5, @4, @6); }
</span><del>-  | FUNCTION '(' FormalParameterList ')' OPENBRACE FunctionBody CLOSEBRACE { $$ = createNodeFeatureInfo(new FuncExprNode(GLOBAL_DATA, GLOBAL_DATA-&gt;propertyNames-&gt;nullIdentifier, $6, LEXER-&gt;sourceRange($5, $7), $3.m_node.head), $3.m_featureInfo | ClosureFeature, 0); DBG($6, @5, @7); }
</del><ins>+    | FUNCTION '(' FormalParameterList ')' OPENBRACE FunctionBody CLOSEBRACE { $$ = createNodeFeatureInfo(new FuncExprNode(GLOBAL_DATA, GLOBAL_DATA-&gt;propertyNames-&gt;nullIdentifier, $6, LEXER-&gt;sourceRange($5, $7), $3.m_node.head), $3.m_featureInfo | ClosureFeature, 0); $6-&gt;setUsesArguments($6-&gt;usesArguments() | ($3.m_featureInfo &amp; ArgumentsFeature)); DBG($6, @5, @7); }
</ins><span class="cx">   | FUNCTION IDENT '(' ')' OPENBRACE FunctionBody CLOSEBRACE { $$ = createNodeFeatureInfo(new FuncExprNode(GLOBAL_DATA, *$2, $6, LEXER-&gt;sourceRange($5, $7)), ClosureFeature, 0); DBG($6, @5, @7); }
</span><del>-  | FUNCTION IDENT '(' FormalParameterList ')' OPENBRACE FunctionBody CLOSEBRACE { $$ = createNodeFeatureInfo(new FuncExprNode(GLOBAL_DATA, *$2, $7, LEXER-&gt;sourceRange($6, $8), $4.m_node.head), $4.m_featureInfo | ClosureFeature, 0); DBG($7, @6, @8); }
</del><ins>+  | FUNCTION IDENT '(' FormalParameterList ')' OPENBRACE FunctionBody CLOSEBRACE { $$ = createNodeFeatureInfo(new FuncExprNode(GLOBAL_DATA, *$2, $7, LEXER-&gt;sourceRange($6, $8), $4.m_node.head), $4.m_featureInfo | ClosureFeature, 0); $7-&gt;setUsesArguments($7-&gt;usesArguments() | ($4.m_featureInfo &amp; ArgumentsFeature)); DBG($7, @6, @8); }
</ins><span class="cx"> ;
</span><span class="cx"> 
</span><span class="cx"> FormalParameterList:
</span></span></pre></div>
<a id="trunkJavaScriptCorekjsnodesh"></a>
<div class="modfile"><h4>Modified: trunk/JavaScriptCore/kjs/nodes.h (37159 => 37160)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/JavaScriptCore/kjs/nodes.h        2008-10-01 22:12:23 UTC (rev 37159)
+++ trunk/JavaScriptCore/kjs/nodes.h        2008-10-01 22:18:50 UTC (rev 37160)
</span><span class="lines">@@ -2176,6 +2176,7 @@
</span><span class="cx">         bool usesEval() const { return m_usesEval; }
</span><span class="cx">         bool needsClosure() const { return m_needsClosure; }
</span><span class="cx">         bool usesArguments() const { return m_usesArguments; }
</span><ins>+        void setUsesArguments(bool usesArguments) { m_usesArguments = usesArguments; }
</ins><span class="cx"> 
</span><span class="cx">         VarStack&amp; varStack() { return m_varStack; }
</span><span class="cx">         FunctionStack&amp; functionStack() { return m_functionStack; }
</span></span></pre></div>
<a id="trunkJavaScriptCoremasmX86Assemblerh"></a>
<div class="modfile"><h4>Modified: trunk/JavaScriptCore/masm/X86Assembler.h (37159 => 37160)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/JavaScriptCore/masm/X86Assembler.h        2008-10-01 22:12:23 UTC (rev 37159)
+++ trunk/JavaScriptCore/masm/X86Assembler.h        2008-10-01 22:18:50 UTC (rev 37160)
</span><span class="lines">@@ -183,6 +183,7 @@
</span><span class="cx">         OP_ADD_EvGv                     = 0x01,
</span><span class="cx">         OP_ADD_GvEv                     = 0x03,
</span><span class="cx">         OP_OR_EvGv                      = 0x09,
</span><ins>+        OP_OR_GvEv                      = 0x0B,
</ins><span class="cx">         OP_2BYTE_ESCAPE                 = 0x0F,
</span><span class="cx">         OP_AND_EvGv                     = 0x21,
</span><span class="cx">         OP_SUB_EvGv                     = 0x29,
</span><span class="lines">@@ -443,6 +444,12 @@
</span><span class="cx">         emitModRm_rr(src, dst);
</span><span class="cx">     }
</span><span class="cx"> 
</span><ins>+    void orl_mr(int offset, RegisterID base, RegisterID dst)
+    {
+        m_buffer-&gt;putByte(OP_OR_GvEv);
+        emitModRm_rm(dst, base, offset);
+    }
+
</ins><span class="cx">     void orl_i32r(int imm, RegisterID dst)
</span><span class="cx">     {
</span><span class="cx">         m_buffer-&gt;putByte(OP_GROUP1_EvIb);
</span></span></pre></div>
<a id="trunkLayoutTestsChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/LayoutTests/ChangeLog (37159 => 37160)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/ChangeLog        2008-10-01 22:12:23 UTC (rev 37159)
+++ trunk/LayoutTests/ChangeLog        2008-10-01 22:18:50 UTC (rev 37160)
</span><span class="lines">@@ -1,3 +1,16 @@
</span><ins>+2008-10-01  Cameron Zwarich  &lt;zwarich@apple.com&gt;
+
+        Reviewed by Darin Adler.
+
+        Add some tests for the 'arguments' object. The included failures are
+        intentional. They are for regressions introduced in r37050, and they
+        will hopefully be fixed in the near future.
+
+        * fast/js/arguments-expected.txt:
+        * fast/js/function-dot-arguments-expected.txt:
+        * fast/js/resources/arguments.js:
+        * fast/js/resources/function-dot-arguments.js:
+
</ins><span class="cx"> 2008-10-01  Kevin McCullough  &lt;kmccullough@apple.com&gt;
</span><span class="cx"> 
</span><span class="cx">         Reviewed by Dan Bernstein.
</span></span></pre></div>
<a id="trunkLayoutTestsfastjsargumentsexpectedtxt"></a>
<div class="modfile"><h4>Modified: trunk/LayoutTests/fast/js/arguments-expected.txt (37159 => 37160)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/fast/js/arguments-expected.txt        2008-10-01 22:12:23 UTC (rev 37159)
+++ trunk/LayoutTests/fast/js/arguments-expected.txt        2008-10-01 22:18:50 UTC (rev 37160)
</span><span class="lines">@@ -125,6 +125,8 @@
</span><span class="cx"> PASS access_after_delete_extra_3(1, 2, 3, 4, 5) is 3
</span><span class="cx"> PASS access_after_delete_extra_5(1, 2, 3, 4, 5) is 5
</span><span class="cx"> PASS argumentsParam(true) is true
</span><ins>+FAIL argumentsVarUndefined() should be undefined. Was [object Arguments]
+FAIL argumentsConstUndefined() should be undefined. Was [object Arguments]
</ins><span class="cx"> PASS successfullyParsed is true
</span><span class="cx"> 
</span><span class="cx"> TEST COMPLETE
</span></span></pre></div>
<a id="trunkLayoutTestsfastjsfunctiondotargumentsexpectedtxt"></a>
<div class="modfile"><h4>Modified: trunk/LayoutTests/fast/js/function-dot-arguments-expected.txt (37159 => 37160)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/fast/js/function-dot-arguments-expected.txt        2008-10-01 22:12:23 UTC (rev 37159)
+++ trunk/LayoutTests/fast/js/function-dot-arguments-expected.txt        2008-10-01 22:18:50 UTC (rev 37160)
</span><span class="lines">@@ -4,14 +4,20 @@
</span><span class="cx"> 
</span><span class="cx"> 
</span><span class="cx"> PASS assignTest() is true
</span><ins>+FAIL assignVarUndefinedTest() should be undefined. Was [object Arguments]
+FAIL assignVarUndefinedTest2() should be undefined. Was [object Arguments]
</ins><span class="cx"> PASS assignVarInitTest() is true
</span><span class="cx"> PASS assignVarInitTest2() is true
</span><ins>+FAIL assignConstUndefinedTest() should be undefined. Was [object Arguments]
+FAIL assignConstUndefinedTest2() should be undefined. Was [object Arguments]
</ins><span class="cx"> PASS assignConstInitTest() is true
</span><span class="cx"> PASS assignConstInitTest2() is true
</span><span class="cx"> PASS assignForInitTest() is true
</span><span class="cx"> PASS assignForInitTest2() is true
</span><span class="cx"> PASS assignForInInitTest() is true
</span><del>-FAIL paramInitTest(true) should be true (of type boolean). Was [object Arguments] (of type object).
</del><ins>+PASS paramInitTest(true) is true
+PASS tearOffTest()[0] is true
+PASS tearOffTest2(true)[0] is true
</ins><span class="cx"> PASS successfullyParsed is true
</span><span class="cx"> 
</span><span class="cx"> TEST COMPLETE
</span></span></pre></div>
<a id="trunkLayoutTestsfastjsresourcesargumentsjs"></a>
<div class="modfile"><h4>Modified: trunk/LayoutTests/fast/js/resources/arguments.js (37159 => 37160)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/fast/js/resources/arguments.js        2008-10-01 22:12:23 UTC (rev 37159)
+++ trunk/LayoutTests/fast/js/resources/arguments.js        2008-10-01 22:18:50 UTC (rev 37160)
</span><span class="lines">@@ -506,7 +506,20 @@
</span><span class="cx"> {
</span><span class="cx">     return arguments;
</span><span class="cx"> }
</span><del>-
</del><span class="cx"> shouldBeTrue(&quot;argumentsParam(true)&quot;);
</span><span class="cx"> 
</span><ins>+function argumentsVarUndefined()
+{
+    var arguments;
+    return arguments;
+}
+shouldBeUndefined(&quot;argumentsVarUndefined()&quot;);
+
+function argumentsConstUndefined()
+{
+    const arguments;
+    return arguments;
+}
+shouldBeUndefined(&quot;argumentsConstUndefined()&quot;);
+
</ins><span class="cx"> var successfullyParsed = true;
</span></span></pre></div>
<a id="trunkLayoutTestsfastjsresourcesfunctiondotargumentsjs"></a>
<div class="modfile"><h4>Modified: trunk/LayoutTests/fast/js/resources/function-dot-arguments.js (37159 => 37160)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/fast/js/resources/function-dot-arguments.js        2008-10-01 22:12:23 UTC (rev 37159)
+++ trunk/LayoutTests/fast/js/resources/function-dot-arguments.js        2008-10-01 22:18:50 UTC (rev 37160)
</span><span class="lines">@@ -12,9 +12,32 @@
</span><span class="cx">     arguments = true;
</span><span class="cx">     return g();
</span><span class="cx"> }
</span><del>-
</del><span class="cx"> shouldBeTrue(&quot;assignTest()&quot;);
</span><span class="cx"> 
</span><ins>+function assignVarUndefinedTest()
+{
+    function g()
+    {
+        return assignVarUndefinedTest.arguments;
+    }
+
+    var arguments;
+    return g();
+}
+shouldBeUndefined(&quot;assignVarUndefinedTest()&quot;);
+
+function assignVarUndefinedTest2()
+{
+    function g()
+    {
+        return assignVarUndefinedTest2.arguments;
+    }
+
+    var a, arguments;
+    return g();
+}
+shouldBeUndefined(&quot;assignVarUndefinedTest2()&quot;);
+
</ins><span class="cx"> function assignVarInitTest()
</span><span class="cx"> {
</span><span class="cx">     function g()
</span><span class="lines">@@ -25,7 +48,6 @@
</span><span class="cx">     var arguments = true;
</span><span class="cx">     return g();
</span><span class="cx"> }
</span><del>-
</del><span class="cx"> shouldBeTrue(&quot;assignVarInitTest()&quot;);
</span><span class="cx"> 
</span><span class="cx"> function assignVarInitTest2()
</span><span class="lines">@@ -38,9 +60,32 @@
</span><span class="cx">     var a, arguments = true;
</span><span class="cx">     return g();
</span><span class="cx"> }
</span><del>-
</del><span class="cx"> shouldBeTrue(&quot;assignVarInitTest2()&quot;);
</span><span class="cx"> 
</span><ins>+function assignConstUndefinedTest()
+{
+    function g()
+    {
+        return assignConstUndefinedTest.arguments;
+    }
+
+    var arguments;
+    return g();
+}
+shouldBeUndefined(&quot;assignConstUndefinedTest()&quot;);
+
+function assignConstUndefinedTest2()
+{
+    function g()
+    {
+        return assignConstUndefinedTest2.arguments;
+    }
+
+    var a, arguments;
+    return g();
+}
+shouldBeUndefined(&quot;assignConstUndefinedTest2()&quot;);
+
</ins><span class="cx"> function assignConstInitTest()
</span><span class="cx"> {
</span><span class="cx">     function g()
</span><span class="lines">@@ -51,7 +96,6 @@
</span><span class="cx">     const arguments = true;
</span><span class="cx">     return g();
</span><span class="cx"> }
</span><del>-
</del><span class="cx"> shouldBeTrue(&quot;assignConstInitTest()&quot;);
</span><span class="cx"> 
</span><span class="cx"> function assignConstInitTest2()
</span><span class="lines">@@ -64,7 +108,6 @@
</span><span class="cx">     const a, arguments = true;
</span><span class="cx">     return g();
</span><span class="cx"> }
</span><del>-
</del><span class="cx"> shouldBeTrue(&quot;assignConstInitTest2()&quot;);
</span><span class="cx"> 
</span><span class="cx"> function assignForInitTest()
</span><span class="lines">@@ -77,7 +120,6 @@
</span><span class="cx">     for (var arguments = true; false;) { }
</span><span class="cx">     return g();
</span><span class="cx"> }
</span><del>-
</del><span class="cx"> shouldBeTrue(&quot;assignForInitTest()&quot;);
</span><span class="cx"> 
</span><span class="cx"> function assignForInitTest2()
</span><span class="lines">@@ -90,7 +132,6 @@
</span><span class="cx">     for (var a, arguments = true; false;) { }
</span><span class="cx">     return g();
</span><span class="cx"> }
</span><del>-
</del><span class="cx"> shouldBeTrue(&quot;assignForInitTest2()&quot;);
</span><span class="cx"> 
</span><span class="cx"> function assignForInInitTest()
</span><span class="lines">@@ -103,7 +144,6 @@
</span><span class="cx">     for (arguments = true; false;) { }
</span><span class="cx">     return g();
</span><span class="cx"> }
</span><del>-
</del><span class="cx"> shouldBeTrue(&quot;assignForInInitTest()&quot;);
</span><span class="cx"> 
</span><span class="cx"> function paramInitTest(arguments)
</span><span class="lines">@@ -115,7 +155,34 @@
</span><span class="cx"> 
</span><span class="cx">     return g();
</span><span class="cx"> }
</span><del>-
</del><span class="cx"> shouldBeTrue(&quot;paramInitTest(true)&quot;);
</span><span class="cx"> 
</span><ins>+function tearOffTest()
+{
+    function g()
+    {
+        var a = 1;
+        return arguments;
+    }
+
+    var b = 2;
+    var arguments = g(true);
+    return arguments;
+}
+shouldBeTrue(&quot;tearOffTest()[0]&quot;);
+
+function tearOffTest2()
+{
+    function g(a)
+    {
+        var arguments = a;
+        var b = 2;
+        return arguments;
+    }
+
+    var c = 3;
+    return g(arguments);
+}
+shouldBeTrue(&quot;tearOffTest2(true)[0]&quot;);
+
</ins><span class="cx"> var successfullyParsed = true;
</span></span></pre>
</div>
</div>

</body>
</html>