<!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>[127698] 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/127698">127698</a></dd>
<dt>Author</dt> <dd>ggaren@apple.com</dd>
<dt>Date</dt> <dd>2012-09-05 23:17:59 -0700 (Wed, 05 Sep 2012)</dd>
</dl>

<h3>Log Message</h3>
<pre>Named functions should not allocate scope objects for their names
https://bugs.webkit.org/show_bug.cgi?id=95659

Reviewed by Oliver Hunt.

Source/JavaScriptCore: 

In most cases, we can merge a function expression's name into its symbol
table. This reduces memory footprint per closure from three objects
(function + activation + name scope) to two (function + activation),
speeds up closure allocation, and speeds up recursive calls.

In the case of a named function expression that contains a non-strict
eval, the rules are so bat-poop crazy that I don't know how to model
them without an extra object. Since functions now default to not having
such an object, this case needs to allocate the object on function
entry.

Therefore, this patch makes the slow case a bit slower so the fast case
can be faster and more memory-efficient. (Note that the slow case already
allocates an activation on entry, and until recently also allocated a
scope chain node on entry, so adding one allocation on entry shouldn't
break the bank.)

* bytecode/CodeBlock.cpp:
(JSC::CodeBlock::CodeBlock): Caught a missed initializer. No behavior change.

* bytecompiler/BytecodeGenerator.cpp:
(JSC::BytecodeGenerator::BytecodeGenerator): Put the callee in static scope
during compilation so it doesn't need to be in dynamic scope at runtime.

(JSC::BytecodeGenerator::resolveCallee):
(JSC::BytecodeGenerator::addCallee): Helper functions for either statically
resolving the callee or adding a dynamic scope that will resolve to it,
depending on whether you're in the fast path.

We move the callee into a var location if it's captured because activations
prefer to have contiguous ranges of captured variables.

* bytecompiler/BytecodeGenerator.h:
(JSC::BytecodeGenerator::registerFor):
(BytecodeGenerator):

* dfg/DFGOperations.cpp:
* interpreter/Interpreter.cpp:
(JSC::Interpreter::privateExecute):
* jit/JITStubs.cpp:
(JSC::DEFINE_STUB_FUNCTION):
* llint/LLIntSlowPaths.cpp:
(JSC::LLInt::LLINT_SLOW_PATH_DECL): This is the point of the patch: remove
one allocation in the case of a named function expression.

* parser/Parser.cpp:
(JSC::::Parser):
* parser/Parser.h:
(JSC::Scope::declareCallee):
(Scope):
(Parser):
(JSC::parse):
* runtime/Executable.cpp:
(JSC::EvalExecutable::compileInternal):
(JSC::ProgramExecutable::checkSyntax):
(JSC::ProgramExecutable::compileInternal):
(JSC::FunctionExecutable::produceCodeBlockFor):
(JSC::FunctionExecutable::fromGlobalCode): Pipe the callee's name through
the parser so we get accurate information on whether the callee was captured.

(JSC::FunctionExecutable::FunctionExecutable):
(JSC::EvalExecutable::compileInternal):
(JSC::ProgramExecutable::checkSyntax):
(JSC::ProgramExecutable::compileInternal):
(JSC::FunctionExecutable::produceCodeBlockFor):
(JSC::FunctionExecutable::fromGlobalCode):
* runtime/Executable.h:
(JSC::FunctionExecutable::create):
(FunctionExecutable):
(JSC::FunctionExecutable::finishCreation): I had to refactor function
creation to support the following function constructor quirk: the function
gets a name, but its name is not in lexical scope.

To simplify this, FunctionExecutable now automatically extracts all the
data it needs from the parsed node. The special &quot;fromGlobalCode&quot; path
used by the function constructor creates an anonymous function, and then
quirkily sets the value used by the .name property to be non-null, even
though the parsed name is null.

* runtime/JSNameScope.h:
(JSC::JSNameScope::create):
(JSC::JSNameScope::JSNameScope): Added support for explicitly specifying
your container scope. The compiler uses this for named function expressions.

LayoutTests: 

Added coverage for some extra-tricky cases.

* fast/js/named-function-expression-expected.txt:
* fast/js/script-tests/named-function-expression.js:
(shouldBeTrueWithDescription): I rolled my own shouldBeTrue() here to avoid the
built-in shouldBe()'s eval scoping, which can change the variable
resolution rules I'm trying to test.

* inspector/debugger/debugger-expand-scope-expected.txt: Not sure why this
result used to miss the function name scope, but the new result is a
progression, so I've updated the expected results.</pre>

<h3>Modified Paths</h3>
<ul>
<li><a href="#trunkLayoutTestsChangeLog">trunk/LayoutTests/ChangeLog</a></li>
<li><a href="#trunkLayoutTestsfastjsnamedfunctionexpressionexpectedtxt">trunk/LayoutTests/fast/js/named-function-expression-expected.txt</a></li>
<li><a href="#trunkLayoutTestsfastjsscripttestsnamedfunctionexpressionjs">trunk/LayoutTests/fast/js/script-tests/named-function-expression.js</a></li>
<li><a href="#trunkLayoutTestsinspectordebuggerdebuggerexpandscopeexpectedtxt">trunk/LayoutTests/inspector/debugger/debugger-expand-scope-expected.txt</a></li>
<li><a href="#trunkSourceJavaScriptCoreChangeLog">trunk/Source/JavaScriptCore/ChangeLog</a></li>
<li><a href="#trunkSourceJavaScriptCorebytecodeCodeBlockcpp">trunk/Source/JavaScriptCore/bytecode/CodeBlock.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCorebytecompilerBytecodeGeneratorcpp">trunk/Source/JavaScriptCore/bytecompiler/BytecodeGenerator.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCorebytecompilerBytecodeGeneratorh">trunk/Source/JavaScriptCore/bytecompiler/BytecodeGenerator.h</a></li>
<li><a href="#trunkSourceJavaScriptCoredfgDFGOperationscpp">trunk/Source/JavaScriptCore/dfg/DFGOperations.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoreinterpreterInterpretercpp">trunk/Source/JavaScriptCore/interpreter/Interpreter.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCorejitJITStubscpp">trunk/Source/JavaScriptCore/jit/JITStubs.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCorellintLLIntSlowPathscpp">trunk/Source/JavaScriptCore/llint/LLIntSlowPaths.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoreparserParsercpp">trunk/Source/JavaScriptCore/parser/Parser.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoreparserParserh">trunk/Source/JavaScriptCore/parser/Parser.h</a></li>
<li><a href="#trunkSourceJavaScriptCoreruntimeExecutablecpp">trunk/Source/JavaScriptCore/runtime/Executable.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoreruntimeExecutableh">trunk/Source/JavaScriptCore/runtime/Executable.h</a></li>
<li><a href="#trunkSourceJavaScriptCoreruntimeJSNameScopeh">trunk/Source/JavaScriptCore/runtime/JSNameScope.h</a></li>
</ul>

</div>
<div id="patch">
<h3>Diff</h3>
<a id="trunkLayoutTestsChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/LayoutTests/ChangeLog (127697 => 127698)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/ChangeLog        2012-09-06 06:06:13 UTC (rev 127697)
+++ trunk/LayoutTests/ChangeLog        2012-09-06 06:17:59 UTC (rev 127698)
</span><span class="lines">@@ -1,3 +1,22 @@
</span><ins>+2012-09-03  Geoffrey Garen  &lt;ggaren@apple.com&gt;
+
+        Named functions should not allocate scope objects for their names
+        https://bugs.webkit.org/show_bug.cgi?id=95659
+
+        Reviewed by Oliver Hunt.
+
+        Added coverage for some extra-tricky cases.
+
+        * fast/js/named-function-expression-expected.txt:
+        * fast/js/script-tests/named-function-expression.js:
+        (shouldBeTrueWithDescription): I rolled my own shouldBeTrue() here to avoid the
+        built-in shouldBe()'s eval scoping, which can change the variable
+        resolution rules I'm trying to test.
+
+        * inspector/debugger/debugger-expand-scope-expected.txt: Not sure why this
+        result used to miss the function name scope, but the new result is a
+        progression, so I've updated the expected results.
+
</ins><span class="cx"> 2012-09-05  Csaba Osztrogon√°c  &lt;ossy@webkit.org&gt;
</span><span class="cx"> 
</span><span class="cx">         [Qt] Unreviewed gardening, skip new fasiling tests.
</span></span></pre></div>
<a id="trunkLayoutTestsfastjsnamedfunctionexpressionexpectedtxt"></a>
<div class="modfile"><h4>Modified: trunk/LayoutTests/fast/js/named-function-expression-expected.txt (127697 => 127698)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/fast/js/named-function-expression-expected.txt        2012-09-06 06:06:13 UTC (rev 127697)
+++ trunk/LayoutTests/fast/js/named-function-expression-expected.txt        2012-09-06 06:17:59 UTC (rev 127698)
</span><span class="lines">@@ -1,4 +1,4 @@
</span><del>-Bug 4698 - kjs does not allow named functions in function expressions.
</del><ins>+Tests variable resolution rules for named function expressions.
</ins><span class="cx"> 
</span><span class="cx"> On success, you will see a series of &quot;PASS&quot; messages, followed by &quot;TEST COMPLETE&quot;.
</span><span class="cx"> 
</span><span class="lines">@@ -17,6 +17,24 @@
</span><span class="cx"> PASS var ctr = 3; var x = (function Named(a,b){ if(--ctr) return 2 * Named(a,b); else return a + b; }); x(5,6) is 44
</span><span class="cx"> regression test where kjs regarded an anonymous function declaration (which is illegal) as a FunctionExpr
</span><span class="cx"> PASS var hadError = 0; try { eval(&quot;function(){ return 2; };&quot;); } catch(e) { hadError = 1; }; hadError; is 1
</span><ins>+
+-----
+
+PASS: (function closure() { return closure == arguments.callee &amp;&amp; !this.closure; })() should be true and is.
+PASS: (function closure() { closure = 1; return closure == arguments.callee &amp;&amp; !this.closure; })() should be true and is.
+PASS: (function closure(closure) { return closure == 1 &amp;&amp; !this.closure; })(1) should be true and is.
+PASS: (function closure() { var closure = 1; return closure == 1 &amp;&amp; !this.closure; })() should be true and is.
+PASS: (function closure() { function closure() { }; return closure != arguments.callee &amp;&amp; !this.closure; })() should be true and is.
+PASS: (function closure() { return (function() { return closure &amp;&amp; !this.closure; })(); })() should be true and is.
+PASS: (function closure() { return (function() { closure = null; return closure &amp;&amp; !this.closure; })(); })() should be true and is.
+PASS: (function closure() { return (function() { return closure &amp;&amp; !this.closure; }); })()() should be true and is.
+PASS: (function closure() { return (function() { closure = null; return closure &amp;&amp; !this.closure; }); })()() should be true and is.
+PASS: (function closure() { eval(&quot;var closure&quot;); return closure == undefined &amp;&amp; !this.closure; })() should be true and is.
+PASS: (function closure() { eval(&quot;function closure() { }&quot;); return closure != arguments.callee &amp;&amp; !this.closure; })() should be true and is.
+PASS: (function closure() { eval(&quot;var closure;&quot;); closure = 1; return closure == 1 &amp;&amp; !this.closure; })() should be true and is.
+PASS: (function closure() { eval(&quot;var closure&quot;); delete closure; return closure == arguments.callee &amp;&amp; !this.closure; })() should be true and is.
+PASS: (function closure() { eval(&quot;function closure() { }&quot;); delete closure; return closure == arguments.callee &amp;&amp; !this.closure; })() should be true and is.
+PASS: (function closure() { eval(&quot;closure = 1;&quot;); return closure == arguments.callee &amp;&amp; !this.closure; })() should be true and is.
</ins><span class="cx"> PASS successfullyParsed is true
</span><span class="cx"> 
</span><span class="cx"> TEST COMPLETE
</span></span></pre></div>
<a id="trunkLayoutTestsfastjsscripttestsnamedfunctionexpressionjs"></a>
<div class="modfile"><h4>Modified: trunk/LayoutTests/fast/js/script-tests/named-function-expression.js (127697 => 127698)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/fast/js/script-tests/named-function-expression.js        2012-09-06 06:06:13 UTC (rev 127697)
+++ trunk/LayoutTests/fast/js/script-tests/named-function-expression.js        2012-09-06 06:17:59 UTC (rev 127698)
</span><span class="lines">@@ -1,5 +1,5 @@
</span><span class="cx"> description(
</span><del>-&quot;Bug 4698 - kjs does not allow named functions in function expressions.&quot;
</del><ins>+&quot;Tests variable resolution rules for named function expressions.&quot;
</ins><span class="cx"> );
</span><span class="cx"> 
</span><span class="cx"> function Call(lambda) { return lambda(); }
</span><span class="lines">@@ -24,3 +24,105 @@
</span><span class="cx"> 
</span><span class="cx"> debug(&quot;regression test where kjs regarded an anonymous function declaration (which is illegal) as a FunctionExpr&quot;);
</span><span class="cx"> shouldBe('var hadError = 0; try { eval(&quot;function(){ return 2; };&quot;); } catch(e) { hadError = 1; }; hadError;', &quot;1&quot;);
</span><ins>+
+debug(&quot;\n-----\n&quot;);
+
+function shouldBeTrueWithDescription(x, xDescription)
+{
+        if (x) {
+                debug(&quot;PASS: &quot; + xDescription + &quot; should be true and is.&quot;);
+                return;
+        }
+
+        debug(&quot;FAIL: &quot; + xDescription + &quot; should be true but isn't.&quot;);
+}
+
+// Recursion.
+shouldBeTrueWithDescription(
+        (function closure() { return closure == arguments.callee &amp;&amp; !this.closure; })(),
+        &quot;(function closure() { return closure == arguments.callee &amp;&amp; !this.closure; })()&quot;
+);
+
+// Assignment.
+shouldBeTrueWithDescription(
+        (function closure() { closure = 1; return closure == arguments.callee &amp;&amp; !this.closure; })(),
+        &quot;(function closure() { closure = 1; return closure == arguments.callee &amp;&amp; !this.closure; })()&quot;
+);
+
+// Function name vs parameter.
+shouldBeTrueWithDescription(
+        (function closure(closure) { return closure == 1 &amp;&amp; !this.closure; })(1),
+        &quot;(function closure(closure) { return closure == 1 &amp;&amp; !this.closure; })(1)&quot;
+);
+
+// Function name vs var.
+shouldBeTrueWithDescription(
+        (function closure() { var closure = 1; return closure == 1 &amp;&amp; !this.closure; })(),
+        &quot;(function closure() { var closure = 1; return closure == 1 &amp;&amp; !this.closure; })()&quot;
+);
+
+// Function name vs declared function.
+shouldBeTrueWithDescription(
+        (function closure() { function closure() { }; return closure != arguments.callee &amp;&amp; !this.closure; })(),
+        &quot;(function closure() { function closure() { }; return closure != arguments.callee &amp;&amp; !this.closure; })()&quot;
+);
+
+// Resolve before tear-off.
+shouldBeTrueWithDescription(
+        (function closure() { return (function() { return closure &amp;&amp; !this.closure; })(); })(),
+        &quot;(function closure() { return (function() { return closure &amp;&amp; !this.closure; })(); })()&quot;
+);
+
+// Resolve assignment before tear-off.
+shouldBeTrueWithDescription(
+        (function closure() { return (function() { closure = null; return closure &amp;&amp; !this.closure; })(); })(),
+        &quot;(function closure() { return (function() { closure = null; return closure &amp;&amp; !this.closure; })(); })()&quot;
+);
+
+// Resolve after tear-off.
+shouldBeTrueWithDescription(
+        (function closure() { return (function() { return closure &amp;&amp; !this.closure; }); })()(),
+        &quot;(function closure() { return (function() { return closure &amp;&amp; !this.closure; }); })()()&quot;
+);
+
+// Resolve assignment after tear-off.
+shouldBeTrueWithDescription(
+        (function closure() { return (function() { closure = null; return closure &amp;&amp; !this.closure; }); })()(),
+        &quot;(function closure() { return (function() { closure = null; return closure &amp;&amp; !this.closure; }); })()()&quot;
+);
+
+// Eval var shadowing (should overwrite).
+shouldBeTrueWithDescription(
+        (function closure() { eval(&quot;var closure&quot;); return closure == undefined &amp;&amp; !this.closure; })(),
+        &quot;(function closure() { eval(\&quot;var closure\&quot;); return closure == undefined &amp;&amp; !this.closure; })()&quot;
+);
+
+// Eval function shadowing (should overwrite).
+shouldBeTrueWithDescription(
+        (function closure() { eval(&quot;function closure() { }&quot;); return closure != arguments.callee &amp;&amp; !this.closure; })(),
+        &quot;(function closure() { eval(\&quot;function closure() { }\&quot;); return closure != arguments.callee &amp;&amp; !this.closure; })()&quot;
+);
+
+// Eval shadowing (should overwrite), followed by put (should overwrite).
+shouldBeTrueWithDescription(
+        (function closure() { eval(&quot;var closure;&quot;); closure = 1; return closure == 1 &amp;&amp; !this.closure; })(),
+        &quot;(function closure() { eval(\&quot;var closure;\&quot;); closure = 1; return closure == 1 &amp;&amp; !this.closure; })()&quot;
+);
+
+// Eval var shadowing, followed by delete (should not overwrite).
+shouldBeTrueWithDescription(
+        (function closure() { eval(&quot;var closure&quot;); delete closure; return closure == arguments.callee &amp;&amp; !this.closure; })(),
+        &quot;(function closure() { eval(\&quot;var closure\&quot;); delete closure; return closure == arguments.callee &amp;&amp; !this.closure; })()&quot;
+);
+
+// Eval function shadowing, followed by delete (should not overwrite).
+shouldBeTrueWithDescription(
+        (function closure() { eval(&quot;function closure() { }&quot;); delete closure; return closure == arguments.callee &amp;&amp; !this.closure; })(),
+        &quot;(function closure() { eval(\&quot;function closure() { }\&quot;); delete closure; return closure == arguments.callee &amp;&amp; !this.closure; })()&quot;
+);
+
+// Eval assignment (should not overwrite).
+shouldBeTrueWithDescription(
+        (function closure() { eval(&quot;closure = 1;&quot;); return closure == arguments.callee &amp;&amp; !this.closure; })(),
+        &quot;(function closure() { eval(\&quot;closure = 1;\&quot;); return closure == arguments.callee &amp;&amp; !this.closure; })()&quot;
+);
</ins></span></pre></div>
<a id="trunkLayoutTestsinspectordebuggerdebuggerexpandscopeexpectedtxt"></a>
<div class="modfile"><h4>Modified: trunk/LayoutTests/inspector/debugger/debugger-expand-scope-expected.txt (127697 => 127698)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/inspector/debugger/debugger-expand-scope-expected.txt        2012-09-06 06:06:13 UTC (rev 127697)
+++ trunk/LayoutTests/inspector/debugger/debugger-expand-scope-expected.txt        2012-09-06 06:17:59 UTC (rev 127698)
</span><span class="lines">@@ -19,6 +19,8 @@
</span><span class="cx">     arguments: Arguments[1]
</span><span class="cx">     makeClosureLocalVar: &quot;local.TextParam&quot;
</span><span class="cx">     n: &quot;TextParam&quot;
</span><ins>+WindowWith Block
+    makeClosure: function makeClosure(n) {
</ins><span class="cx"> WindowGlobal
</span><span class="cx">     &lt;section collapsed&gt;
</span><span class="cx"> Script execution resumed.
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/ChangeLog (127697 => 127698)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/ChangeLog        2012-09-06 06:06:13 UTC (rev 127697)
+++ trunk/Source/JavaScriptCore/ChangeLog        2012-09-06 06:17:59 UTC (rev 127698)
</span><span class="lines">@@ -1,3 +1,94 @@
</span><ins>+2012-09-05  Geoffrey Garen  &lt;ggaren@apple.com&gt;
+
+        Named functions should not allocate scope objects for their names
+        https://bugs.webkit.org/show_bug.cgi?id=95659
+
+        Reviewed by Oliver Hunt.
+
+        In most cases, we can merge a function expression's name into its symbol
+        table. This reduces memory footprint per closure from three objects
+        (function + activation + name scope) to two (function + activation),
+        speeds up closure allocation, and speeds up recursive calls.
+
+        In the case of a named function expression that contains a non-strict
+        eval, the rules are so bat-poop crazy that I don't know how to model
+        them without an extra object. Since functions now default to not having
+        such an object, this case needs to allocate the object on function
+        entry.
+
+        Therefore, this patch makes the slow case a bit slower so the fast case
+        can be faster and more memory-efficient. (Note that the slow case already
+        allocates an activation on entry, and until recently also allocated a
+        scope chain node on entry, so adding one allocation on entry shouldn't
+        break the bank.)
+
+        * bytecode/CodeBlock.cpp:
+        (JSC::CodeBlock::CodeBlock): Caught a missed initializer. No behavior change.
+
+        * bytecompiler/BytecodeGenerator.cpp:
+        (JSC::BytecodeGenerator::BytecodeGenerator): Put the callee in static scope
+        during compilation so it doesn't need to be in dynamic scope at runtime.
+
+        (JSC::BytecodeGenerator::resolveCallee):
+        (JSC::BytecodeGenerator::addCallee): Helper functions for either statically
+        resolving the callee or adding a dynamic scope that will resolve to it,
+        depending on whether you're in the fast path.
+
+        We move the callee into a var location if it's captured because activations
+        prefer to have contiguous ranges of captured variables.
+
+        * bytecompiler/BytecodeGenerator.h:
+        (JSC::BytecodeGenerator::registerFor):
+        (BytecodeGenerator):
+
+        * dfg/DFGOperations.cpp:
+        * interpreter/Interpreter.cpp:
+        (JSC::Interpreter::privateExecute):
+        * jit/JITStubs.cpp:
+        (JSC::DEFINE_STUB_FUNCTION):
+        * llint/LLIntSlowPaths.cpp:
+        (JSC::LLInt::LLINT_SLOW_PATH_DECL): This is the point of the patch: remove
+        one allocation in the case of a named function expression.
+
+        * parser/Parser.cpp:
+        (JSC::::Parser):
+        * parser/Parser.h:
+        (JSC::Scope::declareCallee):
+        (Scope):
+        (Parser):
+        (JSC::parse):
+        * runtime/Executable.cpp:
+        (JSC::EvalExecutable::compileInternal):
+        (JSC::ProgramExecutable::checkSyntax):
+        (JSC::ProgramExecutable::compileInternal):
+        (JSC::FunctionExecutable::produceCodeBlockFor):
+        (JSC::FunctionExecutable::fromGlobalCode): Pipe the callee's name through
+        the parser so we get accurate information on whether the callee was captured.
+
+        (JSC::FunctionExecutable::FunctionExecutable):
+        (JSC::EvalExecutable::compileInternal):
+        (JSC::ProgramExecutable::checkSyntax):
+        (JSC::ProgramExecutable::compileInternal):
+        (JSC::FunctionExecutable::produceCodeBlockFor):
+        (JSC::FunctionExecutable::fromGlobalCode):
+        * runtime/Executable.h:
+        (JSC::FunctionExecutable::create):
+        (FunctionExecutable):
+        (JSC::FunctionExecutable::finishCreation): I had to refactor function
+        creation to support the following function constructor quirk: the function
+        gets a name, but its name is not in lexical scope.
+
+        To simplify this, FunctionExecutable now automatically extracts all the
+        data it needs from the parsed node. The special &quot;fromGlobalCode&quot; path
+        used by the function constructor creates an anonymous function, and then
+        quirkily sets the value used by the .name property to be non-null, even
+        though the parsed name is null.
+
+        * runtime/JSNameScope.h:
+        (JSC::JSNameScope::create):
+        (JSC::JSNameScope::JSNameScope): Added support for explicitly specifying
+        your container scope. The compiler uses this for named function expressions.
+
</ins><span class="cx"> 2012-09-05  Gavin Barraclough  &lt;barraclough@apple.com&gt;
</span><span class="cx"> 
</span><span class="cx">         a = data[a]++; sets the wrong key in data
</span></span></pre></div>
<a id="trunkSourceJavaScriptCorebytecodeCodeBlockcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/bytecode/CodeBlock.cpp (127697 => 127698)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/bytecode/CodeBlock.cpp        2012-09-06 06:06:13 UTC (rev 127697)
+++ trunk/Source/JavaScriptCore/bytecode/CodeBlock.cpp        2012-09-06 06:17:59 UTC (rev 127698)
</span><span class="lines">@@ -1752,6 +1752,7 @@
</span><span class="cx">     , m_heap(&amp;m_globalObject-&gt;globalData().heap)
</span><span class="cx">     , m_numCalleeRegisters(0)
</span><span class="cx">     , m_numVars(0)
</span><ins>+    , m_numCapturedVars(0)
</ins><span class="cx">     , m_isConstructor(isConstructor)
</span><span class="cx">     , m_numParameters(0)
</span><span class="cx">     , m_ownerExecutable(globalObject-&gt;globalData(), ownerExecutable, ownerExecutable)
</span></span></pre></div>
<a id="trunkSourceJavaScriptCorebytecompilerBytecodeGeneratorcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/bytecompiler/BytecodeGenerator.cpp (127697 => 127698)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/bytecompiler/BytecodeGenerator.cpp        2012-09-06 06:06:13 UTC (rev 127697)
+++ trunk/Source/JavaScriptCore/bytecompiler/BytecodeGenerator.cpp        2012-09-06 06:17:59 UTC (rev 127698)
</span><span class="lines">@@ -33,11 +33,11 @@
</span><span class="cx"> 
</span><span class="cx"> #include &quot;BatchedTransitionOptimizer.h&quot;
</span><span class="cx"> #include &quot;Comment.h&quot;
</span><ins>+#include &quot;Interpreter.h&quot;
</ins><span class="cx"> #include &quot;JSActivation.h&quot;
</span><span class="cx"> #include &quot;JSFunction.h&quot;
</span><del>-#include &quot;Interpreter.h&quot;
</del><ins>+#include &quot;JSNameScope.h&quot;
</ins><span class="cx"> #include &quot;LowLevelInterpreter.h&quot;
</span><del>-
</del><span class="cx"> #include &quot;StrongInlines.h&quot;
</span><span class="cx"> #include &lt;wtf/text/WTFString.h&gt;
</span><span class="cx"> 
</span><span class="lines">@@ -324,7 +324,7 @@
</span><span class="cx">         bool propertyDidExist = 
</span><span class="cx">             globalObject-&gt;removeDirect(*m_globalData, function-&gt;ident()); // Newly declared functions overwrite existing properties.
</span><span class="cx">         
</span><del>-        JSValue value = JSFunction::create(exec, makeFunction(exec, function), scope);
</del><ins>+        JSValue value = JSFunction::create(exec, FunctionExecutable::create(*m_globalData, function), scope);
</ins><span class="cx">         int index = addGlobalVar(
</span><span class="cx">             function-&gt;ident(), IsVariable,
</span><span class="cx">             !propertyDidExist ? IsFunctionToSpecialize : NotFunctionOrNotSpecializable);
</span><span class="lines">@@ -419,6 +419,8 @@
</span><span class="cx">         }
</span><span class="cx">     }
</span><span class="cx"> 
</span><ins>+    RegisterID* calleeRegister = resolveCallee(functionBody); // May push to the scope chain and/or add a captured var.
+
</ins><span class="cx">     const DeclarationStacks::FunctionStack&amp; functionStack = functionBody-&gt;functionStack();
</span><span class="cx">     const DeclarationStacks::VarStack&amp; varStack = functionBody-&gt;varStack();
</span><span class="cx"> 
</span><span class="lines">@@ -456,6 +458,7 @@
</span><span class="cx">     }
</span><span class="cx"> 
</span><span class="cx">     codeBlock-&gt;m_numCapturedVars = codeBlock-&gt;m_numVars;
</span><ins>+
</ins><span class="cx">     m_firstLazyFunction = codeBlock-&gt;m_numVars;
</span><span class="cx">     for (size_t i = 0; i &lt; functionStack.size(); ++i) {
</span><span class="cx">         FunctionBodyNode* function = functionStack[i];
</span><span class="lines">@@ -497,6 +500,9 @@
</span><span class="cx"> 
</span><span class="cx">     preserveLastVar();
</span><span class="cx"> 
</span><ins>+    // We declare the callee's name last because it should lose to a var, function, and/or parameter declaration.
+    addCallee(functionBody, calleeRegister);
+
</ins><span class="cx">     if (isConstructor()) {
</span><span class="cx">         prependComment(&quot;'this' because we are a Constructor function&quot;);
</span><span class="cx">         emitOpcode(op_create_this);
</span><span class="lines">@@ -549,7 +555,7 @@
</span><span class="cx"> 
</span><span class="cx">     const DeclarationStacks::FunctionStack&amp; functionStack = evalNode-&gt;functionStack();
</span><span class="cx">     for (size_t i = 0; i &lt; functionStack.size(); ++i)
</span><del>-        m_codeBlock-&gt;addFunctionDecl(makeFunction(m_globalData, functionStack[i]));
</del><ins>+        m_codeBlock-&gt;addFunctionDecl(FunctionExecutable::create(*m_globalData, functionStack[i]));
</ins><span class="cx"> 
</span><span class="cx">     const DeclarationStacks::VarStack&amp; varStack = evalNode-&gt;varStack();
</span><span class="cx">     unsigned numVariables = varStack.size();
</span><span class="lines">@@ -574,6 +580,53 @@
</span><span class="cx">     return reg;
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+RegisterID* BytecodeGenerator::resolveCallee(FunctionBodyNode* functionBodyNode)
+{
+    if (functionBodyNode-&gt;ident().isNull())
+        return 0;
+
+    m_calleeRegister.setIndex(RegisterFile::Callee);
+
+    // If non-strict eval is in play, we use a separate object in the scope chain for the callee's name.
+    if ((m_codeBlock-&gt;usesEval() &amp;&amp; !m_codeBlock-&gt;isStrictMode()) || m_shouldEmitDebugHooks) {
+        emitOpcode(op_push_name_scope);
+        instructions().append(addConstant(functionBodyNode-&gt;ident()));
+        instructions().append(m_calleeRegister.index());
+        instructions().append(ReadOnly | DontDelete);
+
+        // Put a mirror object in compilation scope, so compile-time variable resolution sees the property name we'll see at runtime.
+        m_scope.set(*globalData(),
+            JSNameScope::create(
+                m_scope-&gt;globalObject()-&gt;globalExec(),
+                functionBodyNode-&gt;ident(),
+                jsUndefined(),
+                ReadOnly | DontDelete,
+                m_scope.get()
+            )
+        );
+        return 0;
+    }
+
+    if (!functionBodyNode-&gt;captures(functionBodyNode-&gt;ident()))
+        return &amp;m_calleeRegister;
+
+    // Move the callee into the captured section of the stack.
+    return emitMove(addVar(), &amp;m_calleeRegister);
+}
+
+void BytecodeGenerator::addCallee(FunctionBodyNode* functionBodyNode, RegisterID* calleeRegister)
+{
+    if (functionBodyNode-&gt;ident().isNull())
+        return;
+
+    // If non-strict eval is in play, we use a separate object in the scope chain for the callee's name.
+    if ((m_codeBlock-&gt;usesEval() &amp;&amp; !m_codeBlock-&gt;isStrictMode()) || m_shouldEmitDebugHooks)
+        return;
+
+    ASSERT(calleeRegister);
+    symbolTable().add(functionBodyNode-&gt;ident().impl(), SymbolTableEntry(calleeRegister-&gt;index(), ReadOnly));
+}
+
</ins><span class="cx"> void BytecodeGenerator::addParameter(const Identifier&amp; ident, int parameterIndex)
</span><span class="cx"> {
</span><span class="cx">     // Parameters overwrite var declarations, but not function declarations.
</span><span class="lines">@@ -1830,14 +1883,14 @@
</span><span class="cx"> 
</span><span class="cx"> RegisterID* BytecodeGenerator::emitNewFunction(RegisterID* dst, FunctionBodyNode* function)
</span><span class="cx"> {
</span><del>-    return emitNewFunctionInternal(dst, m_codeBlock-&gt;addFunctionDecl(makeFunction(m_globalData, function)), false);
</del><ins>+    return emitNewFunctionInternal(dst, m_codeBlock-&gt;addFunctionDecl(FunctionExecutable::create(*m_globalData, function)), false);
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> RegisterID* BytecodeGenerator::emitLazyNewFunction(RegisterID* dst, FunctionBodyNode* function)
</span><span class="cx"> {
</span><span class="cx">     FunctionOffsetMap::AddResult ptr = m_functionOffsets.add(function, 0);
</span><span class="cx">     if (ptr.isNewEntry)
</span><del>-        ptr.iterator-&gt;second = m_codeBlock-&gt;addFunctionDecl(makeFunction(m_globalData, function));
</del><ins>+        ptr.iterator-&gt;second = m_codeBlock-&gt;addFunctionDecl(FunctionExecutable::create(*m_globalData, function));
</ins><span class="cx">     return emitNewFunctionInternal(dst, ptr.iterator-&gt;second, true);
</span><span class="cx"> }
</span><span class="cx"> 
</span><span class="lines">@@ -1862,7 +1915,7 @@
</span><span class="cx"> RegisterID* BytecodeGenerator::emitNewFunctionExpression(RegisterID* r0, FuncExprNode* n)
</span><span class="cx"> {
</span><span class="cx">     FunctionBodyNode* function = n-&gt;body();
</span><del>-    unsigned index = m_codeBlock-&gt;addFunctionExpr(makeFunction(m_globalData, function));
</del><ins>+    unsigned index = m_codeBlock-&gt;addFunctionExpr(FunctionExecutable::create(*m_globalData, function));
</ins><span class="cx">     
</span><span class="cx">     createActivationIfNecessary();
</span><span class="cx">     emitOpcode(op_new_func_exp);
</span><span class="lines">@@ -2599,7 +2652,7 @@
</span><span class="cx">     if (!isStrictMode())
</span><span class="cx">         return;
</span><span class="cx"> 
</span><del>-    RefPtr&lt;RegisterID&gt; error = emitLoad(newTemporary(), createTypeError(scope()-&gt;globalObject()-&gt;globalExec(), StrictModeReadonlyPropertyWriteError));
</del><ins>+    RefPtr&lt;RegisterID&gt; error = emitLoad(newTemporary(), JSValue(createTypeError(scope()-&gt;globalObject()-&gt;globalExec(), StrictModeReadonlyPropertyWriteError)));
</ins><span class="cx">     emitThrow(error.get());
</span><span class="cx"> }
</span><span class="cx"> 
</span></span></pre></div>
<a id="trunkSourceJavaScriptCorebytecompilerBytecodeGeneratorh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/bytecompiler/BytecodeGenerator.h (127697 => 127698)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/bytecompiler/BytecodeGenerator.h        2012-09-06 06:06:13 UTC (rev 127697)
+++ trunk/Source/JavaScriptCore/bytecompiler/BytecodeGenerator.h        2012-09-06 06:17:59 UTC (rev 127698)
</span><span class="lines">@@ -617,7 +617,9 @@
</span><span class="cx">         int addGlobalVar(const Identifier&amp;, ConstantMode, FunctionMode);
</span><span class="cx"> 
</span><span class="cx">         void addParameter(const Identifier&amp;, int parameterIndex);
</span><del>-        
</del><ins>+        RegisterID* resolveCallee(FunctionBodyNode*);
+        void addCallee(FunctionBodyNode*, RegisterID*);
+
</ins><span class="cx">         void preserveLastVar();
</span><span class="cx">         bool shouldAvoidResolveGlobal();
</span><span class="cx"> 
</span><span class="lines">@@ -626,6 +628,9 @@
</span><span class="cx">             if (index &gt;= 0)
</span><span class="cx">                 return m_calleeRegisters[index];
</span><span class="cx"> 
</span><ins>+            if (index == RegisterFile::Callee)
+                return m_calleeRegister;
+
</ins><span class="cx">             ASSERT(m_parameters.size());
</span><span class="cx">             return m_parameters[index + m_parameters.size() + RegisterFile::CallFrameHeaderSize];
</span><span class="cx">         }
</span><span class="lines">@@ -636,16 +641,6 @@
</span><span class="cx"> 
</span><span class="cx">         unsigned addConstantBuffer(unsigned length);
</span><span class="cx">         
</span><del>-        FunctionExecutable* makeFunction(ExecState* exec, FunctionBodyNode* body)
-        {
-            return FunctionExecutable::create(exec, body-&gt;ident(), body-&gt;inferredName(), body-&gt;source(), body-&gt;usesArguments(), body-&gt;parameters(), body-&gt;isStrictMode(), body-&gt;lineNo(), body-&gt;lastLine());
-        }
-
-        FunctionExecutable* makeFunction(JSGlobalData* globalData, FunctionBodyNode* body)
-        {
-            return FunctionExecutable::create(*globalData, body-&gt;ident(), body-&gt;inferredName(), body-&gt;source(), body-&gt;usesArguments(), body-&gt;parameters(), body-&gt;isStrictMode(), body-&gt;lineNo(), body-&gt;lastLine());
-        }
-
</del><span class="cx">         JSString* addStringConstant(const Identifier&amp;);
</span><span class="cx"> 
</span><span class="cx">         void addLineInfo(unsigned lineNo)
</span><span class="lines">@@ -716,6 +711,7 @@
</span><span class="cx">         HashSet&lt;RefPtr&lt;StringImpl&gt;, IdentifierRepHash&gt; m_functions;
</span><span class="cx">         RegisterID m_ignoredResultRegister;
</span><span class="cx">         RegisterID m_thisRegister;
</span><ins>+        RegisterID m_calleeRegister;
</ins><span class="cx">         RegisterID* m_activationRegister;
</span><span class="cx">         SegmentedVector&lt;RegisterID, 32&gt; m_constantPoolRegisters;
</span><span class="cx">         SegmentedVector&lt;RegisterID, 32&gt; m_calleeRegisters;
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoredfgDFGOperationscpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/dfg/DFGOperations.cpp (127697 => 127698)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/dfg/DFGOperations.cpp        2012-09-06 06:06:13 UTC (rev 127697)
+++ trunk/Source/JavaScriptCore/dfg/DFGOperations.cpp        2012-09-06 06:17:59 UTC (rev 127698)
</span><span class="lines">@@ -1243,7 +1243,7 @@
</span><span class="cx">     ASSERT(functionExecutable-&gt;inherits(&amp;FunctionExecutable::s_info));
</span><span class="cx">     JSGlobalData&amp; globalData = exec-&gt;globalData();
</span><span class="cx">     NativeCallFrameTracer tracer(&amp;globalData, exec);
</span><del>-    return static_cast&lt;FunctionExecutable*&gt;(functionExecutable)-&gt;make(exec, exec-&gt;scope());
</del><ins>+    return JSFunction::create(exec, static_cast&lt;FunctionExecutable*&gt;(functionExecutable), exec-&gt;scope());
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> JSCell* DFG_OPERATION operationNewFunctionExpression(ExecState* exec, JSCell* functionExecutableAsCell)
</span><span class="lines">@@ -1251,14 +1251,7 @@
</span><span class="cx">     ASSERT(functionExecutableAsCell-&gt;inherits(&amp;FunctionExecutable::s_info));
</span><span class="cx">     FunctionExecutable* functionExecutable =
</span><span class="cx">         static_cast&lt;FunctionExecutable*&gt;(functionExecutableAsCell);
</span><del>-    JSFunction* function = functionExecutable-&gt;make(exec, exec-&gt;scope());
-    if (!functionExecutable-&gt;name().isNull()) {
-        JSNameScope* functionScopeObject =
-            JSNameScope::create(
-                exec, functionExecutable-&gt;name(), function, ReadOnly | DontDelete);
-        function-&gt;setScope(exec-&gt;globalData(), functionScopeObject);
-    }
-    return function;
</del><ins>+    return JSFunction::create(exec, functionExecutable, exec-&gt;scope());
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> size_t DFG_OPERATION operationIsObject(ExecState* exec, EncodedJSValue value)
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreinterpreterInterpretercpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/interpreter/Interpreter.cpp (127697 => 127698)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/interpreter/Interpreter.cpp        2012-09-06 06:06:13 UTC (rev 127697)
+++ trunk/Source/JavaScriptCore/interpreter/Interpreter.cpp        2012-09-06 06:17:59 UTC (rev 127698)
</span><span class="lines">@@ -1347,7 +1347,7 @@
</span><span class="cx">         for (int i = 0; i &lt; numFunctions; ++i) {
</span><span class="cx">             FunctionExecutable* function = codeBlock-&gt;functionDecl(i);
</span><span class="cx">             PutPropertySlot slot;
</span><del>-            variableObject-&gt;methodTable()-&gt;put(variableObject, callFrame, function-&gt;name(), function-&gt;make(callFrame, scope), slot);
</del><ins>+            variableObject-&gt;methodTable()-&gt;put(variableObject, callFrame, function-&gt;name(), JSFunction::create(callFrame, function, scope), slot);
</ins><span class="cx">         }
</span><span class="cx">     }
</span><span class="cx"> 
</span><span class="lines">@@ -4279,18 +4279,6 @@
</span><span class="cx">         FunctionExecutable* function = codeBlock-&gt;functionExpr(funcIndex);
</span><span class="cx">         JSFunction* func = function-&gt;make(callFrame, callFrame-&gt;scope());
</span><span class="cx"> 
</span><del>-        /* 
-            The Identifier in a FunctionExpression can be referenced from inside
-            the FunctionExpression's FunctionBody to allow the function to call
-            itself recursively. However, unlike in a FunctionDeclaration, the
-            Identifier in a FunctionExpression cannot be referenced from and
-            does not affect the scope enclosing the FunctionExpression.
-         */
-        if (!function-&gt;name().isNull()) {
-            JSNameScope* functionScopeObject = JSNameScope::create(callFrame, function-&gt;name(), func, ReadOnly | DontDelete);
-            func-&gt;setScope(*globalData, functionScopeObject);
-        }
-
</del><span class="cx">         callFrame-&gt;uncheckedR(dst) = JSValue(func);
</span><span class="cx"> 
</span><span class="cx">         vPC += OPCODE_LENGTH(op_new_func_exp);
</span></span></pre></div>
<a id="trunkSourceJavaScriptCorejitJITStubscpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/jit/JITStubs.cpp (127697 => 127698)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/jit/JITStubs.cpp        2012-09-06 06:06:13 UTC (rev 127697)
+++ trunk/Source/JavaScriptCore/jit/JITStubs.cpp        2012-09-06 06:17:59 UTC (rev 127698)
</span><span class="lines">@@ -2141,7 +2141,7 @@
</span><span class="cx">     STUB_INIT_STACK_FRAME(stackFrame);
</span><span class="cx">     
</span><span class="cx">     ASSERT(stackFrame.callFrame-&gt;codeBlock()-&gt;codeType() != FunctionCode || !stackFrame.callFrame-&gt;codeBlock()-&gt;needsFullScopeChain() || stackFrame.callFrame-&gt;uncheckedR(stackFrame.callFrame-&gt;codeBlock()-&gt;activationRegister()).jsValue());
</span><del>-    return stackFrame.args[0].function()-&gt;make(stackFrame.callFrame, stackFrame.callFrame-&gt;scope());
</del><ins>+    return JSFunction::create(stackFrame.callFrame, stackFrame.args[0].function(), stackFrame.callFrame-&gt;scope());
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> inline void* jitCompileFor(CallFrame* callFrame, CodeSpecializationKind kind)
</span><span class="lines">@@ -2982,21 +2982,9 @@
</span><span class="cx">     CallFrame* callFrame = stackFrame.callFrame;
</span><span class="cx"> 
</span><span class="cx">     FunctionExecutable* function = stackFrame.args[0].function();
</span><del>-    JSFunction* func = function-&gt;make(callFrame, callFrame-&gt;scope());
</del><ins>+    JSFunction* func = JSFunction::create(callFrame, function, callFrame-&gt;scope());
</ins><span class="cx">     ASSERT(callFrame-&gt;codeBlock()-&gt;codeType() != FunctionCode || !callFrame-&gt;codeBlock()-&gt;needsFullScopeChain() || callFrame-&gt;uncheckedR(callFrame-&gt;codeBlock()-&gt;activationRegister()).jsValue());
</span><span class="cx"> 
</span><del>-    /* 
-        The Identifier in a FunctionExpression can be referenced from inside
-        the FunctionExpression's FunctionBody to allow the function to call
-        itself recursively. However, unlike in a FunctionDeclaration, the
-        Identifier in a FunctionExpression cannot be referenced from and
-        does not affect the scope enclosing the FunctionExpression.
-     */
-    if (!function-&gt;name().isNull()) {
-        JSNameScope* functionScopeObject = JSNameScope::create(callFrame, function-&gt;name(), func, ReadOnly | DontDelete);
-        func-&gt;setScope(callFrame-&gt;globalData(), functionScopeObject);
-    }
-
</del><span class="cx">     return func;
</span><span class="cx"> }
</span><span class="cx"> 
</span></span></pre></div>
<a id="trunkSourceJavaScriptCorellintLLIntSlowPathscpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/llint/LLIntSlowPaths.cpp (127697 => 127698)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/llint/LLIntSlowPaths.cpp        2012-09-06 06:06:13 UTC (rev 127697)
+++ trunk/Source/JavaScriptCore/llint/LLIntSlowPaths.cpp        2012-09-06 06:17:59 UTC (rev 127698)
</span><span class="lines">@@ -1260,7 +1260,7 @@
</span><span class="cx"> #if LLINT_SLOW_PATH_TRACING
</span><span class="cx">     dataLog(&quot;Creating function!\n&quot;);
</span><span class="cx"> #endif
</span><del>-    LLINT_RETURN(codeBlock-&gt;functionDecl(pc[2].u.operand)-&gt;make(exec, exec-&gt;scope()));
</del><ins>+    LLINT_RETURN(JSFunction::create(exec, codeBlock-&gt;functionDecl(pc[2].u.operand), exec-&gt;scope()));
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> LLINT_SLOW_PATH_DECL(slow_path_new_func_exp)
</span><span class="lines">@@ -1268,13 +1268,8 @@
</span><span class="cx">     LLINT_BEGIN();
</span><span class="cx">     CodeBlock* codeBlock = exec-&gt;codeBlock();
</span><span class="cx">     FunctionExecutable* function = codeBlock-&gt;functionExpr(pc[2].u.operand);
</span><del>-    JSFunction* func = function-&gt;make(exec, exec-&gt;scope());
</del><ins>+    JSFunction* func = JSFunction::create(exec, function, exec-&gt;scope());
</ins><span class="cx">     
</span><del>-    if (!function-&gt;name().isNull()) {
-        JSNameScope* functionScopeObject = JSNameScope::create(exec, function-&gt;name(), func, ReadOnly | DontDelete);
-        func-&gt;setScope(globalData, functionScopeObject);
-    }
-    
</del><span class="cx">     LLINT_RETURN(func);
</span><span class="cx"> }
</span><span class="cx"> 
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreparserParsercpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/parser/Parser.cpp (127697 => 127698)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/parser/Parser.cpp        2012-09-06 06:06:13 UTC (rev 127697)
+++ trunk/Source/JavaScriptCore/parser/Parser.cpp        2012-09-06 06:17:59 UTC (rev 127698)
</span><span class="lines">@@ -40,7 +40,7 @@
</span><span class="cx"> namespace JSC {
</span><span class="cx"> 
</span><span class="cx"> template &lt;typename LexerType&gt;
</span><del>-Parser&lt;LexerType&gt;::Parser(JSGlobalData* globalData, const SourceCode&amp; source, FunctionParameters* parameters, JSParserStrictness strictness, JSParserMode parserMode)
</del><ins>+Parser&lt;LexerType&gt;::Parser(JSGlobalData* globalData, const SourceCode&amp; source, FunctionParameters* parameters, const Identifier&amp; name, JSParserStrictness strictness, JSParserMode parserMode)
</ins><span class="cx">     : m_globalData(globalData)
</span><span class="cx">     , m_source(&amp;source)
</span><span class="cx">     , m_stack(wtfThreadData().stack())
</span><span class="lines">@@ -71,6 +71,8 @@
</span><span class="cx">         for (unsigned i = 0; i &lt; parameters-&gt;size(); i++)
</span><span class="cx">             scope-&gt;declareParameter(&amp;parameters-&gt;at(i));
</span><span class="cx">     }
</span><ins>+    if (!name.isNull())
+        scope-&gt;declareCallee(&amp;name);
</ins><span class="cx">     next();
</span><span class="cx">     m_lexer-&gt;setLastLineNumber(tokenLine());
</span><span class="cx"> }
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreparserParserh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/parser/Parser.h (127697 => 127698)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/parser/Parser.h        2012-09-06 06:06:13 UTC (rev 127697)
+++ trunk/Source/JavaScriptCore/parser/Parser.h        2012-09-06 06:17:59 UTC (rev 127698)
</span><span class="lines">@@ -208,6 +208,11 @@
</span><span class="cx">     bool isFunction() { return m_isFunction; }
</span><span class="cx">     bool isFunctionBoundary() { return m_isFunctionBoundary; }
</span><span class="cx"> 
</span><ins>+    void declareCallee(const Identifier* ident)
+    {
+        m_declaredVariables.add(ident-&gt;ustring().impl());
+    }
+
</ins><span class="cx">     bool declareVariable(const Identifier* ident)
</span><span class="cx">     {
</span><span class="cx">         bool isValidStrictMode = m_globalData-&gt;propertyNames-&gt;eval != *ident &amp;&amp; m_globalData-&gt;propertyNames-&gt;arguments != *ident;
</span><span class="lines">@@ -382,7 +387,7 @@
</span><span class="cx">     WTF_MAKE_FAST_ALLOCATED;
</span><span class="cx"> 
</span><span class="cx"> public:
</span><del>-    Parser(JSGlobalData*, const SourceCode&amp;, FunctionParameters*, JSParserStrictness, JSParserMode);
</del><ins>+    Parser(JSGlobalData*, const SourceCode&amp;, FunctionParameters*, const Identifier&amp;, JSParserStrictness, JSParserMode);
</ins><span class="cx">     ~Parser();
</span><span class="cx"> 
</span><span class="cx">     template &lt;class ParsedNode&gt;
</span><span class="lines">@@ -1020,17 +1025,17 @@
</span><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> template &lt;class ParsedNode&gt;
</span><del>-PassRefPtr&lt;ParsedNode&gt; parse(JSGlobalData* globalData, JSGlobalObject* lexicalGlobalObject, const SourceCode&amp; source, FunctionParameters* parameters, JSParserStrictness strictness, JSParserMode parserMode, Debugger* debugger, ExecState* execState, JSObject** exception)
</del><ins>+PassRefPtr&lt;ParsedNode&gt; parse(JSGlobalData* globalData, JSGlobalObject* lexicalGlobalObject, const SourceCode&amp; source, FunctionParameters* parameters, const Identifier&amp; name, JSParserStrictness strictness, JSParserMode parserMode, Debugger* debugger, ExecState* execState, JSObject** exception)
</ins><span class="cx"> {
</span><span class="cx">     SamplingRegion samplingRegion(&quot;Parsing&quot;);
</span><span class="cx"> 
</span><span class="cx">     ASSERT(source.provider()-&gt;data());
</span><span class="cx"> 
</span><span class="cx">     if (source.provider()-&gt;data()-&gt;is8Bit()) {
</span><del>-        Parser&lt; Lexer&lt;LChar&gt; &gt; parser(globalData, source, parameters, strictness, parserMode);
</del><ins>+        Parser&lt; Lexer&lt;LChar&gt; &gt; parser(globalData, source, parameters, name, strictness, parserMode);
</ins><span class="cx">         return parser.parse&lt;ParsedNode&gt;(lexicalGlobalObject, debugger, execState, exception);
</span><span class="cx">     }
</span><del>-    Parser&lt; Lexer&lt;UChar&gt; &gt; parser(globalData, source, parameters, strictness, parserMode);
</del><ins>+    Parser&lt; Lexer&lt;UChar&gt; &gt; parser(globalData, source, parameters, name, strictness, parserMode);
</ins><span class="cx">     return parser.parse&lt;ParsedNode&gt;(lexicalGlobalObject, debugger, execState, exception);
</span><span class="cx"> }
</span><span class="cx"> 
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreruntimeExecutablecpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/runtime/Executable.cpp (127697 => 127698)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/runtime/Executable.cpp        2012-09-06 06:06:13 UTC (rev 127697)
+++ trunk/Source/JavaScriptCore/runtime/Executable.cpp        2012-09-06 06:17:59 UTC (rev 127698)
</span><span class="lines">@@ -133,26 +133,18 @@
</span><span class="cx"> 
</span><span class="cx"> const ClassInfo FunctionExecutable::s_info = { &quot;FunctionExecutable&quot;, &amp;ScriptExecutable::s_info, 0, 0, CREATE_METHOD_TABLE(FunctionExecutable) };
</span><span class="cx"> 
</span><del>-FunctionExecutable::FunctionExecutable(JSGlobalData&amp; globalData, const Identifier&amp; name, const Identifier&amp; inferredName, const SourceCode&amp; source, bool forceUsesArguments, FunctionParameters* parameters, bool inStrictContext)
-    : ScriptExecutable(globalData.functionExecutableStructure.get(), globalData, source, inStrictContext)
</del><ins>+FunctionExecutable::FunctionExecutable(JSGlobalData&amp; globalData, FunctionBodyNode* node)
+    : ScriptExecutable(globalData.functionExecutableStructure.get(), globalData, node-&gt;source(), node-&gt;isStrictMode())
</ins><span class="cx">     , m_numCapturedVariables(0)
</span><del>-    , m_forceUsesArguments(forceUsesArguments)
-    , m_parameters(parameters)
-    , m_name(name)
-    , m_inferredName(inferredName.isNull() ? globalData.propertyNames-&gt;emptyIdentifier : inferredName)
</del><ins>+    , m_forceUsesArguments(node-&gt;usesArguments())
+    , m_parameters(node-&gt;parameters())
+    , m_name(node-&gt;ident())
+    , m_inferredName(node-&gt;inferredName().isNull() ? globalData.propertyNames-&gt;emptyIdentifier : node-&gt;inferredName())
</ins><span class="cx"> {
</span><ins>+    m_firstLine = node-&gt;lineNo();
+    m_lastLine = node-&gt;lastLine();
</ins><span class="cx"> }
</span><span class="cx"> 
</span><del>-FunctionExecutable::FunctionExecutable(ExecState* exec, const Identifier&amp; name, const Identifier&amp; inferredName, const SourceCode&amp; source, bool forceUsesArguments, FunctionParameters* parameters, bool inStrictContext)
-    : ScriptExecutable(exec-&gt;globalData().functionExecutableStructure.get(), exec, source, inStrictContext)
-    , m_numCapturedVariables(0)
-    , m_forceUsesArguments(forceUsesArguments)
-    , m_parameters(parameters)
-    , m_name(name)
-    , m_inferredName(inferredName.isNull() ? exec-&gt;globalData().propertyNames-&gt;emptyIdentifier : inferredName)
-{
-}
-
</del><span class="cx"> void FunctionExecutable::destroy(JSCell* cell)
</span><span class="cx"> {
</span><span class="cx">     static_cast&lt;FunctionExecutable*&gt;(cell)-&gt;FunctionExecutable::~FunctionExecutable();
</span><span class="lines">@@ -210,7 +202,7 @@
</span><span class="cx">     } else {
</span><span class="cx">         if (!lexicalGlobalObject-&gt;evalEnabled())
</span><span class="cx">             return throwError(exec, createEvalError(exec, ASCIILiteral(&quot;Eval is disabled&quot;)));
</span><del>-        RefPtr&lt;EvalNode&gt; evalNode = parse&lt;EvalNode&gt;(globalData, lexicalGlobalObject, m_source, 0, isStrictMode() ? JSParseStrict : JSParseNormal, EvalNode::isFunctionNode ? JSParseFunctionCode : JSParseProgramCode, lexicalGlobalObject-&gt;debugger(), exec, &amp;exception);
</del><ins>+        RefPtr&lt;EvalNode&gt; evalNode = parse&lt;EvalNode&gt;(globalData, lexicalGlobalObject, m_source, 0, Identifier(), isStrictMode() ? JSParseStrict : JSParseNormal, EvalNode::isFunctionNode ? JSParseFunctionCode : JSParseProgramCode, lexicalGlobalObject-&gt;debugger(), exec, &amp;exception);
</ins><span class="cx">         if (!evalNode) {
</span><span class="cx">             ASSERT(exception);
</span><span class="cx">             return exception;
</span><span class="lines">@@ -293,7 +285,7 @@
</span><span class="cx">     JSObject* exception = 0;
</span><span class="cx">     JSGlobalData* globalData = &amp;exec-&gt;globalData();
</span><span class="cx">     JSGlobalObject* lexicalGlobalObject = exec-&gt;lexicalGlobalObject();
</span><del>-    RefPtr&lt;ProgramNode&gt; programNode = parse&lt;ProgramNode&gt;(globalData, lexicalGlobalObject, m_source, 0, JSParseNormal, ProgramNode::isFunctionNode ? JSParseFunctionCode : JSParseProgramCode, lexicalGlobalObject-&gt;debugger(), exec, &amp;exception);
</del><ins>+    RefPtr&lt;ProgramNode&gt; programNode = parse&lt;ProgramNode&gt;(globalData, lexicalGlobalObject, m_source, 0, Identifier(), JSParseNormal, ProgramNode::isFunctionNode ? JSParseFunctionCode : JSParseProgramCode, lexicalGlobalObject-&gt;debugger(), exec, &amp;exception);
</ins><span class="cx">     if (programNode)
</span><span class="cx">         return 0;
</span><span class="cx">     ASSERT(exception);
</span><span class="lines">@@ -335,7 +327,7 @@
</span><span class="cx">         newCodeBlock-&gt;setAlternative(static_pointer_cast&lt;CodeBlock&gt;(m_programCodeBlock.release()));
</span><span class="cx">         m_programCodeBlock = newCodeBlock.release();
</span><span class="cx">     } else {
</span><del>-        RefPtr&lt;ProgramNode&gt; programNode = parse&lt;ProgramNode&gt;(globalData, lexicalGlobalObject, m_source, 0, isStrictMode() ? JSParseStrict : JSParseNormal, ProgramNode::isFunctionNode ? JSParseFunctionCode : JSParseProgramCode, lexicalGlobalObject-&gt;debugger(), exec, &amp;exception);
</del><ins>+        RefPtr&lt;ProgramNode&gt; programNode = parse&lt;ProgramNode&gt;(globalData, lexicalGlobalObject, m_source, 0, Identifier(), isStrictMode() ? JSParseStrict : JSParseNormal, ProgramNode::isFunctionNode ? JSParseFunctionCode : JSParseProgramCode, lexicalGlobalObject-&gt;debugger(), exec, &amp;exception);
</ins><span class="cx">         if (!programNode) {
</span><span class="cx">             ASSERT(exception);
</span><span class="cx">             return exception;
</span><span class="lines">@@ -478,7 +470,18 @@
</span><span class="cx">     exception = 0;
</span><span class="cx">     JSGlobalData* globalData = scope-&gt;globalData();
</span><span class="cx">     JSGlobalObject* globalObject = scope-&gt;globalObject();
</span><del>-    RefPtr&lt;FunctionBodyNode&gt; body = parse&lt;FunctionBodyNode&gt;(globalData, globalObject, m_source, m_parameters.get(), isStrictMode() ? JSParseStrict : JSParseNormal, FunctionBodyNode::isFunctionNode ? JSParseFunctionCode : JSParseProgramCode, 0, 0, &amp;exception);
</del><ins>+    RefPtr&lt;FunctionBodyNode&gt; body = parse&lt;FunctionBodyNode&gt;(
+        globalData,
+        globalObject,
+        m_source,
+        m_parameters.get(),
+        name(),
+        isStrictMode() ? JSParseStrict : JSParseNormal,
+        FunctionBodyNode::isFunctionNode ? JSParseFunctionCode : JSParseProgramCode,
+        0,
+        0,
+        &amp;exception
+    );
</ins><span class="cx"> 
</span><span class="cx">     if (!body) {
</span><span class="cx">         ASSERT(exception);
</span><span class="lines">@@ -647,16 +650,16 @@
</span><span class="cx"> #endif
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-FunctionExecutable* FunctionExecutable::fromGlobalCode(const Identifier&amp; functionName, ExecState* exec, Debugger* debugger, const SourceCode&amp; source, JSObject** exception)
</del><ins>+FunctionExecutable* FunctionExecutable::fromGlobalCode(const Identifier&amp; name, ExecState* exec, Debugger* debugger, const SourceCode&amp; source, JSObject** exception)
</ins><span class="cx"> {
</span><span class="cx">     JSGlobalObject* lexicalGlobalObject = exec-&gt;lexicalGlobalObject();
</span><del>-    RefPtr&lt;ProgramNode&gt; program = parse&lt;ProgramNode&gt;(&amp;exec-&gt;globalData(), lexicalGlobalObject, source, 0, JSParseNormal, ProgramNode::isFunctionNode ? JSParseFunctionCode : JSParseProgramCode, debugger, exec, exception);
</del><ins>+    RefPtr&lt;ProgramNode&gt; program = parse&lt;ProgramNode&gt;(&amp;exec-&gt;globalData(), lexicalGlobalObject, source, 0, Identifier(), JSParseNormal, ProgramNode::isFunctionNode ? JSParseFunctionCode : JSParseProgramCode, debugger, exec, exception);
</ins><span class="cx">     if (!program) {
</span><span class="cx">         ASSERT(*exception);
</span><span class="cx">         return 0;
</span><span class="cx">     }
</span><span class="cx"> 
</span><del>-    // Uses of this function that would not result in a single function expression are invalid.
</del><ins>+    // This function assumes an input string that would result in a single anonymous function expression.
</ins><span class="cx">     StatementNode* exprStatement = program-&gt;singleStatement();
</span><span class="cx">     ASSERT(exprStatement);
</span><span class="cx">     ASSERT(exprStatement-&gt;isExprStatement());
</span><span class="lines">@@ -665,8 +668,11 @@
</span><span class="cx">     ASSERT(funcExpr-&gt;isFuncExprNode());
</span><span class="cx">     FunctionBodyNode* body = static_cast&lt;FuncExprNode*&gt;(funcExpr)-&gt;body();
</span><span class="cx">     ASSERT(body);
</span><ins>+    ASSERT(body-&gt;ident().isNull());
</ins><span class="cx"> 
</span><del>-    return FunctionExecutable::create(exec-&gt;globalData(), functionName, functionName, body-&gt;source(), body-&gt;usesArguments(), body-&gt;parameters(), body-&gt;isStrictMode(), body-&gt;lineNo(), body-&gt;lastLine());
</del><ins>+    FunctionExecutable* functionExecutable = FunctionExecutable::create(exec-&gt;globalData(), body);
+    functionExecutable-&gt;m_nameValue.set(exec-&gt;globalData(), functionExecutable, jsString(&amp;exec-&gt;globalData(), name.ustring()));
+    return functionExecutable;
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> String FunctionExecutable::paramString() const
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreruntimeExecutableh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/runtime/Executable.h (127697 => 127698)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/runtime/Executable.h        2012-09-06 06:06:13 UTC (rev 127697)
+++ trunk/Source/JavaScriptCore/runtime/Executable.h        2012-09-06 06:17:59 UTC (rev 127698)
</span><span class="lines">@@ -539,27 +539,16 @@
</span><span class="cx">     public:
</span><span class="cx">         typedef ScriptExecutable Base;
</span><span class="cx"> 
</span><del>-        static FunctionExecutable* create(ExecState* exec, const Identifier&amp; name, const Identifier&amp; inferredName, const SourceCode&amp; source, bool forceUsesArguments, FunctionParameters* parameters, bool isInStrictContext, int firstLine, int lastLine)
</del><ins>+        static FunctionExecutable* create(JSGlobalData&amp; globalData, FunctionBodyNode* node)
</ins><span class="cx">         {
</span><del>-            FunctionExecutable* executable = new (NotNull, allocateCell&lt;FunctionExecutable&gt;(*exec-&gt;heap())) FunctionExecutable(exec, name, inferredName, source, forceUsesArguments, parameters, isInStrictContext);
-            executable-&gt;finishCreation(exec-&gt;globalData(), name, firstLine, lastLine);
</del><ins>+            FunctionExecutable* executable = new (NotNull, allocateCell&lt;FunctionExecutable&gt;(globalData.heap)) FunctionExecutable(globalData, node);
+            executable-&gt;finishCreation(globalData);
</ins><span class="cx">             return executable;
</span><span class="cx">         }
</span><ins>+        static FunctionExecutable* fromGlobalCode(const Identifier&amp; name, ExecState*, Debugger*, const SourceCode&amp;, JSObject** exception);
</ins><span class="cx"> 
</span><del>-        static FunctionExecutable* create(JSGlobalData&amp; globalData, const Identifier&amp; name, const Identifier&amp; inferredName, const SourceCode&amp; source, bool forceUsesArguments, FunctionParameters* parameters, bool isInStrictContext, int firstLine, int lastLine)
-        {
-            FunctionExecutable* executable = new (NotNull, allocateCell&lt;FunctionExecutable&gt;(globalData.heap)) FunctionExecutable(globalData, name, inferredName, source, forceUsesArguments, parameters, isInStrictContext);
-            executable-&gt;finishCreation(globalData, name, firstLine, lastLine);
-            return executable;
-        }
-
</del><span class="cx">         static void destroy(JSCell*);
</span><span class="cx"> 
</span><del>-        JSFunction* make(ExecState* exec, JSScope* scope)
-        {
-            return JSFunction::create(exec, this, scope);
-        }
-        
</del><span class="cx">         // Returns either call or construct bytecode. This can be appropriate
</span><span class="cx">         // for answering questions that that don't vary between call and construct --
</span><span class="cx">         // for example, argumentsRegister().
</span><span class="lines">@@ -708,7 +697,6 @@
</span><span class="cx"> 
</span><span class="cx">         void clearCodeIfNotCompiling();
</span><span class="cx">         static void visitChildren(JSCell*, SlotVisitor&amp;);
</span><del>-        static FunctionExecutable* fromGlobalCode(const Identifier&amp;, ExecState*, Debugger*, const SourceCode&amp;, JSObject** exception);
</del><span class="cx">         static Structure* createStructure(JSGlobalData&amp; globalData, JSGlobalObject* globalObject, JSValue proto)
</span><span class="cx">         {
</span><span class="cx">             return Structure::create(globalData, globalObject, proto, TypeInfo(FunctionExecutableType, StructureFlags), &amp;s_info);
</span><span class="lines">@@ -721,17 +709,14 @@
</span><span class="cx">         void clearCode();
</span><span class="cx"> 
</span><span class="cx">     protected:
</span><del>-        void finishCreation(JSGlobalData&amp; globalData, const Identifier&amp; name, int firstLine, int lastLine)
</del><ins>+        void finishCreation(JSGlobalData&amp; globalData)
</ins><span class="cx">         {
</span><span class="cx">             Base::finishCreation(globalData);
</span><del>-            m_firstLine = firstLine;
-            m_lastLine = lastLine;
-            m_nameValue.set(globalData, this, jsString(&amp;globalData, name.ustring()));
</del><ins>+            m_nameValue.set(globalData, this, jsString(&amp;globalData, name().ustring()));
</ins><span class="cx">         }
</span><span class="cx"> 
</span><span class="cx">     private:
</span><del>-        FunctionExecutable(JSGlobalData&amp;, const Identifier&amp; name, const Identifier&amp; inferredName, const SourceCode&amp;, bool forceUsesArguments, FunctionParameters*, bool);
-        FunctionExecutable(ExecState*, const Identifier&amp; name, const Identifier&amp; inferredName, const SourceCode&amp;, bool forceUsesArguments, FunctionParameters*, bool);
</del><ins>+        FunctionExecutable(JSGlobalData&amp;, FunctionBodyNode*);
</ins><span class="cx"> 
</span><span class="cx">         JSObject* compileForCallInternal(ExecState*, JSScope*, JITCode::JITType, unsigned bytecodeIndex = UINT_MAX);
</span><span class="cx">         JSObject* compileForConstructInternal(ExecState*, JSScope*, JITCode::JITType, unsigned bytecodeIndex = UINT_MAX);
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreruntimeJSNameScopeh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/runtime/JSNameScope.h (127697 => 127698)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/runtime/JSNameScope.h        2012-09-06 06:06:13 UTC (rev 127697)
+++ trunk/Source/JavaScriptCore/runtime/JSNameScope.h        2012-09-06 06:17:59 UTC (rev 127698)
</span><span class="lines">@@ -38,11 +38,18 @@
</span><span class="cx"> 
</span><span class="cx">     static JSNameScope* create(ExecState* exec, const Identifier&amp; identifier, JSValue value, unsigned attributes)
</span><span class="cx">     {
</span><del>-        JSNameScope* scopeObject = new (NotNull, allocateCell&lt;JSNameScope&gt;(*exec-&gt;heap())) JSNameScope(exec);
</del><ins>+        JSNameScope* scopeObject = new (NotNull, allocateCell&lt;JSNameScope&gt;(*exec-&gt;heap())) JSNameScope(exec, exec-&gt;scope());
</ins><span class="cx">         scopeObject-&gt;finishCreation(exec, identifier, value, attributes);
</span><span class="cx">         return scopeObject;
</span><span class="cx">     }
</span><span class="cx"> 
</span><ins>+    static JSNameScope* create(ExecState* exec, const Identifier&amp; identifier, JSValue value, unsigned attributes, JSScope* next)
+    {
+        JSNameScope* scopeObject = new (NotNull, allocateCell&lt;JSNameScope&gt;(*exec-&gt;heap())) JSNameScope(exec, next);
+        scopeObject-&gt;finishCreation(exec, identifier, value, attributes);
+        return scopeObject;
+    }
+
</ins><span class="cx">     static void visitChildren(JSCell*, SlotVisitor&amp;);
</span><span class="cx">     bool isDynamicScope(bool&amp; requiresDynamicChecks) const;
</span><span class="cx">     static JSObject* toThisObject(JSCell*, ExecState*);
</span><span class="lines">@@ -64,12 +71,12 @@
</span><span class="cx">     static const unsigned StructureFlags = OverridesGetOwnPropertySlot | OverridesVisitChildren | Base::StructureFlags;
</span><span class="cx"> 
</span><span class="cx"> private:
</span><del>-    JSNameScope(ExecState* exec)
</del><ins>+    JSNameScope(ExecState* exec, JSScope* next)
</ins><span class="cx">         : Base(
</span><span class="cx">             exec-&gt;globalData(),
</span><span class="cx">             exec-&gt;lexicalGlobalObject()-&gt;nameScopeStructure(),
</span><span class="cx">             reinterpret_cast&lt;Register*&gt;(&amp;m_registerStore + 1),
</span><del>-            exec-&gt;scope()
</del><ins>+            next
</ins><span class="cx">         )
</span><span class="cx">     {
</span><span class="cx">     }
</span></span></pre>
</div>
</div>

</body>
</html>