<!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>[202659] 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/202659">202659</a></dd>
<dt>Author</dt> <dd>joepeck@webkit.org</dd>
<dt>Date</dt> <dd>2016-06-29 16:59:35 -0700 (Wed, 29 Jun 2016)</dd>
</dl>

<h3>Log Message</h3>
<pre>Web Inspector: Wrong function name next to scope
https://bugs.webkit.org/show_bug.cgi?id=158210
&lt;rdar://problem/26543093&gt;

Reviewed by Brian Burg.

Source/JavaScriptCore:

* CMakeLists.txt:
* JavaScriptCore.xcodeproj/project.pbxproj:
Add DebuggerLocation. A helper for describing a unique location.

* bytecode/CodeBlock.cpp:
(JSC::CodeBlock::setConstantRegisters):
When compiled with debug info, add a SymbolTable rare data pointer
back to the CodeBlock. This will be used later to get JSScope debug
info if Web Inspector pauses.

* runtime/SymbolTable.h:
* runtime/SymbolTable.cpp:
(JSC::SymbolTable::cloneScopePart):
(JSC::SymbolTable::prepareForTypeProfiling):
(JSC::SymbolTable::uniqueIDForVariable):
(JSC::SymbolTable::uniqueIDForOffset):
(JSC::SymbolTable::globalTypeSetForOffset):
(JSC::SymbolTable::globalTypeSetForVariable):
Rename rareData and include a CodeBlock pointer.

(JSC::SymbolTable::rareDataCodeBlock):
(JSC::SymbolTable::setRareDataCodeBlock):
Setter and getter for the rare data. It should only be set once.

(JSC::SymbolTable::visitChildren):
Visit the rare data code block if we have one.

* debugger/DebuggerLocation.cpp: Added.
(JSC::DebuggerLocation::DebuggerLocation):
* debugger/DebuggerLocation.h: Added.
(JSC::DebuggerLocation::DebuggerLocation):
Construction from a ScriptExecutable.

* runtime/JSScope.cpp:
(JSC::JSScope::symbolTable):
* runtime/JSScope.h:
* debugger/DebuggerScope.h:
* debugger/DebuggerScope.cpp:
(JSC::DebuggerScope::name):
(JSC::DebuggerScope::location):
Name and location for a scope. This uses:
JSScope -&gt; SymbolTable -&gt; CodeBlock -&gt; Executable

* inspector/protocol/Debugger.json:
* inspector/InjectedScriptSource.js:
(InjectedScript.CallFrameProxy.prototype._wrapScopeChain):
(InjectedScript.CallFrameProxy._createScopeJson):
* inspector/JSJavaScriptCallFrame.cpp:
(Inspector::valueForScopeType):
(Inspector::valueForScopeLocation):
(Inspector::JSJavaScriptCallFrame::scopeDescriptions):
(Inspector::JSJavaScriptCallFrame::scopeType): Deleted.
* inspector/JSJavaScriptCallFrame.h:
* inspector/JSJavaScriptCallFramePrototype.cpp:
(Inspector::JSJavaScriptCallFramePrototype::finishCreation):
(Inspector::jsJavaScriptCallFramePrototypeFunctionScopeDescriptions):
(Inspector::jsJavaScriptCallFramePrototypeFunctionScopeType): Deleted.
Simplify this code to build the objects we will send across the protocol
to descript a Scope.

Source/WebInspectorUI:

* UserInterface/Controllers/DebuggerManager.js:
(WebInspector.DebuggerManager.prototype._scopeChainNodeFromPayload):
Include new payload data in the construction call.
All the new data is optional, so we gracefully handle
legacy backends.

* UserInterface/Models/ScopeChainNode.js:
(WebInspector.ScopeChainNode):
(WebInspector.ScopeChainNode.prototype.get type):
(WebInspector.ScopeChainNode.prototype.get objects):
(WebInspector.ScopeChainNode.prototype.get name):
(WebInspector.ScopeChainNode.prototype.get location):
(WebInspector.ScopeChainNode.prototype.get hash):
Hash is a rough (name:sourceId:line:column) string for quick comparisons.

(WebInspector.ScopeChainNode.prototype.makeLocalScope):
Make this an action you take on a scope, to avoid having to
do it at construction time, or making it a generic setting.

* UserInterface/Views/ScopeChainDetailsSidebarPanel.js:
(WebInspector.ScopeChainDetailsSidebarPanel.prototype._generateCallFramesSection):
This was wrong before. Move the work to CallFrame
and change it to be correct.

* UserInterface/CallFrame.js:
(WebInspector.CallFrame.prototype.mergedScopeChain):

This transforms the scope chain for a call frame from:

     scope1  scope2  scope3  scope4  scope5  scope6  scope7
      foo     foo     foo     bar     bar      -       -
     Block  Closure Closure Closure Closure   GLE     GBL

To:
     scope1  scope2&amp;3   scope4&amp;5  scope6  scope7
      foo      foo*       bar*      -       -
     Block    Local     Closure    GLE     GBL

Doing a few things:

    - Merge the first two Closure scopes sharing a location.
      These are the &quot;var&quot; and &quot;let&quot; Closure scopes in a function,
      and it is better to present these together in the UI.

    - Mark the first Closure scope within a function (*). When
      this is displayed in the UI, we can provide the name of
      the function: &quot;Closure Scope (name)&quot;, and we even have
      location information that we can use to display a goto
      arrow if needed.

    - Make the first Closure scope the Local scope if it
      matches the Call Frame's function name. This lets us
      display the section as &quot;Local Variables&quot;.

LayoutTests:

* inspector/debugger/paused-scopes-expected.txt: Added.
* inspector/debugger/paused-scopes.html: Added.
* inspector/debugger/resources/paused-scopes.js: Added.
Test dumps the call frames and scope chains for each call frame
when pausing at different locations in a program. Outputting
the hashes we can see even identically named functions have
different hashes because their location is different.</pre>

<h3>Modified Paths</h3>
<ul>
<li><a href="#trunkLayoutTestsChangeLog">trunk/LayoutTests/ChangeLog</a></li>
<li><a href="#trunkSourceJavaScriptCoreCMakeListstxt">trunk/Source/JavaScriptCore/CMakeLists.txt</a></li>
<li><a href="#trunkSourceJavaScriptCoreChangeLog">trunk/Source/JavaScriptCore/ChangeLog</a></li>
<li><a href="#trunkSourceJavaScriptCoreJavaScriptCorexcodeprojprojectpbxproj">trunk/Source/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj</a></li>
<li><a href="#trunkSourceJavaScriptCorebytecodeCodeBlockcpp">trunk/Source/JavaScriptCore/bytecode/CodeBlock.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoredebuggerDebuggerScopecpp">trunk/Source/JavaScriptCore/debugger/DebuggerScope.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoredebuggerDebuggerScopeh">trunk/Source/JavaScriptCore/debugger/DebuggerScope.h</a></li>
<li><a href="#trunkSourceJavaScriptCoreinspectorInjectedScriptSourcejs">trunk/Source/JavaScriptCore/inspector/InjectedScriptSource.js</a></li>
<li><a href="#trunkSourceJavaScriptCoreinspectorJSJavaScriptCallFramecpp">trunk/Source/JavaScriptCore/inspector/JSJavaScriptCallFrame.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoreinspectorJSJavaScriptCallFrameh">trunk/Source/JavaScriptCore/inspector/JSJavaScriptCallFrame.h</a></li>
<li><a href="#trunkSourceJavaScriptCoreinspectorJSJavaScriptCallFramePrototypecpp">trunk/Source/JavaScriptCore/inspector/JSJavaScriptCallFramePrototype.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoreinspectorprotocolDebuggerjson">trunk/Source/JavaScriptCore/inspector/protocol/Debugger.json</a></li>
<li><a href="#trunkSourceJavaScriptCoreruntimeJSScopecpp">trunk/Source/JavaScriptCore/runtime/JSScope.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoreruntimeJSScopeh">trunk/Source/JavaScriptCore/runtime/JSScope.h</a></li>
<li><a href="#trunkSourceJavaScriptCoreruntimeSymbolTablecpp">trunk/Source/JavaScriptCore/runtime/SymbolTable.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoreruntimeSymbolTableh">trunk/Source/JavaScriptCore/runtime/SymbolTable.h</a></li>
<li><a href="#trunkSourceWebInspectorUIChangeLog">trunk/Source/WebInspectorUI/ChangeLog</a></li>
<li><a href="#trunkSourceWebInspectorUIUserInterfaceControllersDebuggerManagerjs">trunk/Source/WebInspectorUI/UserInterface/Controllers/DebuggerManager.js</a></li>
<li><a href="#trunkSourceWebInspectorUIUserInterfaceModelsCallFramejs">trunk/Source/WebInspectorUI/UserInterface/Models/CallFrame.js</a></li>
<li><a href="#trunkSourceWebInspectorUIUserInterfaceModelsScopeChainNodejs">trunk/Source/WebInspectorUI/UserInterface/Models/ScopeChainNode.js</a></li>
<li><a href="#trunkSourceWebInspectorUIUserInterfaceViewsScopeChainDetailsSidebarPaneljs">trunk/Source/WebInspectorUI/UserInterface/Views/ScopeChainDetailsSidebarPanel.js</a></li>
</ul>

<h3>Added Paths</h3>
<ul>
<li><a href="#trunkLayoutTestsinspectordebuggerpausedscopesexpectedtxt">trunk/LayoutTests/inspector/debugger/paused-scopes-expected.txt</a></li>
<li><a href="#trunkLayoutTestsinspectordebuggerpausedscopeshtml">trunk/LayoutTests/inspector/debugger/paused-scopes.html</a></li>
<li><a href="#trunkLayoutTestsinspectordebuggerresourcespausedscopesjs">trunk/LayoutTests/inspector/debugger/resources/paused-scopes.js</a></li>
<li><a href="#trunkSourceJavaScriptCoredebuggerDebuggerLocationcpp">trunk/Source/JavaScriptCore/debugger/DebuggerLocation.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoredebuggerDebuggerLocationh">trunk/Source/JavaScriptCore/debugger/DebuggerLocation.h</a></li>
</ul>

</div>
<div id="patch">
<h3>Diff</h3>
<a id="trunkLayoutTestsChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/LayoutTests/ChangeLog (202658 => 202659)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/ChangeLog        2016-06-29 23:28:16 UTC (rev 202658)
+++ trunk/LayoutTests/ChangeLog        2016-06-29 23:59:35 UTC (rev 202659)
</span><span class="lines">@@ -1,3 +1,19 @@
</span><ins>+2016-06-29  Joseph Pecoraro  &lt;pecoraro@apple.com&gt;
+
+        Web Inspector: Wrong function name next to scope
+        https://bugs.webkit.org/show_bug.cgi?id=158210
+        &lt;rdar://problem/26543093&gt;
+
+        Reviewed by Brian Burg.
+
+        * inspector/debugger/paused-scopes-expected.txt: Added.
+        * inspector/debugger/paused-scopes.html: Added.
+        * inspector/debugger/resources/paused-scopes.js: Added.
+        Test dumps the call frames and scope chains for each call frame
+        when pausing at different locations in a program. Outputting
+        the hashes we can see even identically named functions have
+        different hashes because their location is different.
+
</ins><span class="cx"> 2016-06-29  Ryan Haddad  &lt;ryanhaddad@apple.com&gt;
</span><span class="cx"> 
</span><span class="cx">         Marking perf/rel-list-remove.html as flaky on ios-simulator
</span></span></pre></div>
<a id="trunkLayoutTestsinspectordebuggerpausedscopesexpectedtxt"></a>
<div class="addfile"><h4>Added: trunk/LayoutTests/inspector/debugger/paused-scopes-expected.txt (0 => 202659)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/inspector/debugger/paused-scopes-expected.txt                                (rev 0)
+++ trunk/LayoutTests/inspector/debugger/paused-scopes-expected.txt        2016-06-29 23:59:35 UTC (rev 202659)
</span><span class="lines">@@ -0,0 +1,205 @@
</span><ins>+Check scope chains for different call frames at different pauses.
+
+
+== Running test suite: PausedCallFrameScope
+-- Running test case: TriggerFirstPause
+CALLFRAME: firstPause
+
+---- Scope Chain ----
+  SCOPE: Name (firstPause) - Type (Block) - Hash (firstPause:&lt;sourceID&gt;:21:29)
+    - barLexicalVariable2
+  SCOPE: Name (firstPause) - Type (Closure) - Hash (firstPause:&lt;sourceID&gt;:21:29)
+    - barLexicalVariable2
+  SCOPE: Name (firstPause) - Type (Closure) - Hash (firstPause:&lt;sourceID&gt;:21:29)
+    - barVarVariable1
+  SCOPE: Name (firstPause) - Type (FunctionName) - Hash (firstPause:&lt;sourceID&gt;:21:29)
+    - firstPause
+  SCOPE: Name (firstPause) - Type (Closure) - Hash (firstPause:&lt;sourceID&gt;:19:24)
+    - fakeFirstPauseLexicalVariable
+  SCOPE: Name (firstPause) - Type (Closure) - Hash (firstPause:&lt;sourceID&gt;:19:24)
+  SCOPE: Name (entry) - Type (Closure) - Hash (entry:&lt;sourceID&gt;:14:15)
+    - fooLexicalVariable2
+  SCOPE: Name (entry) - Type (Closure) - Hash (entry:&lt;sourceID&gt;:14:15)
+    - firstPause
+    - fooVarVariable1
+  SCOPE: Name () - Type (GlobalLexicalEnvironment) - Hash ()
+    - globalLet2
+  SCOPE: Name () - Type (Global) - Hash ()
+
+---- Merged Scope Chain ----
+  SCOPE: Name (firstPause) - Type (Block) - Hash (firstPause:&lt;sourceID&gt;:21:29)
+    - barLexicalVariable2
+  SCOPE: Name (firstPause) - Type (Local) - Hash (firstPause:&lt;sourceID&gt;:21:29)
+    - barVarVariable1
+    - barLexicalVariable2
+  SCOPE: Name (firstPause) - Type (FunctionName) - Hash (firstPause:&lt;sourceID&gt;:21:29)
+    - firstPause
+  SCOPE: Name (firstPause) - Type (Closure) - Hash (firstPause:&lt;sourceID&gt;:19:24)
+    - fakeFirstPauseLexicalVariable
+  SCOPE: Name (entry) - Type (Closure) - Hash (entry:&lt;sourceID&gt;:14:15)
+    - firstPause
+    - fooVarVariable1
+    - fooLexicalVariable2
+  SCOPE: Name () - Type (GlobalLexicalEnvironment) - Hash ()
+    - globalLet2
+  SCOPE: Name () - Type (Global) - Hash ()
+
+CALLFRAME: firstPause
+
+---- Scope Chain ----
+  SCOPE: Name (firstPause) - Type (Closure) - Hash (firstPause:&lt;sourceID&gt;:19:24)
+    - fakeFirstPauseLexicalVariable
+  SCOPE: Name (firstPause) - Type (Closure) - Hash (firstPause:&lt;sourceID&gt;:19:24)
+  SCOPE: Name (entry) - Type (Closure) - Hash (entry:&lt;sourceID&gt;:14:15)
+    - fooLexicalVariable2
+  SCOPE: Name (entry) - Type (Closure) - Hash (entry:&lt;sourceID&gt;:14:15)
+    - firstPause
+    - fooVarVariable1
+  SCOPE: Name () - Type (GlobalLexicalEnvironment) - Hash ()
+    - globalLet2
+  SCOPE: Name () - Type (Global) - Hash ()
+
+---- Merged Scope Chain ----
+  SCOPE: Name (firstPause) - Type (Local) - Hash (firstPause:&lt;sourceID&gt;:19:24)
+    - fakeFirstPauseLexicalVariable
+  SCOPE: Name (entry) - Type (Closure) - Hash (entry:&lt;sourceID&gt;:14:15)
+    - firstPause
+    - fooVarVariable1
+    - fooLexicalVariable2
+  SCOPE: Name () - Type (GlobalLexicalEnvironment) - Hash ()
+    - globalLet2
+  SCOPE: Name () - Type (Global) - Hash ()
+
+CALLFRAME: entry
+
+---- Scope Chain ----
+  SCOPE: Name (entry) - Type (Closure) - Hash (entry:&lt;sourceID&gt;:14:15)
+    - fooLexicalVariable2
+  SCOPE: Name (entry) - Type (Closure) - Hash (entry:&lt;sourceID&gt;:14:15)
+    - firstPause
+    - fooVarVariable1
+  SCOPE: Name () - Type (GlobalLexicalEnvironment) - Hash ()
+    - globalLet2
+  SCOPE: Name () - Type (Global) - Hash ()
+
+---- Merged Scope Chain ----
+  SCOPE: Name (entry) - Type (Local) - Hash (entry:&lt;sourceID&gt;:14:15)
+    - firstPause
+    - fooVarVariable1
+    - fooLexicalVariable2
+  SCOPE: Name () - Type (GlobalLexicalEnvironment) - Hash ()
+    - globalLet2
+  SCOPE: Name () - Type (Global) - Hash ()
+
+
+-- Running test case: TriggerSecondPause
+CALLFRAME: secondPause
+
+---- Scope Chain ----
+  SCOPE: Name (secondPause) - Type (Block) - Hash (secondPause:&lt;sourceID&gt;:6:21)
+    - blockLexicalVariable
+  SCOPE: Name (secondPause) - Type (Closure) - Hash (secondPause:&lt;sourceID&gt;:6:21)
+    - shoeLexicalVariable1
+  SCOPE: Name (secondPause) - Type (Closure) - Hash (secondPause:&lt;sourceID&gt;:6:21)
+  SCOPE: Name () - Type (GlobalLexicalEnvironment) - Hash ()
+    - globalLet2
+  SCOPE: Name () - Type (Global) - Hash ()
+
+---- Merged Scope Chain ----
+  SCOPE: Name (secondPause) - Type (Block) - Hash (secondPause:&lt;sourceID&gt;:6:21)
+    - blockLexicalVariable
+  SCOPE: Name (secondPause) - Type (Local) - Hash (secondPause:&lt;sourceID&gt;:6:21)
+    - shoeLexicalVariable1
+  SCOPE: Name () - Type (GlobalLexicalEnvironment) - Hash ()
+    - globalLet2
+  SCOPE: Name () - Type (Global) - Hash ()
+
+CALLFRAME: firstPause
+
+---- Scope Chain ----
+  SCOPE: Name (firstPause) - Type (Block) - Hash (firstPause:&lt;sourceID&gt;:21:29)
+    - barLexicalVariable2
+  SCOPE: Name (firstPause) - Type (Closure) - Hash (firstPause:&lt;sourceID&gt;:21:29)
+    - barLexicalVariable2
+  SCOPE: Name (firstPause) - Type (Closure) - Hash (firstPause:&lt;sourceID&gt;:21:29)
+    - barVarVariable1
+  SCOPE: Name (firstPause) - Type (FunctionName) - Hash (firstPause:&lt;sourceID&gt;:21:29)
+    - firstPause
+  SCOPE: Name (firstPause) - Type (Closure) - Hash (firstPause:&lt;sourceID&gt;:19:24)
+    - fakeFirstPauseLexicalVariable
+  SCOPE: Name (firstPause) - Type (Closure) - Hash (firstPause:&lt;sourceID&gt;:19:24)
+  SCOPE: Name (entry) - Type (Closure) - Hash (entry:&lt;sourceID&gt;:14:15)
+    - fooLexicalVariable2
+  SCOPE: Name (entry) - Type (Closure) - Hash (entry:&lt;sourceID&gt;:14:15)
+    - firstPause
+    - fooVarVariable1
+  SCOPE: Name () - Type (GlobalLexicalEnvironment) - Hash ()
+    - globalLet2
+  SCOPE: Name () - Type (Global) - Hash ()
+
+---- Merged Scope Chain ----
+  SCOPE: Name (firstPause) - Type (Block) - Hash (firstPause:&lt;sourceID&gt;:21:29)
+    - barLexicalVariable2
+  SCOPE: Name (firstPause) - Type (Local) - Hash (firstPause:&lt;sourceID&gt;:21:29)
+    - barVarVariable1
+    - barLexicalVariable2
+  SCOPE: Name (firstPause) - Type (FunctionName) - Hash (firstPause:&lt;sourceID&gt;:21:29)
+    - firstPause
+  SCOPE: Name (firstPause) - Type (Closure) - Hash (firstPause:&lt;sourceID&gt;:19:24)
+    - fakeFirstPauseLexicalVariable
+  SCOPE: Name (entry) - Type (Closure) - Hash (entry:&lt;sourceID&gt;:14:15)
+    - firstPause
+    - fooVarVariable1
+    - fooLexicalVariable2
+  SCOPE: Name () - Type (GlobalLexicalEnvironment) - Hash ()
+    - globalLet2
+  SCOPE: Name () - Type (Global) - Hash ()
+
+CALLFRAME: firstPause
+
+---- Scope Chain ----
+  SCOPE: Name (firstPause) - Type (Closure) - Hash (firstPause:&lt;sourceID&gt;:19:24)
+    - fakeFirstPauseLexicalVariable
+  SCOPE: Name (firstPause) - Type (Closure) - Hash (firstPause:&lt;sourceID&gt;:19:24)
+  SCOPE: Name (entry) - Type (Closure) - Hash (entry:&lt;sourceID&gt;:14:15)
+    - fooLexicalVariable2
+  SCOPE: Name (entry) - Type (Closure) - Hash (entry:&lt;sourceID&gt;:14:15)
+    - firstPause
+    - fooVarVariable1
+  SCOPE: Name () - Type (GlobalLexicalEnvironment) - Hash ()
+    - globalLet2
+  SCOPE: Name () - Type (Global) - Hash ()
+
+---- Merged Scope Chain ----
+  SCOPE: Name (firstPause) - Type (Local) - Hash (firstPause:&lt;sourceID&gt;:19:24)
+    - fakeFirstPauseLexicalVariable
+  SCOPE: Name (entry) - Type (Closure) - Hash (entry:&lt;sourceID&gt;:14:15)
+    - firstPause
+    - fooVarVariable1
+    - fooLexicalVariable2
+  SCOPE: Name () - Type (GlobalLexicalEnvironment) - Hash ()
+    - globalLet2
+  SCOPE: Name () - Type (Global) - Hash ()
+
+CALLFRAME: entry
+
+---- Scope Chain ----
+  SCOPE: Name (entry) - Type (Closure) - Hash (entry:&lt;sourceID&gt;:14:15)
+    - fooLexicalVariable2
+  SCOPE: Name (entry) - Type (Closure) - Hash (entry:&lt;sourceID&gt;:14:15)
+    - firstPause
+    - fooVarVariable1
+  SCOPE: Name () - Type (GlobalLexicalEnvironment) - Hash ()
+    - globalLet2
+  SCOPE: Name () - Type (Global) - Hash ()
+
+---- Merged Scope Chain ----
+  SCOPE: Name (entry) - Type (Local) - Hash (entry:&lt;sourceID&gt;:14:15)
+    - firstPause
+    - fooVarVariable1
+    - fooLexicalVariable2
+  SCOPE: Name () - Type (GlobalLexicalEnvironment) - Hash ()
+    - globalLet2
+  SCOPE: Name () - Type (Global) - Hash ()
+
+
</ins></span></pre></div>
<a id="trunkLayoutTestsinspectordebuggerpausedscopeshtml"></a>
<div class="addfile"><h4>Added: trunk/LayoutTests/inspector/debugger/paused-scopes.html (0 => 202659)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/inspector/debugger/paused-scopes.html                                (rev 0)
+++ trunk/LayoutTests/inspector/debugger/paused-scopes.html        2016-06-29 23:59:35 UTC (rev 202659)
</span><span class="lines">@@ -0,0 +1,118 @@
</span><ins>+&lt;!DOCTYPE html&gt;
+&lt;html&gt;
+&lt;head&gt;
+&lt;script src=&quot;../../http/tests/inspector/resources/inspector-test.js&quot;&gt;&lt;/script&gt;
+&lt;script src=&quot;resources/paused-scopes.js&quot;&gt;&lt;/script&gt;
+&lt;script&gt;
+
+function test()
+{
+    function scopeTypeName(type) {
+        switch (type) {
+            case WebInspector.ScopeChainNode.Type.Local: return &quot;Local&quot;;
+            case WebInspector.ScopeChainNode.Type.Global: return &quot;Global&quot;;
+            case WebInspector.ScopeChainNode.Type.GlobalLexicalEnvironment: return &quot;GlobalLexicalEnvironment&quot;;
+            case WebInspector.ScopeChainNode.Type.With: return &quot;With&quot;;
+            case WebInspector.ScopeChainNode.Type.Closure: return &quot;Closure&quot;;
+            case WebInspector.ScopeChainNode.Type.Catch: return &quot;Catch&quot;;
+            case WebInspector.ScopeChainNode.Type.FunctionName: return &quot;FunctionName&quot;;
+            case WebInspector.ScopeChainNode.Type.Block: return &quot;Block&quot;;
+            default: return &quot;Unknown!&quot;;
+        };        
+    }
+
+    function sanitizeHash(hash) {
+        return hash.replace(/:(.*?):/, &quot;:&lt;sourceID&gt;:&quot;);
+    }
+
+    function collectScopeChainProperties(scopeChain) {
+        let scopeChainData = [];
+
+        let promises = [];
+        for (let scope of scopeChain) {
+            let data = {scope, properties: []};
+            scopeChainData.push(data);
+            if (scope.type === WebInspector.ScopeChainNode.Type.Global)
+                continue;
+
+            for (let scopeObject of scope.objects) {
+                promises.push(new Promise((resolve, reject) =&gt; {
+                    scopeObject.getAllPropertyDescriptors((propertyDescriptors) =&gt; {
+                        data.properties = data.properties.concat(propertyDescriptors);
+                        resolve();
+                    });
+                }));
+            }
+        }
+
+        return Promise.all(promises)
+            .then(() =&gt; scopeChainData);
+    }
+
+    function dumpScopeChainData(scopeChainData) {
+        for (let {scope, properties} of scopeChainData) {
+            InspectorTest.log(`  SCOPE: Name (${scope.name}) - Type (${scopeTypeName(scope.type)}) - Hash (${sanitizeHash(scope.hash)})`);
+            for (let propertyDescriptor of properties)
+                InspectorTest.log(`    - ${propertyDescriptor.name}`);            
+        }
+    }
+
+    function dumpCallFrame(callFrame) {
+        return Promise.all([
+            collectScopeChainProperties(callFrame.scopeChain),
+            collectScopeChainProperties(callFrame.mergedScopeChain()),
+        ]).then((results) =&gt; {
+            let [scopeChainData, mergedScopeChainData] = results;
+            InspectorTest.log(`CALLFRAME: ${callFrame.functionName}`);
+            InspectorTest.log(&quot;\n---- Scope Chain ----&quot;);
+            dumpScopeChainData(scopeChainData);
+            InspectorTest.log(&quot;\n---- Merged Scope Chain ----&quot;);
+            dumpScopeChainData(mergedScopeChainData);
+            InspectorTest.log(&quot;&quot;);
+        });
+    }
+
+    function dumpCallFrames() {
+        let callFrames = WebInspector.debuggerManager.callFrames;
+        let chain = Promise.resolve();
+        for (let callFrame of callFrames)
+            chain = chain.then(() =&gt; dumpCallFrame(callFrame));
+        return chain;
+    }
+
+
+    let suite = InspectorTest.createAsyncSuite(&quot;PausedCallFrameScope&quot;);
+
+    suite.addTestCase({
+        name: &quot;TriggerFirstPause&quot;,
+        description: &quot;Verify CallFrames and Scopes with the first pause.&quot;,
+        test: (resolve, reject) =&gt; {
+            InspectorTest.evaluateInPage(&quot;setTimeout(entry)&quot;);
+            WebInspector.debuggerManager.singleFireEventListener(WebInspector.DebuggerManager.Event.CallFramesDidChange, (event) =&gt; {
+                dumpCallFrames().then(resolve, reject);
+            });
+        }
+    });
+
+    suite.addTestCase({
+        name: &quot;TriggerSecondPause&quot;,
+        description: &quot;Verify CallFrames and Scopes with the first pause.&quot;,
+        test: (resolve, reject) =&gt; {
+            WebInspector.debuggerManager.resume();
+            WebInspector.debuggerManager.singleFireEventListener(WebInspector.DebuggerManager.Event.CallFramesDidChange, (event) =&gt; {
+                dumpCallFrames().then(() =&gt; {
+                    WebInspector.debuggerManager.resume();
+                    resolve();
+                }, reject);
+            });
+        }
+    });
+
+    suite.runTestCasesAndFinish();
+}
+&lt;/script&gt;
+&lt;/head&gt;
+&lt;body onload=&quot;runTest()&quot;&gt;
+&lt;p&gt;Check scope chains for different call frames at different pauses.&lt;/p&gt;
+&lt;/body&gt;
+&lt;/html&gt;
</ins></span></pre></div>
<a id="trunkLayoutTestsinspectordebuggerresourcespausedscopesjs"></a>
<div class="addfile"><h4>Added: trunk/LayoutTests/inspector/debugger/resources/paused-scopes.js (0 => 202659)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/inspector/debugger/resources/paused-scopes.js                                (rev 0)
+++ trunk/LayoutTests/inspector/debugger/resources/paused-scopes.js        2016-06-29 23:59:35 UTC (rev 202659)
</span><span class="lines">@@ -0,0 +1,31 @@
</span><ins>+&quot;use strict&quot;;
+
+var globalVar1; // Global (globalVar1)
+let globalLet2; // GlobalLexicalEnvironment (globalLet2)
+
+function secondPause() { // Global (secondPause)
+    let shoeLexicalVariable1 = document; // ClosureScope (shoeLexicalVariable1)
+    if (true) {
+        let blockLexicalVariable = &quot;block&quot;; // NestedBlockScope (blockLexicalVariable)
+        debugger;
+    }
+}
+
+function entry() { // Global (entry)
+    var fooVarVariable1; // foo ClosureScope (fooVarVariable1)
+    let fooLexicalVariable2; // foo ClosureScope (fooLexicalVariable2)
+    firstPause();
+
+    function firstPause() { // foo ClosureScope (firstPause)
+        let fakeFirstPauseLexicalVariable; // firstPause ClosureScope (fakeFirstPauseLexicalVariable)
+        (function firstPause() {
+            var barVarVariable1 = window.navigator; // firstPause ClosureScope (barVarVariable1)
+            let barLexicalVariable2 = window.navigator; // firstPause ClosureScope (barLexicalVariable2)
+            if (true) {
+                let barLexicalVariable2 = window.navigator; // NestedBlockScope (barLexicalVariable2)
+                debugger;
+                secondPause();
+            }
+        })();
+    }
+}
</ins></span></pre></div>
<a id="trunkSourceJavaScriptCoreCMakeListstxt"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/CMakeLists.txt (202658 => 202659)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/CMakeLists.txt        2016-06-29 23:28:16 UTC (rev 202658)
+++ trunk/Source/JavaScriptCore/CMakeLists.txt        2016-06-29 23:59:35 UTC (rev 202659)
</span><span class="lines">@@ -239,6 +239,7 @@
</span><span class="cx"> 
</span><span class="cx">     debugger/Debugger.cpp
</span><span class="cx">     debugger/DebuggerCallFrame.cpp
</span><ins>+    debugger/DebuggerLocation.cpp
</ins><span class="cx">     debugger/DebuggerScope.cpp
</span><span class="cx"> 
</span><span class="cx">     dfg/DFGAbstractHeap.cpp
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/ChangeLog (202658 => 202659)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/ChangeLog        2016-06-29 23:28:16 UTC (rev 202658)
+++ trunk/Source/JavaScriptCore/ChangeLog        2016-06-29 23:59:35 UTC (rev 202659)
</span><span class="lines">@@ -1,3 +1,71 @@
</span><ins>+2016-06-29  Joseph Pecoraro  &lt;pecoraro@apple.com&gt;
+
+        Web Inspector: Wrong function name next to scope
+        https://bugs.webkit.org/show_bug.cgi?id=158210
+        &lt;rdar://problem/26543093&gt;
+
+        Reviewed by Brian Burg.
+
+        * CMakeLists.txt:
+        * JavaScriptCore.xcodeproj/project.pbxproj:
+        Add DebuggerLocation. A helper for describing a unique location.
+
+        * bytecode/CodeBlock.cpp:
+        (JSC::CodeBlock::setConstantRegisters):
+        When compiled with debug info, add a SymbolTable rare data pointer
+        back to the CodeBlock. This will be used later to get JSScope debug
+        info if Web Inspector pauses.
+
+        * runtime/SymbolTable.h:
+        * runtime/SymbolTable.cpp:
+        (JSC::SymbolTable::cloneScopePart):
+        (JSC::SymbolTable::prepareForTypeProfiling):
+        (JSC::SymbolTable::uniqueIDForVariable):
+        (JSC::SymbolTable::uniqueIDForOffset):
+        (JSC::SymbolTable::globalTypeSetForOffset):
+        (JSC::SymbolTable::globalTypeSetForVariable):
+        Rename rareData and include a CodeBlock pointer.
+
+        (JSC::SymbolTable::rareDataCodeBlock):
+        (JSC::SymbolTable::setRareDataCodeBlock):
+        Setter and getter for the rare data. It should only be set once.
+
+        (JSC::SymbolTable::visitChildren):
+        Visit the rare data code block if we have one.
+
+        * debugger/DebuggerLocation.cpp: Added.
+        (JSC::DebuggerLocation::DebuggerLocation):
+        * debugger/DebuggerLocation.h: Added.
+        (JSC::DebuggerLocation::DebuggerLocation):
+        Construction from a ScriptExecutable.
+
+        * runtime/JSScope.cpp:
+        (JSC::JSScope::symbolTable):
+        * runtime/JSScope.h:
+        * debugger/DebuggerScope.h:
+        * debugger/DebuggerScope.cpp:
+        (JSC::DebuggerScope::name):
+        (JSC::DebuggerScope::location):
+        Name and location for a scope. This uses:
+        JSScope -&gt; SymbolTable -&gt; CodeBlock -&gt; Executable
+
+        * inspector/protocol/Debugger.json:
+        * inspector/InjectedScriptSource.js:
+        (InjectedScript.CallFrameProxy.prototype._wrapScopeChain):
+        (InjectedScript.CallFrameProxy._createScopeJson):
+        * inspector/JSJavaScriptCallFrame.cpp:
+        (Inspector::valueForScopeType):
+        (Inspector::valueForScopeLocation):
+        (Inspector::JSJavaScriptCallFrame::scopeDescriptions):
+        (Inspector::JSJavaScriptCallFrame::scopeType): Deleted.
+        * inspector/JSJavaScriptCallFrame.h:
+        * inspector/JSJavaScriptCallFramePrototype.cpp:
+        (Inspector::JSJavaScriptCallFramePrototype::finishCreation):
+        (Inspector::jsJavaScriptCallFramePrototypeFunctionScopeDescriptions):
+        (Inspector::jsJavaScriptCallFramePrototypeFunctionScopeType): Deleted.
+        Simplify this code to build the objects we will send across the protocol
+        to descript a Scope.
+
</ins><span class="cx"> 2016-06-29  Saam barati  &lt;sbarati@apple.com&gt;
</span><span class="cx"> 
</span><span class="cx">         We don't emit TDZ checks for call_eval
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreJavaScriptCorexcodeprojprojectpbxproj"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj (202658 => 202659)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj        2016-06-29 23:28:16 UTC (rev 202658)
+++ trunk/Source/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj        2016-06-29 23:59:35 UTC (rev 202659)
</span><span class="lines">@@ -1645,6 +1645,8 @@
</span><span class="cx">                 A5EF9B171A1D440300702E90 /* generate_cpp_frontend_dispatcher_implementation.py in Headers */ = {isa = PBXBuildFile; fileRef = C4F4B6D41A05C76F005CAB76 /* generate_cpp_frontend_dispatcher_implementation.py */; settings = {ATTRIBUTES = (Private, ); }; };
</span><span class="cx">                 A5EF9B181A1D440600702E90 /* generate_cpp_protocol_types_header.py in Headers */ = {isa = PBXBuildFile; fileRef = C4F4B6D51A05C76F005CAB76 /* generate_cpp_protocol_types_header.py */; settings = {ATTRIBUTES = (Private, ); }; };
</span><span class="cx">                 A5EF9B191A1D440700702E90 /* generate_cpp_protocol_types_implementation.py in Headers */ = {isa = PBXBuildFile; fileRef = C4F4B6D61A05C76F005CAB76 /* generate_cpp_protocol_types_implementation.py */; settings = {ATTRIBUTES = (Private, ); }; };
</span><ins>+                A5FC84B21D1DDAD6006B5C46 /* DebuggerLocation.h in Headers */ = {isa = PBXBuildFile; fileRef = A5FC84B11D1DDAC8006B5C46 /* DebuggerLocation.h */; };
+                A5FC84B31D1DDAD9006B5C46 /* DebuggerLocation.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A5FC84B01D1DDAC8006B5C46 /* DebuggerLocation.cpp */; };
</ins><span class="cx">                 A5FD0067189AFE9C00633231 /* ScriptArguments.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A5FD0065189AFE9C00633231 /* ScriptArguments.cpp */; };
</span><span class="cx">                 A5FD0068189AFE9C00633231 /* ScriptArguments.h in Headers */ = {isa = PBXBuildFile; fileRef = A5FD0066189AFE9C00633231 /* ScriptArguments.h */; settings = {ATTRIBUTES = (Private, ); }; };
</span><span class="cx">                 A5FD006D189B00AA00633231 /* ScriptCallFrame.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A5FD0069189B00A900633231 /* ScriptCallFrame.cpp */; };
</span><span class="lines">@@ -3865,6 +3867,8 @@
</span><span class="cx">                 A5EA70F619F6DE5A0098F5EC /* generate_objc_internal_header.py */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.script.python; path = generate_objc_internal_header.py; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><span class="cx">                 A5EA70F819F6DE5A0098F5EC /* objc_generator.py */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.script.python; path = objc_generator.py; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><span class="cx">                 A5EA710D19F6DF810098F5EC /* InspectorAlternateBackendDispatchers.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = InspectorAlternateBackendDispatchers.h; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><ins>+                A5FC84B01D1DDAC8006B5C46 /* DebuggerLocation.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = DebuggerLocation.cpp; sourceTree = &quot;&lt;group&gt;&quot;; };
+                A5FC84B11D1DDAC8006B5C46 /* DebuggerLocation.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DebuggerLocation.h; sourceTree = &quot;&lt;group&gt;&quot;; };
</ins><span class="cx">                 A5FD0065189AFE9C00633231 /* ScriptArguments.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ScriptArguments.cpp; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><span class="cx">                 A5FD0066189AFE9C00633231 /* ScriptArguments.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ScriptArguments.h; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><span class="cx">                 A5FD0069189B00A900633231 /* ScriptCallFrame.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ScriptCallFrame.cpp; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><span class="lines">@@ -5342,6 +5346,8 @@
</span><span class="cx">                                 149559ED0DDCDDF700648087 /* DebuggerCallFrame.cpp */,
</span><span class="cx">                                 1480DB9B0DDC227F003CFDF2 /* DebuggerCallFrame.h */,
</span><span class="cx">                                 6AD2CB4C19B9140100065719 /* DebuggerEvalEnabler.h */,
</span><ins>+                                A5FC84B01D1DDAC8006B5C46 /* DebuggerLocation.cpp */,
+                                A5FC84B11D1DDAC8006B5C46 /* DebuggerLocation.h */,
</ins><span class="cx">                                 FEA0861F182B7A0400F6D851 /* DebuggerPrimitives.h */,
</span><span class="cx">                                 0F2D4DDB19832D34007D4B19 /* DebuggerScope.cpp */,
</span><span class="cx">                                 0F2D4DDC19832D34007D4B19 /* DebuggerScope.h */,
</span><span class="lines">@@ -7691,6 +7697,7 @@
</span><span class="cx">                                 996B731C1BDA08DD00331B84 /* JSDataViewPrototype.lut.h in Headers */,
</span><span class="cx">                                 978801411471AD920041B016 /* JSDateMath.h in Headers */,
</span><span class="cx">                                 C2A7F688160432D400F76B98 /* JSDestructibleObject.h in Headers */,
</span><ins>+                                A5FC84B21D1DDAD6006B5C46 /* DebuggerLocation.h in Headers */,
</ins><span class="cx">                                 FE384EE61ADDB7AD0055DE2C /* JSDollarVM.h in Headers */,
</span><span class="cx">                                 FE384EE81ADDB7AD0055DE2C /* JSDollarVMPrototype.h in Headers */,
</span><span class="cx">                                 BC18C42D0E16F5CD00B34460 /* JSEnvironmentRecord.h in Headers */,
</span><span class="lines">@@ -8770,6 +8777,7 @@
</span><span class="cx">                                 A57D23F11891B5B40031C7FA /* ContentSearchUtilities.cpp in Sources */,
</span><span class="cx">                                 52B717B51A0597E1007AF4F3 /* ControlFlowProfiler.cpp in Sources */,
</span><span class="cx">                                 0FBADF541BD1F4B800E073C1 /* CopiedBlock.cpp in Sources */,
</span><ins>+                                A5FC84B31D1DDAD9006B5C46 /* DebuggerLocation.cpp in Sources */,
</ins><span class="cx">                                 C240305514B404E60079EB64 /* CopiedSpace.cpp in Sources */,
</span><span class="cx">                                 0F6183301C45BF070072450B /* AirLowerMacros.cpp in Sources */,
</span><span class="cx">                                 C2239D1716262BDD005AC5FD /* CopyVisitor.cpp in Sources */,
</span></span></pre></div>
<a id="trunkSourceJavaScriptCorebytecodeCodeBlockcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/bytecode/CodeBlock.cpp (202658 => 202659)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/bytecode/CodeBlock.cpp        2016-06-29 23:28:16 UTC (rev 202658)
+++ trunk/Source/JavaScriptCore/bytecode/CodeBlock.cpp        2016-06-29 23:59:35 UTC (rev 202659)
</span><span class="lines">@@ -2477,7 +2477,12 @@
</span><span class="cx">                     ConcurrentJITLocker locker(symbolTable-&gt;m_lock);
</span><span class="cx">                     symbolTable-&gt;prepareForTypeProfiling(locker);
</span><span class="cx">                 }
</span><del>-                constant = symbolTable-&gt;cloneScopePart(*m_vm);
</del><ins>+
+                SymbolTable* clone = symbolTable-&gt;cloneScopePart(*m_vm);
+                if (wasCompiledWithDebuggingOpcodes())
+                    clone-&gt;setRareDataCodeBlock(this);
+
+                constant = clone;
</ins><span class="cx">             }
</span><span class="cx">         }
</span><span class="cx"> 
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoredebuggerDebuggerLocationcpp"></a>
<div class="addfile"><h4>Added: trunk/Source/JavaScriptCore/debugger/DebuggerLocation.cpp (0 => 202659)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/debugger/DebuggerLocation.cpp                                (rev 0)
+++ trunk/Source/JavaScriptCore/debugger/DebuggerLocation.cpp        2016-06-29 23:59:35 UTC (rev 202659)
</span><span class="lines">@@ -0,0 +1,46 @@
</span><ins>+/*
+ * Copyright (C) 2016 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
+ */
+
+#include &quot;config.h&quot;
+#include &quot;DebuggerLocation.h&quot;
+
+#include &quot;Executable.h&quot;
+
+namespace JSC {
+
+DebuggerLocation::DebuggerLocation(ScriptExecutable* executable)
+{
+    if (executable-&gt;isHostFunction())
+        return;
+
+    sourceID = executable-&gt;sourceID();
+    line = executable-&gt;firstLine();
+    column = executable-&gt;startColumn();
+    url = executable-&gt;sourceURL();
+    if (url.isEmpty())
+        url = executable-&gt;source().provider()-&gt;sourceURL();
+}
+
+} // namespace JSC
</ins></span></pre></div>
<a id="trunkSourceJavaScriptCoredebuggerDebuggerLocationh"></a>
<div class="addfile"><h4>Added: trunk/Source/JavaScriptCore/debugger/DebuggerLocation.h (0 => 202659)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/debugger/DebuggerLocation.h                                (rev 0)
+++ trunk/Source/JavaScriptCore/debugger/DebuggerLocation.h        2016-06-29 23:59:35 UTC (rev 202659)
</span><span class="lines">@@ -0,0 +1,53 @@
</span><ins>+/*
+ * Copyright (C) 2016 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
+ */
+
+#pragma once
+
+#include &quot;DebuggerPrimitives.h&quot;
+#include &lt;wtf/text/WTFString.h&gt;
+
+namespace JSC {
+
+class ScriptExecutable;
+
+struct DebuggerLocation {
+
+    DebuggerLocation() { }
+    DebuggerLocation(const String&amp; url, intptr_t sourceID, unsigned line, unsigned column)
+        : url(url)
+        , sourceID(sourceID)
+        , line(line)
+        , column(column)
+    { }
+
+    DebuggerLocation(ScriptExecutable*);
+
+    String url;
+    intptr_t sourceID { noSourceID };
+    unsigned line { 0 };
+    unsigned column { 0 };
+};
+
+} // namespace JSC
</ins></span></pre></div>
<a id="trunkSourceJavaScriptCoredebuggerDebuggerScopecpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/debugger/DebuggerScope.cpp (202658 => 202659)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/debugger/DebuggerScope.cpp        2016-06-29 23:28:16 UTC (rev 202658)
+++ trunk/Source/JavaScriptCore/debugger/DebuggerScope.cpp        2016-06-29 23:59:35 UTC (rev 202659)
</span><span class="lines">@@ -210,6 +210,33 @@
</span><span class="cx">     return m_scope-&gt;isNestedLexicalScope();
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+String DebuggerScope::name() const
+{
+    SymbolTable* symbolTable = m_scope-&gt;symbolTable();
+    if (!symbolTable)
+        return String();
+
+    CodeBlock* codeBlock = symbolTable-&gt;rareDataCodeBlock();
+    if (!codeBlock)
+        return String();
+
+    return String::fromUTF8(codeBlock-&gt;inferredName());
+}
+
+DebuggerLocation DebuggerScope::location() const
+{
+    SymbolTable* symbolTable = m_scope-&gt;symbolTable();
+    if (!symbolTable)
+        return DebuggerLocation();
+
+    CodeBlock* codeBlock = symbolTable-&gt;rareDataCodeBlock();
+    if (!codeBlock)
+        return DebuggerLocation();
+
+    ScriptExecutable* executable = codeBlock-&gt;ownerScriptExecutable();
+    return DebuggerLocation(executable);
+}
+
</ins><span class="cx"> JSValue DebuggerScope::caughtValue(ExecState* exec) const
</span><span class="cx"> {
</span><span class="cx">     ASSERT(isCatchScope());
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoredebuggerDebuggerScopeh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/debugger/DebuggerScope.h (202658 => 202659)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/debugger/DebuggerScope.h        2016-06-29 23:28:16 UTC (rev 202658)
+++ trunk/Source/JavaScriptCore/debugger/DebuggerScope.h        2016-06-29 23:59:35 UTC (rev 202659)
</span><span class="lines">@@ -26,6 +26,7 @@
</span><span class="cx"> #ifndef DebuggerScope_h
</span><span class="cx"> #define DebuggerScope_h
</span><span class="cx"> 
</span><ins>+#include &quot;DebuggerLocation.h&quot;
</ins><span class="cx"> #include &quot;JSObject.h&quot;
</span><span class="cx"> 
</span><span class="cx"> namespace JSC {
</span><span class="lines">@@ -88,6 +89,9 @@
</span><span class="cx">     bool isGlobalLexicalEnvironment() const;
</span><span class="cx">     bool isNestedLexicalScope() const;
</span><span class="cx"> 
</span><ins>+    String name() const;
+    DebuggerLocation location() const;
+
</ins><span class="cx">     JSValue caughtValue(ExecState*) const;
</span><span class="cx"> 
</span><span class="cx"> private:
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreinspectorInjectedScriptSourcejs"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/inspector/InjectedScriptSource.js (202658 => 202659)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/inspector/InjectedScriptSource.js        2016-06-29 23:28:16 UTC (rev 202658)
+++ trunk/Source/JavaScriptCore/inspector/InjectedScriptSource.js        2016-06-29 23:59:35 UTC (rev 202659)
</span><span class="lines">@@ -1306,9 +1306,11 @@
</span><span class="cx">     _wrapScopeChain: function(callFrame)
</span><span class="cx">     {
</span><span class="cx">         var scopeChain = callFrame.scopeChain;
</span><ins>+        var scopeDescriptions = callFrame.scopeDescriptions();
+
</ins><span class="cx">         var scopeChainProxy = [];
</span><span class="cx">         for (var i = 0; i &lt; scopeChain.length; i++)
</span><del>-            scopeChainProxy[i] = InjectedScript.CallFrameProxy._createScopeJson(callFrame.scopeType(i), scopeChain[i], &quot;backtrace&quot;);
</del><ins>+            scopeChainProxy[i] = InjectedScript.CallFrameProxy._createScopeJson(scopeChain[i], scopeDescriptions[i], &quot;backtrace&quot;);
</ins><span class="cx">         return scopeChainProxy;
</span><span class="cx">     }
</span><span class="cx"> }
</span><span class="lines">@@ -1321,14 +1323,21 @@
</span><span class="cx">     4: &quot;functionName&quot;, // FUNCTION_NAME_SCOPE
</span><span class="cx">     5: &quot;globalLexicalEnvironment&quot;, // GLOBAL_LEXICAL_ENVIRONMENT_SCOPE
</span><span class="cx">     6: &quot;nestedLexical&quot;, // NESTED_LEXICAL_SCOPE
</span><del>-}
</del><ins>+};
</ins><span class="cx"> 
</span><del>-InjectedScript.CallFrameProxy._createScopeJson = function(scopeTypeCode, scopeObject, groupId)
</del><ins>+InjectedScript.CallFrameProxy._createScopeJson = function(object, {name, type, location}, groupId)
</ins><span class="cx"> {
</span><del>-    return {
-        object: injectedScript._wrapObject(scopeObject, groupId),
-        type: InjectedScript.CallFrameProxy._scopeTypeNames[scopeTypeCode]
</del><ins>+    var scope = {
+        object: injectedScript._wrapObject(object, groupId),
+        type: InjectedScript.CallFrameProxy._scopeTypeNames[type],
</ins><span class="cx">     };
</span><ins>+
+    if (name)
+        scope.name = name;
+    if (location)
+        scope.location = location;
+
+    return scope;
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> 
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreinspectorJSJavaScriptCallFramecpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/inspector/JSJavaScriptCallFrame.cpp (202658 => 202659)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/inspector/JSJavaScriptCallFrame.cpp        2016-06-29 23:28:16 UTC (rev 202658)
+++ trunk/Source/JavaScriptCore/inspector/JSJavaScriptCallFrame.cpp        2016-06-29 23:59:35 UTC (rev 202659)
</span><span class="lines">@@ -28,9 +28,11 @@
</span><span class="cx"> 
</span><span class="cx"> #include &quot;DebuggerScope.h&quot;
</span><span class="cx"> #include &quot;Error.h&quot;
</span><ins>+#include &quot;IdentifierInlines.h&quot;
</ins><span class="cx"> #include &quot;JSCJSValue.h&quot;
</span><span class="cx"> #include &quot;JSCellInlines.h&quot;
</span><span class="cx"> #include &quot;JSJavaScriptCallFramePrototype.h&quot;
</span><ins>+#include &quot;ObjectConstructor.h&quot;
</ins><span class="cx"> #include &quot;StructureInlines.h&quot;
</span><span class="cx"> 
</span><span class="cx"> using namespace JSC;
</span><span class="lines">@@ -92,45 +94,58 @@
</span><span class="cx">     return result;
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-JSValue JSJavaScriptCallFrame::scopeType(ExecState* exec)
</del><ins>+static JSValue valueForScopeType(DebuggerScope* scope)
</ins><span class="cx"> {
</span><del>-    if (!impl().scopeChain())
-        return jsUndefined();
</del><ins>+    if (scope-&gt;isCatchScope())
+        return jsNumber(JSJavaScriptCallFrame::CATCH_SCOPE);
+    if (scope-&gt;isFunctionNameScope())
+        return jsNumber(JSJavaScriptCallFrame::FUNCTION_NAME_SCOPE);
+    if (scope-&gt;isWithScope())
+        return jsNumber(JSJavaScriptCallFrame::WITH_SCOPE);
+    if (scope-&gt;isNestedLexicalScope())
+        return jsNumber(JSJavaScriptCallFrame::NESTED_LEXICAL_SCOPE);
+    if (scope-&gt;isGlobalLexicalEnvironment())
+        return jsNumber(JSJavaScriptCallFrame::GLOBAL_LEXICAL_ENVIRONMENT_SCOPE);
+    if (scope-&gt;isGlobalScope())
+        return jsNumber(JSJavaScriptCallFrame::GLOBAL_SCOPE);
</ins><span class="cx"> 
</span><del>-    if (!exec-&gt;argument(0).isInt32())
</del><ins>+    ASSERT(scope-&gt;isClosureScope());
+    return jsNumber(JSJavaScriptCallFrame::CLOSURE_SCOPE);
+}
+
+static JSValue valueForScopeLocation(ExecState* exec, const DebuggerLocation&amp; location)
+{
+    if (location.sourceID == noSourceID)
+        return jsNull();
+
+    // Debugger.Location protocol object.
+    JSObject* result = constructEmptyObject(exec);
+    result-&gt;putDirect(exec-&gt;vm(), Identifier::fromString(exec, &quot;scriptId&quot;), jsString(exec, String::number(location.sourceID)));
+    result-&gt;putDirect(exec-&gt;vm(), Identifier::fromString(exec, &quot;lineNumber&quot;), jsNumber(location.line));
+    result-&gt;putDirect(exec-&gt;vm(), Identifier::fromString(exec, &quot;columnNumber&quot;), jsNumber(location.column));
+    return result;
+}
+
+JSValue JSJavaScriptCallFrame::scopeDescriptions(ExecState* exec)
+{
+    DebuggerScope* scopeChain = impl().scopeChain();
+    if (!scopeChain)
</ins><span class="cx">         return jsUndefined();
</span><del>-    int index = exec-&gt;argument(0).asInt32();
</del><span class="cx"> 
</span><del>-    DebuggerScope* scopeChain = impl().scopeChain();
</del><ins>+    int index = 0;
+    JSArray* array = constructEmptyArray(exec, nullptr);
+
</ins><span class="cx">     DebuggerScope::iterator end = scopeChain-&gt;end();
</span><del>-
</del><span class="cx">     for (DebuggerScope::iterator iter = scopeChain-&gt;begin(); iter != end; ++iter) {
</span><span class="cx">         DebuggerScope* scope = iter.get();
</span><del>-
-        if (!index) {
-            if (scope-&gt;isCatchScope())
-                return jsNumber(JSJavaScriptCallFrame::CATCH_SCOPE);
-            if (scope-&gt;isFunctionNameScope())
-                return jsNumber(JSJavaScriptCallFrame::FUNCTION_NAME_SCOPE);
-            if (scope-&gt;isWithScope())
-                return jsNumber(JSJavaScriptCallFrame::WITH_SCOPE);
-            if (scope-&gt;isNestedLexicalScope())
-                return jsNumber(JSJavaScriptCallFrame::NESTED_LEXICAL_SCOPE);
-            if (scope-&gt;isGlobalLexicalEnvironment())
-                return jsNumber(JSJavaScriptCallFrame::GLOBAL_LEXICAL_ENVIRONMENT_SCOPE);
-            if (scope-&gt;isGlobalScope()) {
-                ASSERT(++iter == end);
-                return jsNumber(JSJavaScriptCallFrame::GLOBAL_SCOPE);
-            }
-            ASSERT(scope-&gt;isClosureScope());
-            return jsNumber(JSJavaScriptCallFrame::CLOSURE_SCOPE);
-        }
-
-        --index;
</del><ins>+        JSObject* description = constructEmptyObject(exec);
+        description-&gt;putDirect(exec-&gt;vm(), Identifier::fromString(exec, &quot;type&quot;), valueForScopeType(scope));
+        description-&gt;putDirect(exec-&gt;vm(), Identifier::fromString(exec, &quot;name&quot;), jsString(exec, scope-&gt;name()));
+        description-&gt;putDirect(exec-&gt;vm(), Identifier::fromString(exec, &quot;location&quot;), valueForScopeLocation(exec, scope-&gt;location()));
+        array-&gt;putDirectIndex(exec, index++, description);
</ins><span class="cx">     }
</span><span class="cx"> 
</span><del>-    ASSERT_NOT_REACHED();
-    return jsUndefined();
</del><ins>+    return array;
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> JSValue JSJavaScriptCallFrame::caller(ExecState* exec) const
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreinspectorJSJavaScriptCallFrameh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/inspector/JSJavaScriptCallFrame.h (202658 => 202659)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/inspector/JSJavaScriptCallFrame.h        2016-06-29 23:28:16 UTC (rev 202658)
+++ trunk/Source/JavaScriptCore/inspector/JSJavaScriptCallFrame.h        2016-06-29 23:59:35 UTC (rev 202659)
</span><span class="lines">@@ -58,7 +58,7 @@
</span><span class="cx"> 
</span><span class="cx">     // Functions.
</span><span class="cx">     JSC::JSValue evaluateWithScopeExtension(JSC::ExecState*);
</span><del>-    JSC::JSValue scopeType(JSC::ExecState*);
</del><ins>+    JSC::JSValue scopeDescriptions(JSC::ExecState*);
</ins><span class="cx"> 
</span><span class="cx">     // Attributes.
</span><span class="cx">     JSC::JSValue caller(JSC::ExecState*) const;
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreinspectorJSJavaScriptCallFramePrototypecpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/inspector/JSJavaScriptCallFramePrototype.cpp (202658 => 202659)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/inspector/JSJavaScriptCallFramePrototype.cpp        2016-06-29 23:28:16 UTC (rev 202658)
+++ trunk/Source/JavaScriptCore/inspector/JSJavaScriptCallFramePrototype.cpp        2016-06-29 23:59:35 UTC (rev 202659)
</span><span class="lines">@@ -39,7 +39,7 @@
</span><span class="cx"> 
</span><span class="cx"> // Functions.
</span><span class="cx"> static EncodedJSValue JSC_HOST_CALL jsJavaScriptCallFramePrototypeFunctionEvaluateWithScopeExtension(ExecState*);
</span><del>-static EncodedJSValue JSC_HOST_CALL jsJavaScriptCallFramePrototypeFunctionScopeType(ExecState*);
</del><ins>+static EncodedJSValue JSC_HOST_CALL jsJavaScriptCallFramePrototypeFunctionScopeDescriptions(ExecState*);
</ins><span class="cx"> 
</span><span class="cx"> // Attributes.
</span><span class="cx"> static EncodedJSValue JSC_HOST_CALL jsJavaScriptCallFrameAttributeCaller(ExecState*);
</span><span class="lines">@@ -61,7 +61,7 @@
</span><span class="cx">     vm.prototypeMap.addPrototype(this);
</span><span class="cx"> 
</span><span class="cx">     JSC_NATIVE_FUNCTION_WITHOUT_TRANSITION(&quot;evaluateWithScopeExtension&quot;, jsJavaScriptCallFramePrototypeFunctionEvaluateWithScopeExtension, DontEnum, 1);
</span><del>-    JSC_NATIVE_FUNCTION_WITHOUT_TRANSITION(&quot;scopeType&quot;, jsJavaScriptCallFramePrototypeFunctionScopeType, DontEnum, 1);
</del><ins>+    JSC_NATIVE_FUNCTION_WITHOUT_TRANSITION(&quot;scopeDescriptions&quot;, jsJavaScriptCallFramePrototypeFunctionScopeDescriptions, DontEnum, 0);
</ins><span class="cx"> 
</span><span class="cx">     JSC_NATIVE_GETTER(&quot;caller&quot;, jsJavaScriptCallFrameAttributeCaller, DontEnum | Accessor);
</span><span class="cx">     JSC_NATIVE_GETTER(&quot;sourceID&quot;, jsJavaScriptCallFrameAttributeSourceID, DontEnum | Accessor);
</span><span class="lines">@@ -84,7 +84,7 @@
</span><span class="cx">     return JSValue::encode(castedThis-&gt;evaluateWithScopeExtension(exec));
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-EncodedJSValue JSC_HOST_CALL jsJavaScriptCallFramePrototypeFunctionScopeType(ExecState* exec)
</del><ins>+EncodedJSValue JSC_HOST_CALL jsJavaScriptCallFramePrototypeFunctionScopeDescriptions(ExecState* exec)
</ins><span class="cx"> {
</span><span class="cx">     JSValue thisValue = exec-&gt;thisValue();
</span><span class="cx">     JSJavaScriptCallFrame* castedThis = jsDynamicCast&lt;JSJavaScriptCallFrame*&gt;(thisValue);
</span><span class="lines">@@ -91,7 +91,7 @@
</span><span class="cx">     if (!castedThis)
</span><span class="cx">         return throwVMTypeError(exec);
</span><span class="cx"> 
</span><del>-    return JSValue::encode(castedThis-&gt;scopeType(exec));
</del><ins>+    return JSValue::encode(castedThis-&gt;scopeDescriptions(exec));
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> EncodedJSValue JSC_HOST_CALL jsJavaScriptCallFrameAttributeCaller(ExecState* exec)
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreinspectorprotocolDebuggerjson"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/inspector/protocol/Debugger.json (202658 => 202659)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/inspector/protocol/Debugger.json        2016-06-29 23:28:16 UTC (rev 202658)
+++ trunk/Source/JavaScriptCore/inspector/protocol/Debugger.json        2016-06-29 23:59:35 UTC (rev 202659)
</span><span class="lines">@@ -81,8 +81,10 @@
</span><span class="cx">             &quot;id&quot;: &quot;Scope&quot;,
</span><span class="cx">             &quot;type&quot;: &quot;object&quot;,
</span><span class="cx">             &quot;properties&quot;: [
</span><ins>+                { &quot;name&quot;: &quot;object&quot;, &quot;$ref&quot;: &quot;Runtime.RemoteObject&quot;, &quot;description&quot;: &quot;Object representing the scope. For &lt;code&gt;global&lt;/code&gt; and &lt;code&gt;with&lt;/code&gt; scopes it represents the actual object; for the rest of the scopes, it is artificial transient object enumerating scope variables as its properties.&quot; },
</ins><span class="cx">                 { &quot;name&quot;: &quot;type&quot;, &quot;type&quot;: &quot;string&quot;, &quot;enum&quot;: [&quot;global&quot;, &quot;with&quot;, &quot;closure&quot;, &quot;catch&quot;, &quot;functionName&quot;, &quot;globalLexicalEnvironment&quot;, &quot;nestedLexical&quot;], &quot;description&quot;: &quot;Scope type.&quot; },
</span><del>-                { &quot;name&quot;: &quot;object&quot;, &quot;$ref&quot;: &quot;Runtime.RemoteObject&quot;, &quot;description&quot;: &quot;Object representing the scope. For &lt;code&gt;global&lt;/code&gt; and &lt;code&gt;with&lt;/code&gt; scopes it represents the actual object; for the rest of the scopes, it is artificial transient object enumerating scope variables as its properties.&quot; }
</del><ins>+                { &quot;name&quot;: &quot;name&quot;, &quot;type&quot;: &quot;string&quot;, &quot;optional&quot;: true, &quot;description&quot;: &quot;Name associated with the scope.&quot; },
+                { &quot;name&quot;: &quot;location&quot;, &quot;$ref&quot;: &quot;Location&quot;, &quot;optional&quot;: true, &quot;description&quot;: &quot;Location if available of the scope definition.&quot; }
</ins><span class="cx">             ],
</span><span class="cx">             &quot;description&quot;: &quot;Scope description.&quot;
</span><span class="cx">         },
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreruntimeJSScopecpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/runtime/JSScope.cpp (202658 => 202659)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/runtime/JSScope.cpp        2016-06-29 23:28:16 UTC (rev 202658)
+++ trunk/Source/JavaScriptCore/runtime/JSScope.cpp        2016-06-29 23:59:35 UTC (rev 202659)
</span><span class="lines">@@ -340,4 +340,12 @@
</span><span class="cx">     return nullptr;
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+SymbolTable* JSScope::symbolTable()
+{
+    if (JSSymbolTableObject* symbolTableObject = jsDynamicCast&lt;JSSymbolTableObject*&gt;(this))
+        return symbolTableObject-&gt;symbolTable();
+
+    return nullptr;
+}
+
</ins><span class="cx"> } // namespace JSC
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreruntimeJSScopeh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/runtime/JSScope.h (202658 => 202659)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/runtime/JSScope.h        2016-06-29 23:28:16 UTC (rev 202658)
+++ trunk/Source/JavaScriptCore/runtime/JSScope.h        2016-06-29 23:59:35 UTC (rev 202659)
</span><span class="lines">@@ -32,8 +32,9 @@
</span><span class="cx"> namespace JSC {
</span><span class="cx"> 
</span><span class="cx"> class ScopeChainIterator;
</span><ins>+class SymbolTable;
+class VariableEnvironment;
</ins><span class="cx"> class WatchpointSet;
</span><del>-class VariableEnvironment;
</del><span class="cx"> 
</span><span class="cx"> class JSScope : public JSNonFinalObject {
</span><span class="cx"> public:
</span><span class="lines">@@ -71,6 +72,8 @@
</span><span class="cx">     VM* vm();
</span><span class="cx">     JSObject* globalThis();
</span><span class="cx"> 
</span><ins>+    SymbolTable* symbolTable();
+
</ins><span class="cx"> protected:
</span><span class="cx">     JSScope(VM&amp;, Structure*, JSScope* next);
</span><span class="cx"> 
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreruntimeSymbolTablecpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/runtime/SymbolTable.cpp (202658 => 202659)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/runtime/SymbolTable.cpp        2016-06-29 23:28:16 UTC (rev 202658)
+++ trunk/Source/JavaScriptCore/runtime/SymbolTable.cpp        2016-06-29 23:59:35 UTC (rev 202659)
</span><span class="lines">@@ -104,6 +104,9 @@
</span><span class="cx">     visitor.append(&amp;thisSymbolTable-&gt;m_arguments);
</span><span class="cx">     visitor.append(&amp;thisSymbolTable-&gt;m_singletonScope);
</span><span class="cx">     
</span><ins>+    if (thisSymbolTable-&gt;m_rareData)
+        visitor.append(&amp;thisSymbolTable-&gt;m_rareData-&gt;m_codeBlock);
+    
</ins><span class="cx">     // Save some memory. This is O(n) to rebuild and we do so on the fly.
</span><span class="cx">     ConcurrentJITLocker locker(thisSymbolTable-&gt;m_lock);
</span><span class="cx">     thisSymbolTable-&gt;m_localToEntry = nullptr;
</span><span class="lines">@@ -159,28 +162,28 @@
</span><span class="cx">     if (ScopedArgumentsTable* arguments = this-&gt;arguments())
</span><span class="cx">         result-&gt;m_arguments.set(vm, result, arguments);
</span><span class="cx">     
</span><del>-    if (m_typeProfilingRareData) {
-        result-&gt;m_typeProfilingRareData = std::make_unique&lt;TypeProfilingRareData&gt;();
</del><ins>+    if (m_rareData) {
+        result-&gt;m_rareData = std::make_unique&lt;SymbolTableRareData&gt;();
</ins><span class="cx"> 
</span><span class="cx">         {
</span><del>-            auto iter = m_typeProfilingRareData-&gt;m_uniqueIDMap.begin();
-            auto end = m_typeProfilingRareData-&gt;m_uniqueIDMap.end();
</del><ins>+            auto iter = m_rareData-&gt;m_uniqueIDMap.begin();
+            auto end = m_rareData-&gt;m_uniqueIDMap.end();
</ins><span class="cx">             for (; iter != end; ++iter)
</span><del>-                result-&gt;m_typeProfilingRareData-&gt;m_uniqueIDMap.set(iter-&gt;key, iter-&gt;value);
</del><ins>+                result-&gt;m_rareData-&gt;m_uniqueIDMap.set(iter-&gt;key, iter-&gt;value);
</ins><span class="cx">         }
</span><span class="cx"> 
</span><span class="cx">         {
</span><del>-            auto iter = m_typeProfilingRareData-&gt;m_offsetToVariableMap.begin();
-            auto end = m_typeProfilingRareData-&gt;m_offsetToVariableMap.end();
</del><ins>+            auto iter = m_rareData-&gt;m_offsetToVariableMap.begin();
+            auto end = m_rareData-&gt;m_offsetToVariableMap.end();
</ins><span class="cx">             for (; iter != end; ++iter)
</span><del>-                result-&gt;m_typeProfilingRareData-&gt;m_offsetToVariableMap.set(iter-&gt;key, iter-&gt;value);
</del><ins>+                result-&gt;m_rareData-&gt;m_offsetToVariableMap.set(iter-&gt;key, iter-&gt;value);
</ins><span class="cx">         }
</span><span class="cx"> 
</span><span class="cx">         {
</span><del>-            auto iter = m_typeProfilingRareData-&gt;m_uniqueTypeSetMap.begin();
-            auto end = m_typeProfilingRareData-&gt;m_uniqueTypeSetMap.end();
</del><ins>+            auto iter = m_rareData-&gt;m_uniqueTypeSetMap.begin();
+            auto end = m_rareData-&gt;m_uniqueTypeSetMap.end();
</ins><span class="cx">             for (; iter != end; ++iter)
</span><del>-                result-&gt;m_typeProfilingRareData-&gt;m_uniqueTypeSetMap.set(iter-&gt;key, iter-&gt;value);
</del><ins>+                result-&gt;m_rareData-&gt;m_uniqueTypeSetMap.set(iter-&gt;key, iter-&gt;value);
</ins><span class="cx">         }
</span><span class="cx">     }
</span><span class="cx">     
</span><span class="lines">@@ -189,23 +192,40 @@
</span><span class="cx"> 
</span><span class="cx"> void SymbolTable::prepareForTypeProfiling(const ConcurrentJITLocker&amp;)
</span><span class="cx"> {
</span><del>-    if (m_typeProfilingRareData)
</del><ins>+    if (m_rareData)
</ins><span class="cx">         return;
</span><span class="cx"> 
</span><del>-    m_typeProfilingRareData = std::make_unique&lt;TypeProfilingRareData&gt;();
</del><ins>+    m_rareData = std::make_unique&lt;SymbolTableRareData&gt;();
</ins><span class="cx"> 
</span><span class="cx">     for (auto iter = m_map.begin(), end = m_map.end(); iter != end; ++iter) {
</span><del>-        m_typeProfilingRareData-&gt;m_uniqueIDMap.set(iter-&gt;key, TypeProfilerNeedsUniqueIDGeneration);
-        m_typeProfilingRareData-&gt;m_offsetToVariableMap.set(iter-&gt;value.varOffset(), iter-&gt;key);
</del><ins>+        m_rareData-&gt;m_uniqueIDMap.set(iter-&gt;key, TypeProfilerNeedsUniqueIDGeneration);
+        m_rareData-&gt;m_offsetToVariableMap.set(iter-&gt;value.varOffset(), iter-&gt;key);
</ins><span class="cx">     }
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+CodeBlock* SymbolTable::rareDataCodeBlock()
+{
+    if (!m_rareData)
+        return nullptr;
+
+    return m_rareData-&gt;m_codeBlock.get();
+}
+
+void SymbolTable::setRareDataCodeBlock(CodeBlock* codeBlock)
+{
+    if (!m_rareData)
+        m_rareData = std::make_unique&lt;SymbolTableRareData&gt;();
+
+    ASSERT(!m_rareData-&gt;m_codeBlock);
+    m_rareData-&gt;m_codeBlock.set(*codeBlock-&gt;vm(), this, codeBlock);
+}
+
</ins><span class="cx"> GlobalVariableID SymbolTable::uniqueIDForVariable(const ConcurrentJITLocker&amp;, UniquedStringImpl* key, VM&amp; vm)
</span><span class="cx"> {
</span><del>-    RELEASE_ASSERT(m_typeProfilingRareData);
</del><ins>+    RELEASE_ASSERT(m_rareData);
</ins><span class="cx"> 
</span><del>-    auto iter = m_typeProfilingRareData-&gt;m_uniqueIDMap.find(key);
-    auto end = m_typeProfilingRareData-&gt;m_uniqueIDMap.end();
</del><ins>+    auto iter = m_rareData-&gt;m_uniqueIDMap.find(key);
+    auto end = m_rareData-&gt;m_uniqueIDMap.end();
</ins><span class="cx">     if (iter == end)
</span><span class="cx">         return TypeProfilerNoGlobalIDExists;
</span><span class="cx"> 
</span><span class="lines">@@ -212,8 +232,8 @@
</span><span class="cx">     GlobalVariableID id = iter-&gt;value;
</span><span class="cx">     if (id == TypeProfilerNeedsUniqueIDGeneration) {
</span><span class="cx">         id = vm.typeProfiler()-&gt;getNextUniqueVariableID();
</span><del>-        m_typeProfilingRareData-&gt;m_uniqueIDMap.set(key, id);
-        m_typeProfilingRareData-&gt;m_uniqueTypeSetMap.set(key, TypeSet::create()); // Make a new global typeset for this corresponding ID.
</del><ins>+        m_rareData-&gt;m_uniqueIDMap.set(key, id);
+        m_rareData-&gt;m_uniqueTypeSetMap.set(key, TypeSet::create()); // Make a new global typeset for this corresponding ID.
</ins><span class="cx">     }
</span><span class="cx"> 
</span><span class="cx">     return id;
</span><span class="lines">@@ -221,10 +241,10 @@
</span><span class="cx"> 
</span><span class="cx"> GlobalVariableID SymbolTable::uniqueIDForOffset(const ConcurrentJITLocker&amp; locker, VarOffset offset, VM&amp; vm)
</span><span class="cx"> {
</span><del>-    RELEASE_ASSERT(m_typeProfilingRareData);
</del><ins>+    RELEASE_ASSERT(m_rareData);
</ins><span class="cx"> 
</span><del>-    auto iter = m_typeProfilingRareData-&gt;m_offsetToVariableMap.find(offset);
-    auto end = m_typeProfilingRareData-&gt;m_offsetToVariableMap.end();
</del><ins>+    auto iter = m_rareData-&gt;m_offsetToVariableMap.find(offset);
+    auto end = m_rareData-&gt;m_offsetToVariableMap.end();
</ins><span class="cx">     if (iter == end)
</span><span class="cx">         return TypeProfilerNoGlobalIDExists;
</span><span class="cx"> 
</span><span class="lines">@@ -233,12 +253,12 @@
</span><span class="cx"> 
</span><span class="cx"> RefPtr&lt;TypeSet&gt; SymbolTable::globalTypeSetForOffset(const ConcurrentJITLocker&amp; locker, VarOffset offset, VM&amp; vm)
</span><span class="cx"> {
</span><del>-    RELEASE_ASSERT(m_typeProfilingRareData);
</del><ins>+    RELEASE_ASSERT(m_rareData);
</ins><span class="cx"> 
</span><span class="cx">     uniqueIDForOffset(locker, offset, vm); // Lazily create the TypeSet if necessary.
</span><span class="cx"> 
</span><del>-    auto iter = m_typeProfilingRareData-&gt;m_offsetToVariableMap.find(offset);
-    auto end = m_typeProfilingRareData-&gt;m_offsetToVariableMap.end();
</del><ins>+    auto iter = m_rareData-&gt;m_offsetToVariableMap.find(offset);
+    auto end = m_rareData-&gt;m_offsetToVariableMap.end();
</ins><span class="cx">     if (iter == end)
</span><span class="cx">         return nullptr;
</span><span class="cx"> 
</span><span class="lines">@@ -247,12 +267,12 @@
</span><span class="cx"> 
</span><span class="cx"> RefPtr&lt;TypeSet&gt; SymbolTable::globalTypeSetForVariable(const ConcurrentJITLocker&amp; locker, UniquedStringImpl* key, VM&amp; vm)
</span><span class="cx"> {
</span><del>-    RELEASE_ASSERT(m_typeProfilingRareData);
</del><ins>+    RELEASE_ASSERT(m_rareData);
</ins><span class="cx"> 
</span><span class="cx">     uniqueIDForVariable(locker, key, vm); // Lazily create the TypeSet if necessary.
</span><span class="cx"> 
</span><del>-    auto iter = m_typeProfilingRareData-&gt;m_uniqueTypeSetMap.find(key);
-    auto end = m_typeProfilingRareData-&gt;m_uniqueTypeSetMap.end();
</del><ins>+    auto iter = m_rareData-&gt;m_uniqueTypeSetMap.find(key);
+    auto end = m_rareData-&gt;m_uniqueTypeSetMap.end();
</ins><span class="cx">     if (iter == end)
</span><span class="cx">         return nullptr;
</span><span class="cx"> 
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreruntimeSymbolTableh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/runtime/SymbolTable.h (202658 => 202659)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/runtime/SymbolTable.h        2016-06-29 23:28:16 UTC (rev 202658)
+++ trunk/Source/JavaScriptCore/runtime/SymbolTable.h        2016-06-29 23:59:35 UTC (rev 202659)
</span><span class="lines">@@ -679,6 +679,9 @@
</span><span class="cx">     SymbolTable* cloneScopePart(VM&amp;);
</span><span class="cx"> 
</span><span class="cx">     void prepareForTypeProfiling(const ConcurrentJITLocker&amp;);
</span><ins>+
+    CodeBlock* rareDataCodeBlock();
+    void setRareDataCodeBlock(CodeBlock*);
</ins><span class="cx">     
</span><span class="cx">     InferredValue* singletonScope() { return m_singletonScope.get(); }
</span><span class="cx"> 
</span><span class="lines">@@ -695,12 +698,13 @@
</span><span class="cx">     Map m_map;
</span><span class="cx">     ScopeOffset m_maxScopeOffset;
</span><span class="cx">     
</span><del>-    struct TypeProfilingRareData {
</del><ins>+    struct SymbolTableRareData {
</ins><span class="cx">         UniqueIDMap m_uniqueIDMap;
</span><span class="cx">         OffsetToVariableMap m_offsetToVariableMap;
</span><span class="cx">         UniqueTypeSetMap m_uniqueTypeSetMap;
</span><ins>+        WriteBarrier&lt;CodeBlock&gt; m_codeBlock;
</ins><span class="cx">     };
</span><del>-    std::unique_ptr&lt;TypeProfilingRareData&gt; m_typeProfilingRareData;
</del><ins>+    std::unique_ptr&lt;SymbolTableRareData&gt; m_rareData;
</ins><span class="cx"> 
</span><span class="cx">     bool m_usesNonStrictEval : 1;
</span><span class="cx">     bool m_nestedLexicalScope : 1; // Non-function LexicalScope.
</span></span></pre></div>
<a id="trunkSourceWebInspectorUIChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebInspectorUI/ChangeLog (202658 => 202659)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebInspectorUI/ChangeLog        2016-06-29 23:28:16 UTC (rev 202658)
+++ trunk/Source/WebInspectorUI/ChangeLog        2016-06-29 23:59:35 UTC (rev 202659)
</span><span class="lines">@@ -1,3 +1,65 @@
</span><ins>+2016-06-29  Joseph Pecoraro  &lt;pecoraro@apple.com&gt;
+
+        Web Inspector: Wrong function name next to scope
+        https://bugs.webkit.org/show_bug.cgi?id=158210
+        &lt;rdar://problem/26543093&gt;
+
+        Reviewed by Brian Burg.
+
+        * UserInterface/Controllers/DebuggerManager.js:
+        (WebInspector.DebuggerManager.prototype._scopeChainNodeFromPayload):
+        Include new payload data in the construction call.
+        All the new data is optional, so we gracefully handle
+        legacy backends.
+
+        * UserInterface/Models/ScopeChainNode.js:
+        (WebInspector.ScopeChainNode):
+        (WebInspector.ScopeChainNode.prototype.get type):
+        (WebInspector.ScopeChainNode.prototype.get objects):
+        (WebInspector.ScopeChainNode.prototype.get name):
+        (WebInspector.ScopeChainNode.prototype.get location):
+        (WebInspector.ScopeChainNode.prototype.get hash):
+        Hash is a rough (name:sourceId:line:column) string for quick comparisons.
+
+        (WebInspector.ScopeChainNode.prototype.makeLocalScope):
+        Make this an action you take on a scope, to avoid having to
+        do it at construction time, or making it a generic setting.
+
+        * UserInterface/Views/ScopeChainDetailsSidebarPanel.js:
+        (WebInspector.ScopeChainDetailsSidebarPanel.prototype._generateCallFramesSection):
+        This was wrong before. Move the work to CallFrame
+        and change it to be correct.
+
+        * UserInterface/CallFrame.js:
+        (WebInspector.CallFrame.prototype.mergedScopeChain):
+
+        This transforms the scope chain for a call frame from:
+        
+             scope1  scope2  scope3  scope4  scope5  scope6  scope7
+              foo     foo     foo     bar     bar      -       -
+             Block  Closure Closure Closure Closure   GLE     GBL
+
+        To:
+             scope1  scope2&amp;3   scope4&amp;5  scope6  scope7
+              foo      foo*       bar*      -       -
+             Block    Local     Closure    GLE     GBL
+
+        Doing a few things:
+
+            - Merge the first two Closure scopes sharing a location.
+              These are the &quot;var&quot; and &quot;let&quot; Closure scopes in a function,
+              and it is better to present these together in the UI.
+
+            - Mark the first Closure scope within a function (*). When
+              this is displayed in the UI, we can provide the name of
+              the function: &quot;Closure Scope (name)&quot;, and we even have
+              location information that we can use to display a goto
+              arrow if needed.
+
+            - Make the first Closure scope the Local scope if it
+              matches the Call Frame's function name. This lets us
+              display the section as &quot;Local Variables&quot;.
+
</ins><span class="cx"> 2016-06-29  Brian Burg  &lt;bburg@apple.com&gt;
</span><span class="cx"> 
</span><span class="cx">         Web Inspector: Uncaught Exception page never shows if exception is thrown while processing a protocol event
</span></span></pre></div>
<a id="trunkSourceWebInspectorUIUserInterfaceControllersDebuggerManagerjs"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebInspectorUI/UserInterface/Controllers/DebuggerManager.js (202658 => 202659)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebInspectorUI/UserInterface/Controllers/DebuggerManager.js        2016-06-29 23:28:16 UTC (rev 202658)
+++ trunk/Source/WebInspectorUI/UserInterface/Controllers/DebuggerManager.js        2016-06-29 23:59:35 UTC (rev 202659)
</span><span class="lines">@@ -662,7 +662,7 @@
</span><span class="cx">         }
</span><span class="cx"> 
</span><span class="cx">         var object = WebInspector.RemoteObject.fromPayload(payload.object);
</span><del>-        return new WebInspector.ScopeChainNode(type, [object]);
</del><ins>+        return new WebInspector.ScopeChainNode(type, [object], payload.name, payload.location);
</ins><span class="cx">     }
</span><span class="cx"> 
</span><span class="cx">     _pauseReasonFromPayload(payload)
</span></span></pre></div>
<a id="trunkSourceWebInspectorUIUserInterfaceModelsCallFramejs"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebInspectorUI/UserInterface/Models/CallFrame.js (202658 => 202659)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebInspectorUI/UserInterface/Models/CallFrame.js        2016-06-29 23:28:16 UTC (rev 202658)
+++ trunk/Source/WebInspectorUI/UserInterface/Models/CallFrame.js        2016-06-29 23:59:35 UTC (rev 202659)
</span><span class="lines">@@ -45,46 +45,15 @@
</span><span class="cx"> 
</span><span class="cx">     // Public
</span><span class="cx"> 
</span><del>-    get id()
-    {
-        return this._id;
-    }
</del><ins>+    get id() { return this._id; }
+    get sourceCodeLocation() { return this._sourceCodeLocation; }
+    get functionName() { return this._functionName; }
+    get nativeCode() { return this._nativeCode; }
+    get programCode() { return this._programCode; }
+    get thisObject() { return this._thisObject; }
+    get scopeChain() { return this._scopeChain; }
+    get isTailDeleted() { return this._isTailDeleted; }
</ins><span class="cx"> 
</span><del>-    get sourceCodeLocation()
-    {
-        return this._sourceCodeLocation;
-    }
-
-    get functionName()
-    {
-        return this._functionName;
-    }
-
-    get nativeCode()
-    {
-        return this._nativeCode;
-    }
-
-    get programCode()
-    {
-        return this._programCode;
-    }
-
-    get thisObject()
-    {
-        return this._thisObject;
-    }
-
-    get scopeChain()
-    {
-        return this._scopeChain;
-    }
-
-    get isTailDeleted()
-    {
-        return this._isTailDeleted;
-    }
-
</del><span class="cx">     saveIdentityToCookie()
</span><span class="cx">     {
</span><span class="cx">         // Do nothing. The call frame is torn down when the inspector closes, and
</span><span class="lines">@@ -112,6 +81,99 @@
</span><span class="cx">             this._scopeChain[i].objects[0].deprecatedGetAllProperties(propertiesCollected);
</span><span class="cx">     }
</span><span class="cx"> 
</span><ins>+    mergedScopeChain()
+    {
+        let mergedScopes = [];
+
+        // Scopes list goes from top/local (1) to bottom/global (5)
+        //   [scope1, scope2, scope3, scope4, scope5]
+        let scopes = this._scopeChain.slice();
+
+        // Merge similiar scopes. Some function call frames may have multiple
+        // top level closure scopes (one for `var`s one for `let`s) that can be
+        // combined to a single scope of variables. Go in reverse order so we
+        // merge the first two closure scopes with the same name. Also mark
+        // the first time we see a new name, so we know the base for the name.
+        //   [scope1&amp;2, scope3, scope4, scope5]
+        //      foo      bar     GLE    global
+        let lastMarkedHash = null;
+        function markAsBaseIfNeeded(scope) {
+            if (!scope.hash)
+                return false;
+            if (scope.type !== WebInspector.ScopeChainNode.Type.Closure)
+                return false;
+            if (scope.hash === lastMarkedHash)
+                return false;
+            lastMarkedHash = scope.hash;
+            scope.__baseClosureScope = true;
+            return true;
+        }
+
+        function shouldMergeClosureScopes(youngScope, oldScope, lastMerge) {
+            if (!youngScope || !oldScope)
+                return false;
+
+            // Don't merge unknown locations.
+            if (!youngScope.hash || !oldScope.hash)
+                return false;
+
+            // Only merge closure scopes.
+            if (youngScope.type !== WebInspector.ScopeChainNode.Type.Closure)
+                return false;
+            if (oldScope.type !== WebInspector.ScopeChainNode.Type.Closure)
+                return false;
+
+            // Don't merge if they are not the same.
+            if (youngScope.hash !== oldScope.hash)
+                return false;
+
+            // Don't merge if there was already a merge.
+            if (lastMerge &amp;&amp; youngScope.hash === lastMerge.hash)
+                return false;
+
+            return true;
+        }
+
+        let lastScope = null;
+        let lastMerge = null;
+        for (let i = scopes.length - 1; i &gt;= 0; --i) {
+            let scope = scopes[i];
+            markAsBaseIfNeeded(scope);
+            if (shouldMergeClosureScopes(scope, lastScope, lastMerge)) {
+                console.assert(lastScope.__baseClosureScope);
+                let type = WebInspector.ScopeChainNode.Type.Closure;
+                let objects = lastScope.objects.concat(scope.objects);
+                let merged = new WebInspector.ScopeChainNode(type, objects, scope.name, scope.location);
+                merged.__baseClosureScope = true;
+                console.assert(objects.length === 2);
+
+                mergedScopes.pop(); // Remove the last.
+                mergedScopes.push(merged); // Add the merged scope.
+
+                lastMerge = merged;
+                lastScope = null;
+            } else {
+                mergedScopes.push(scope);
+
+                lastMerge = null;
+                lastScope = scope;
+            }
+        }
+
+        mergedScopes = mergedScopes.reverse();
+
+        // Mark the first Closure as Local if the name matches this call frame.
+        for (let scope of mergedScopes) {
+            if (scope.type === WebInspector.ScopeChainNode.Type.Closure) {
+                if (scope.name === this._functionName)
+                    scope.convertToLocalScope();
+                break;
+            }
+        }
+
+        return mergedScopes;
+    }
+
</ins><span class="cx">     // Static
</span><span class="cx"> 
</span><span class="cx">     static functionNameFromPayload(payload)
</span></span></pre></div>
<a id="trunkSourceWebInspectorUIUserInterfaceModelsScopeChainNodejs"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebInspectorUI/UserInterface/Models/ScopeChainNode.js (202658 => 202659)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebInspectorUI/UserInterface/Models/ScopeChainNode.js        2016-06-29 23:28:16 UTC (rev 202658)
+++ trunk/Source/WebInspectorUI/UserInterface/Models/ScopeChainNode.js        2016-06-29 23:59:35 UTC (rev 202659)
</span><span class="lines">@@ -25,7 +25,7 @@
</span><span class="cx"> 
</span><span class="cx"> WebInspector.ScopeChainNode = class ScopeChainNode extends WebInspector.Object
</span><span class="cx"> {
</span><del>-    constructor(type, objects)
</del><ins>+    constructor(type, objects, name, location)
</ins><span class="cx">     {
</span><span class="cx">         super();
</span><span class="cx"> 
</span><span class="lines">@@ -37,18 +37,31 @@
</span><span class="cx"> 
</span><span class="cx">         this._type = type || null;
</span><span class="cx">         this._objects = objects || [];
</span><ins>+        this._name = name || &quot;&quot;;
+        this._location = location || null;
</ins><span class="cx">     }
</span><span class="cx"> 
</span><span class="cx">     // Public
</span><span class="cx"> 
</span><del>-    get type()
</del><ins>+    get type() { return this._type; }
+    get objects() { return this._objects; }
+    get name() { return this._name; }
+    get location() { return this._location; }
+
+    get hash()
</ins><span class="cx">     {
</span><del>-        return this._type;
</del><ins>+        if (this._hash)
+            return this._hash;
+
+        this._hash = this._name;
+        if (this._location)
+            this._hash += `:${this._location.scriptId}:${this._location.lineNumber}:${this._location.columnNumber}`;
+        return this._hash;
</ins><span class="cx">     }
</span><span class="cx"> 
</span><del>-    get objects()
</del><ins>+    convertToLocalScope()
</ins><span class="cx">     {
</span><del>-        return this._objects;
</del><ins>+        this._type = WebInspector.ScopeChainNode.Type.Local;
</ins><span class="cx">     }
</span><span class="cx"> };
</span><span class="cx"> 
</span></span></pre></div>
<a id="trunkSourceWebInspectorUIUserInterfaceViewsScopeChainDetailsSidebarPaneljs"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebInspectorUI/UserInterface/Views/ScopeChainDetailsSidebarPanel.js (202658 => 202659)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebInspectorUI/UserInterface/Views/ScopeChainDetailsSidebarPanel.js        2016-06-29 23:28:16 UTC (rev 202658)
+++ trunk/Source/WebInspectorUI/UserInterface/Views/ScopeChainDetailsSidebarPanel.js        2016-06-29 23:59:35 UTC (rev 202659)
</span><span class="lines">@@ -164,159 +164,92 @@
</span><span class="cx">         for (let type in WebInspector.ScopeChainNode.Type)
</span><span class="cx">             sectionCountByType.set(WebInspector.ScopeChainNode.Type[type], 0);
</span><span class="cx"> 
</span><del>-        // Scopes list goes from top/local (1) to bottom/global (5)
-        // Call frames list goes from top/local (1) to bottom/global (2)
-        //   [scope1, scope2, scope3, scope4, scope5]
-        //   [CallFrame1, CallFrame2]
-        let scopeChain = callFrame.scopeChain;
-        let callFrames = WebInspector.debuggerManager.callFrames;
</del><ins>+        let scopeChain = callFrame.mergedScopeChain();
+        for (let scope of scopeChain) {
+            let title = null;
+            let extraPropertyDescriptor = null;
+            let collapsedByDefault = false;
</ins><span class="cx"> 
</span><del>-        // Group scopes with the call frame containing them.
-        // Creating a map that looks like:
-        //   CallFrame2 =&gt; [scope5, scope4]
-        //   CallFrame1 =&gt; [scope3, scope2, scope1]
-        let reversedScopeChain = scopeChain.slice().reverse();
-        let callFrameScopes = new Map;
-        let lastLength = 0;
-        for (let i = callFrames.length - 1; i &gt;= 0; --i) {
-            let nextCallFrame = callFrames[i];
-            console.assert(nextCallFrame.scopeChain.length &gt; lastLength);
-            callFrameScopes.set(nextCallFrame, reversedScopeChain.slice(lastLength, nextCallFrame.scopeChain.length));
-            lastLength = nextCallFrame.scopeChain.length;
-            if (nextCallFrame === callFrame) {
-                console.assert(lastLength === scopeChain.length);
</del><ins>+            let count = sectionCountByType.get(scope.type);
+            sectionCountByType.set(scope.type, ++count);
+
+            switch (scope.type) {
+            case WebInspector.ScopeChainNode.Type.Local:
+                foundLocalScope = true;
+                collapsedByDefault = false;
+                title = WebInspector.UIString(&quot;Local Variables&quot;);
+                if (callFrame.thisObject)
+                    extraPropertyDescriptor = new WebInspector.PropertyDescriptor({name: &quot;this&quot;, value: callFrame.thisObject});
</ins><span class="cx">                 break;
</span><del>-            }
-        }
</del><span class="cx"> 
</span><del>-        // Now that we have this map we can merge some of the scopes within an individual
-        // call frame. In particular, function call frames may have multiple top level
-        // closure scopes (one for `var`s one for `let`s) that can be combined to a
-        // single scope of variables.
-        // This modifies the Map, resulting in:
-        //   CallFrame2 =&gt; [scope4, scope5]
-        //   CallFrame1 =&gt; [scope1, scope2&amp;3]
-        for (let [currentCallFrame, scopes] of callFrameScopes) {
-            let firstClosureScope = null;
-            for (let scope of scopes) {
-                // Reached a non-closure scope. Bail.
-                let isClosureScope = scope.type === WebInspector.ScopeChainNode.Type.Closure;
-                if (!isClosureScope &amp;&amp; firstClosureScope)
-                    break;
</del><ins>+            case WebInspector.ScopeChainNode.Type.Closure:
+                if (scope.__baseClosureScope &amp;&amp; scope.name)
+                    title = WebInspector.UIString(&quot;Closure Variables (%s)&quot;).format(scope.name);
+                else
+                    title = WebInspector.UIString(&quot;Closure Variables&quot;);
+                collapsedByDefault = false;
+                break;
</ins><span class="cx"> 
</span><del>-                // Found first closure scope. Mark it so we can provide the function name later in the UI.
-                if (isClosureScope &amp;&amp; !firstClosureScope) {
-                    firstClosureScope = scope;
-                    firstClosureScope[WebInspector.ScopeChainDetailsSidebarPanel.CallFrameBaseClosureScopeSymbol] = true;
-                    continue;
-                }
</del><ins>+            case WebInspector.ScopeChainNode.Type.Block:
+                title = WebInspector.UIString(&quot;Block Variables&quot;);
+                collapsedByDefault = false;
+                break;
</ins><span class="cx"> 
</span><del>-                // Found 2 sequential top level closure scopes. Merge and mark it so we can provide the function name later in the UI.
-                if (isClosureScope &amp;&amp; firstClosureScope) {
-                    let type = currentCallFrame === callFrame ? WebInspector.ScopeChainNode.Type.Local : WebInspector.ScopeChainNode.Type.Closure;
-                    let objects = firstClosureScope.objects.concat(scope.objects);
-                    let merged = new WebInspector.ScopeChainNode(type, objects);
-                    merged[WebInspector.ScopeChainDetailsSidebarPanel.CallFrameBaseClosureScopeSymbol] = true;
-                    console.assert(objects.length === 2);
</del><ins>+            case WebInspector.ScopeChainNode.Type.Catch:
+                title = WebInspector.UIString(&quot;Catch Variables&quot;);
+                collapsedByDefault = false;
+                break;
</ins><span class="cx"> 
</span><del>-                    let index = scopes.indexOf(firstClosureScope);
-                    scopes.splice(index, 1); // Remove one of them.
-                    scopes[index] = merged; // Replace the remaining with the merged.
-                    break;
-                }
-            }
-            scopes.reverse();
-        }
</del><ins>+            case WebInspector.ScopeChainNode.Type.FunctionName:
+                title = WebInspector.UIString(&quot;Function Name Variable&quot;);
+                collapsedByDefault = true;
+                break;
</ins><span class="cx"> 
</span><del>-        // Now we can walk the list of call frames and their scopes.
-        // We walk in top -&gt; down order:
-        //   CallFrame1 =&gt; [scope1, scope2&amp;3]
-        //   CallFrame2 =&gt; [scope5, scope4]
-        for (let [call, scopes] of [...callFrameScopes.entries()].reverse()) {
-            for (let scope of scopes) {
-                let title = null;
-                let extraPropertyDescriptor = null;
-                let collapsedByDefault = false;
</del><ins>+            case WebInspector.ScopeChainNode.Type.With:
+                title = WebInspector.UIString(&quot;With Object Properties&quot;);
+                collapsedByDefault = foundLocalScope;
+                break;
</ins><span class="cx"> 
</span><del>-                let count = sectionCountByType.get(scope.type);
-                sectionCountByType.set(scope.type, ++count);
</del><ins>+            case WebInspector.ScopeChainNode.Type.Global:
+                title = WebInspector.UIString(&quot;Global Variables&quot;);
+                collapsedByDefault = true;
+                break;
</ins><span class="cx"> 
</span><del>-                switch (scope.type) {
-                    case WebInspector.ScopeChainNode.Type.Local:
-                        foundLocalScope = true;
-                        collapsedByDefault = false;
-                        title = WebInspector.UIString(&quot;Local Variables&quot;);
-                        if (call.thisObject)
-                            extraPropertyDescriptor = new WebInspector.PropertyDescriptor({name: &quot;this&quot;, value: call.thisObject});
-                        break;
</del><ins>+            case WebInspector.ScopeChainNode.Type.GlobalLexicalEnvironment:
+                title = WebInspector.UIString(&quot;Global Lexical Environment&quot;);
+                collapsedByDefault = true;
+                break;
+            }
</ins><span class="cx"> 
</span><del>-                    case WebInspector.ScopeChainNode.Type.Closure:
-                        if (scope[WebInspector.ScopeChainDetailsSidebarPanel.CallFrameBaseClosureScopeSymbol] &amp;&amp; call.functionName)
-                            title = WebInspector.UIString(&quot;Closure Variables (%s)&quot;).format(call.functionName);
-                        else
-                            title = WebInspector.UIString(&quot;Closure Variables&quot;);
-                        collapsedByDefault = false;
-                        break;
</del><ins>+            let detailsSectionIdentifier = scope.type + &quot;-&quot; + sectionCountByType.get(scope.type);
</ins><span class="cx"> 
</span><del>-                    case WebInspector.ScopeChainNode.Type.Block:
-                        title = WebInspector.UIString(&quot;Block Variables&quot;);
-                        collapsedByDefault = false;
-                        break;
</del><ins>+            // FIXME: This just puts two ObjectTreeViews next to each other, but that means
+            // that properties are not nicely sorted between the two separate lists.
</ins><span class="cx"> 
</span><del>-                    case WebInspector.ScopeChainNode.Type.Catch:
-                        title = WebInspector.UIString(&quot;Catch Variables&quot;);
-                        collapsedByDefault = false;
-                        break;
</del><ins>+            let rows = [];
+            for (let object of scope.objects) {
+                let scopePropertyPath = WebInspector.PropertyPath.emptyPropertyPathForScope(object);
+                let objectTree = new WebInspector.ObjectTreeView(object, WebInspector.ObjectTreeView.Mode.Properties, scopePropertyPath);
</ins><span class="cx"> 
</span><del>-                    case WebInspector.ScopeChainNode.Type.FunctionName:
-                        title = WebInspector.UIString(&quot;Function Name Variable&quot;);
-                        collapsedByDefault = true;
-                        break;
</del><ins>+                objectTree.showOnlyProperties();
</ins><span class="cx"> 
</span><del>-                    case WebInspector.ScopeChainNode.Type.With:
-                        title = WebInspector.UIString(&quot;With Object Properties&quot;);
-                        collapsedByDefault = foundLocalScope;
-                        break;
-
-                    case WebInspector.ScopeChainNode.Type.Global:
-                        title = WebInspector.UIString(&quot;Global Variables&quot;);
-                        collapsedByDefault = true;
-                        break;
-
-                    case WebInspector.ScopeChainNode.Type.GlobalLexicalEnvironment:
-                        title = WebInspector.UIString(&quot;Global Lexical Environment&quot;);
-                        collapsedByDefault = true;
-                        break;
</del><ins>+                if (extraPropertyDescriptor) {
+                    objectTree.appendExtraPropertyDescriptor(extraPropertyDescriptor);
+                    extraPropertyDescriptor = null;
</ins><span class="cx">                 }
</span><span class="cx"> 
</span><del>-                let detailsSectionIdentifier = scope.type + &quot;-&quot; + sectionCountByType.get(scope.type);
</del><ins>+                let treeOutline = objectTree.treeOutline;
+                treeOutline.addEventListener(WebInspector.TreeOutline.Event.ElementAdded, this._treeElementAdded.bind(this, detailsSectionIdentifier), this);
+                treeOutline.addEventListener(WebInspector.TreeOutline.Event.ElementDisclosureDidChanged, this._treeElementDisclosureDidChange.bind(this, detailsSectionIdentifier), this);
</ins><span class="cx"> 
</span><del>-                // FIXME: This just puts two ObjectTreeViews next to eachother, but that means
-                // that properties are not nicely sorted between the two separate lists.
</del><ins>+                // FIXME: &lt;https://webkit.org/b/140567&gt; Web Inspector: Do not request Scope Chain lists if section is collapsed (mainly Global Variables)
+                // This autoexpands the ObjectTreeView and fetches all properties. Should wait to see if we are collapsed or not.
+                rows.push(new WebInspector.DetailsSectionPropertiesRow(objectTree));
+            }
</ins><span class="cx"> 
</span><del>-                let rows = [];
-                for (let object of scope.objects) {
-                    let scopePropertyPath = WebInspector.PropertyPath.emptyPropertyPathForScope(object);
-                    let objectTree = new WebInspector.ObjectTreeView(object, WebInspector.ObjectTreeView.Mode.Properties, scopePropertyPath);
-
-                    objectTree.showOnlyProperties();
-
-                    if (extraPropertyDescriptor) {
-                        objectTree.appendExtraPropertyDescriptor(extraPropertyDescriptor);
-                        extraPropertyDescriptor = null;
-                    }
-
-                    let treeOutline = objectTree.treeOutline;
-                    treeOutline.addEventListener(WebInspector.TreeOutline.Event.ElementAdded, this._treeElementAdded.bind(this, detailsSectionIdentifier), this);
-                    treeOutline.addEventListener(WebInspector.TreeOutline.Event.ElementDisclosureDidChanged, this._treeElementDisclosureDidChange.bind(this, detailsSectionIdentifier), this);
-
-                    rows.push(new WebInspector.DetailsSectionPropertiesRow(objectTree));
-                }
-
-                let detailsSection = new WebInspector.DetailsSection(detailsSectionIdentifier, title, null, null, collapsedByDefault);
-                detailsSection.groups[0].rows = rows;
-                detailsSections.push(detailsSection);
-            }
</del><ins>+            let detailsSection = new WebInspector.DetailsSection(detailsSectionIdentifier, title, null, null, collapsedByDefault);
+            detailsSection.groups[0].rows = rows;
+            detailsSections.push(detailsSection);
</ins><span class="cx">         }
</span><span class="cx"> 
</span><span class="cx">         return Promise.resolve(detailsSections);
</span><span class="lines">@@ -545,4 +478,3 @@
</span><span class="cx"> 
</span><span class="cx"> WebInspector.ScopeChainDetailsSidebarPanel._autoExpandProperties = new Set;
</span><span class="cx"> WebInspector.ScopeChainDetailsSidebarPanel.WatchExpressionsObjectGroupName = &quot;watch-expressions&quot;;
</span><del>-WebInspector.ScopeChainDetailsSidebarPanel.CallFrameBaseClosureScopeSymbol = Symbol(&quot;scope-chain-call-frame-base-closure-scope&quot;);
</del></span></pre>
</div>
</div>

</body>
</html>