Diff
Modified: trunk/LayoutTests/ChangeLog (202716 => 202717)
--- trunk/LayoutTests/ChangeLog 2016-06-30 23:12:03 UTC (rev 202716)
+++ trunk/LayoutTests/ChangeLog 2016-06-30 23:24:58 UTC (rev 202717)
@@ -1,3 +1,22 @@
+2016-06-30 Joseph Pecoraro <pecor...@apple.com>
+
+ Web Inspector: Wrong function name next to scope
+ https://bugs.webkit.org/show_bug.cgi?id=158210
+ <rdar://problem/26543093>
+
+ Reviewed by Timothy Hatcher.
+
+ * 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.
+
+ * inspector/model/scope-chain-node.html:
+ Make the test more stable on debug builds which run slower.
+
2016-06-30 Antoine Quint <grao...@apple.com>
Drawing an SVG image into a <canvas> that is not in the DOM draws the wrong region
Added: trunk/LayoutTests/inspector/debugger/paused-scopes-expected.txt (0 => 202717)
--- trunk/LayoutTests/inspector/debugger/paused-scopes-expected.txt (rev 0)
+++ trunk/LayoutTests/inspector/debugger/paused-scopes-expected.txt 2016-06-30 23:24:58 UTC (rev 202717)
@@ -0,0 +1,205 @@
+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:<sourceID>:21:29)
+ - barLexicalVariable2
+ SCOPE: Name (firstPause) - Type (Closure) - Hash (firstPause:<sourceID>:21:29)
+ - barLexicalVariable2
+ SCOPE: Name (firstPause) - Type (Closure) - Hash (firstPause:<sourceID>:21:29)
+ - barVarVariable1
+ SCOPE: Name (firstPause) - Type (FunctionName) - Hash (firstPause:<sourceID>:21:29)
+ - firstPause
+ SCOPE: Name (firstPause) - Type (Closure) - Hash (firstPause:<sourceID>:19:24)
+ - fakeFirstPauseLexicalVariable
+ SCOPE: Name (firstPause) - Type (Closure) - Hash (firstPause:<sourceID>:19:24)
+ SCOPE: Name (entry) - Type (Closure) - Hash (entry:<sourceID>:14:15)
+ - fooLexicalVariable2
+ SCOPE: Name (entry) - Type (Closure) - Hash (entry:<sourceID>: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:<sourceID>:21:29)
+ - barLexicalVariable2
+ SCOPE: Name (firstPause) - Type (Local) - Hash (firstPause:<sourceID>:21:29)
+ - barVarVariable1
+ - barLexicalVariable2
+ SCOPE: Name (firstPause) - Type (FunctionName) - Hash (firstPause:<sourceID>:21:29)
+ - firstPause
+ SCOPE: Name (firstPause) - Type (Closure) - Hash (firstPause:<sourceID>:19:24)
+ - fakeFirstPauseLexicalVariable
+ SCOPE: Name (entry) - Type (Closure) - Hash (entry:<sourceID>: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:<sourceID>:19:24)
+ - fakeFirstPauseLexicalVariable
+ SCOPE: Name (firstPause) - Type (Closure) - Hash (firstPause:<sourceID>:19:24)
+ SCOPE: Name (entry) - Type (Closure) - Hash (entry:<sourceID>:14:15)
+ - fooLexicalVariable2
+ SCOPE: Name (entry) - Type (Closure) - Hash (entry:<sourceID>: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:<sourceID>:19:24)
+ - fakeFirstPauseLexicalVariable
+ SCOPE: Name (entry) - Type (Closure) - Hash (entry:<sourceID>: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:<sourceID>:14:15)
+ - fooLexicalVariable2
+ SCOPE: Name (entry) - Type (Closure) - Hash (entry:<sourceID>: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:<sourceID>: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:<sourceID>:6:21)
+ - blockLexicalVariable
+ SCOPE: Name (secondPause) - Type (Closure) - Hash (secondPause:<sourceID>:6:21)
+ - shoeLexicalVariable1
+ SCOPE: Name (secondPause) - Type (Closure) - Hash (secondPause:<sourceID>:6:21)
+ SCOPE: Name () - Type (GlobalLexicalEnvironment) - Hash ()
+ - globalLet2
+ SCOPE: Name () - Type (Global) - Hash ()
+
+---- Merged Scope Chain ----
+ SCOPE: Name (secondPause) - Type (Block) - Hash (secondPause:<sourceID>:6:21)
+ - blockLexicalVariable
+ SCOPE: Name (secondPause) - Type (Local) - Hash (secondPause:<sourceID>: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:<sourceID>:21:29)
+ - barLexicalVariable2
+ SCOPE: Name (firstPause) - Type (Closure) - Hash (firstPause:<sourceID>:21:29)
+ - barLexicalVariable2
+ SCOPE: Name (firstPause) - Type (Closure) - Hash (firstPause:<sourceID>:21:29)
+ - barVarVariable1
+ SCOPE: Name (firstPause) - Type (FunctionName) - Hash (firstPause:<sourceID>:21:29)
+ - firstPause
+ SCOPE: Name (firstPause) - Type (Closure) - Hash (firstPause:<sourceID>:19:24)
+ - fakeFirstPauseLexicalVariable
+ SCOPE: Name (firstPause) - Type (Closure) - Hash (firstPause:<sourceID>:19:24)
+ SCOPE: Name (entry) - Type (Closure) - Hash (entry:<sourceID>:14:15)
+ - fooLexicalVariable2
+ SCOPE: Name (entry) - Type (Closure) - Hash (entry:<sourceID>: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:<sourceID>:21:29)
+ - barLexicalVariable2
+ SCOPE: Name (firstPause) - Type (Local) - Hash (firstPause:<sourceID>:21:29)
+ - barVarVariable1
+ - barLexicalVariable2
+ SCOPE: Name (firstPause) - Type (FunctionName) - Hash (firstPause:<sourceID>:21:29)
+ - firstPause
+ SCOPE: Name (firstPause) - Type (Closure) - Hash (firstPause:<sourceID>:19:24)
+ - fakeFirstPauseLexicalVariable
+ SCOPE: Name (entry) - Type (Closure) - Hash (entry:<sourceID>: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:<sourceID>:19:24)
+ - fakeFirstPauseLexicalVariable
+ SCOPE: Name (firstPause) - Type (Closure) - Hash (firstPause:<sourceID>:19:24)
+ SCOPE: Name (entry) - Type (Closure) - Hash (entry:<sourceID>:14:15)
+ - fooLexicalVariable2
+ SCOPE: Name (entry) - Type (Closure) - Hash (entry:<sourceID>: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:<sourceID>:19:24)
+ - fakeFirstPauseLexicalVariable
+ SCOPE: Name (entry) - Type (Closure) - Hash (entry:<sourceID>: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:<sourceID>:14:15)
+ - fooLexicalVariable2
+ SCOPE: Name (entry) - Type (Closure) - Hash (entry:<sourceID>: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:<sourceID>:14:15)
+ - firstPause
+ - fooVarVariable1
+ - fooLexicalVariable2
+ SCOPE: Name () - Type (GlobalLexicalEnvironment) - Hash ()
+ - globalLet2
+ SCOPE: Name () - Type (Global) - Hash ()
+
+
Added: trunk/LayoutTests/inspector/debugger/resources/paused-scopes.js (0 => 202717)
--- trunk/LayoutTests/inspector/debugger/resources/paused-scopes.js (rev 0)
+++ trunk/LayoutTests/inspector/debugger/resources/paused-scopes.js 2016-06-30 23:24:58 UTC (rev 202717)
@@ -0,0 +1,31 @@
+"use strict";
+
+var globalVar1; // Global (globalVar1)
+let globalLet2; // GlobalLexicalEnvironment (globalLet2)
+
+function secondPause() { // Global (secondPause)
+ let shoeLexicalVariable1 = document; // ClosureScope (shoeLexicalVariable1)
+ if (true) {
+ let blockLexicalVariable = "block"; // 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();
+ }
+ })();
+ }
+}
Modified: trunk/LayoutTests/inspector/model/scope-chain-node.html (202716 => 202717)
--- trunk/LayoutTests/inspector/model/scope-chain-node.html 2016-06-30 23:12:03 UTC (rev 202716)
+++ trunk/LayoutTests/inspector/model/scope-chain-node.html 2016-06-30 23:24:58 UTC (rev 202717)
@@ -66,7 +66,9 @@
InspectorTest.expectThat(scopeChain.length === 13, "ScopeChain should have 13 scopes.");
logScopeChain(scopeChain).then((result) => {
WebInspector.debuggerManager.resume();
- resolve();
+ WebInspector.debuggerManager.singleFireEventListener(WebInspector.DebuggerManager.Event.Resumed, (event) => {
+ resolve();
+ });
});
});
}
@@ -81,7 +83,9 @@
let scopeChain = WebInspector.debuggerManager.activeCallFrame.scopeChain;
logScopeChain(scopeChain).then((result) => {
WebInspector.debuggerManager.resume();
- resolve();
+ WebInspector.debuggerManager.singleFireEventListener(WebInspector.DebuggerManager.Event.Resumed, (event) => {
+ resolve();
+ });
});
});
}
@@ -96,7 +100,9 @@
let scopeChain = WebInspector.debuggerManager.activeCallFrame.scopeChain;
logScopeChain(scopeChain).then((result) => {
WebInspector.debuggerManager.resume();
- resolve();
+ WebInspector.debuggerManager.singleFireEventListener(WebInspector.DebuggerManager.Event.Resumed, (event) => {
+ resolve();
+ });
});
});
}
@@ -112,7 +118,10 @@
let pauseCount = 0;
let pauseEventsExpected = 19;
function callFramesDidChangeListener(event) {
- pauseCount++;
+ if (!WebInspector.debuggerManager.activeCallFrame)
+ return;
+
+ pauseCount++;
let scopeChain = WebInspector.debuggerManager.activeCallFrame.scopeChain;
// First, normal function scope.
Modified: trunk/Source/_javascript_Core/CMakeLists.txt (202716 => 202717)
--- trunk/Source/_javascript_Core/CMakeLists.txt 2016-06-30 23:12:03 UTC (rev 202716)
+++ trunk/Source/_javascript_Core/CMakeLists.txt 2016-06-30 23:24:58 UTC (rev 202717)
@@ -239,6 +239,7 @@
debugger/Debugger.cpp
debugger/DebuggerCallFrame.cpp
+ debugger/DebuggerLocation.cpp
debugger/DebuggerScope.cpp
dfg/DFGAbstractHeap.cpp
Modified: trunk/Source/_javascript_Core/ChangeLog (202716 => 202717)
--- trunk/Source/_javascript_Core/ChangeLog 2016-06-30 23:12:03 UTC (rev 202716)
+++ trunk/Source/_javascript_Core/ChangeLog 2016-06-30 23:24:58 UTC (rev 202717)
@@ -1,3 +1,79 @@
+2016-06-30 Joseph Pecoraro <pecor...@apple.com>
+
+ Web Inspector: Wrong function name next to scope
+ https://bugs.webkit.org/show_bug.cgi?id=158210
+ <rdar://problem/26543093>
+
+ Reviewed by Timothy Hatcher.
+
+ * CMakeLists.txt:
+ * _javascript_Core.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.
+
+ * runtime/JSSymbolTableObject.h:
+ * runtime/JSSymbolTableObject.cpp:
+ (JSC::JSSymbolTableObject::deleteProperty):
+ (JSC::JSSymbolTableObject::getOwnNonIndexPropertyNames):
+ Give JSSymbolTable its own class info. JSWithScope was unexpectedly
+ inheriting from JSSymbolTable since it did not have its own and
+ was using JSScope's class info. Also do a bit of cleanup.
+
+ * 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 -> SymbolTable -> CodeBlock -> 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.
+
2016-06-30 Saam Barati <sbar...@apple.com>
missing exception checks in arrayProtoFuncReverse
Modified: trunk/Source/_javascript_Core/_javascript_Core.xcodeproj/project.pbxproj (202716 => 202717)
--- trunk/Source/_javascript_Core/_javascript_Core.xcodeproj/project.pbxproj 2016-06-30 23:12:03 UTC (rev 202716)
+++ trunk/Source/_javascript_Core/_javascript_Core.xcodeproj/project.pbxproj 2016-06-30 23:24:58 UTC (rev 202717)
@@ -1645,6 +1645,8 @@
A5EF9B171A1D440300702E90 /* generate_cpp_frontend_dispatcher_implementation.py in Headers */ = {isa = PBXBuildFile; fileRef = C4F4B6D41A05C76F005CAB76 /* generate_cpp_frontend_dispatcher_implementation.py */; settings = {ATTRIBUTES = (Private, ); }; };
A5EF9B181A1D440600702E90 /* generate_cpp_protocol_types_header.py in Headers */ = {isa = PBXBuildFile; fileRef = C4F4B6D51A05C76F005CAB76 /* generate_cpp_protocol_types_header.py */; settings = {ATTRIBUTES = (Private, ); }; };
A5EF9B191A1D440700702E90 /* generate_cpp_protocol_types_implementation.py in Headers */ = {isa = PBXBuildFile; fileRef = C4F4B6D61A05C76F005CAB76 /* generate_cpp_protocol_types_implementation.py */; settings = {ATTRIBUTES = (Private, ); }; };
+ A5FC84B21D1DDAD6006B5C46 /* DebuggerLocation.h in Headers */ = {isa = PBXBuildFile; fileRef = A5FC84B11D1DDAC8006B5C46 /* DebuggerLocation.h */; };
+ A5FC84B31D1DDAD9006B5C46 /* DebuggerLocation.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A5FC84B01D1DDAC8006B5C46 /* DebuggerLocation.cpp */; };
A5FD0067189AFE9C00633231 /* ScriptArguments.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A5FD0065189AFE9C00633231 /* ScriptArguments.cpp */; };
A5FD0068189AFE9C00633231 /* ScriptArguments.h in Headers */ = {isa = PBXBuildFile; fileRef = A5FD0066189AFE9C00633231 /* ScriptArguments.h */; settings = {ATTRIBUTES = (Private, ); }; };
A5FD006D189B00AA00633231 /* ScriptCallFrame.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A5FD0069189B00A900633231 /* ScriptCallFrame.cpp */; };
@@ -3867,6 +3869,8 @@
A5EA70F619F6DE5A0098F5EC /* generate_objc_internal_header.py */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.script.python; path = generate_objc_internal_header.py; sourceTree = "<group>"; };
A5EA70F819F6DE5A0098F5EC /* objc_generator.py */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.script.python; path = objc_generator.py; sourceTree = "<group>"; };
A5EA710D19F6DF810098F5EC /* InspectorAlternateBackendDispatchers.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = InspectorAlternateBackendDispatchers.h; sourceTree = "<group>"; };
+ A5FC84B01D1DDAC8006B5C46 /* DebuggerLocation.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = DebuggerLocation.cpp; sourceTree = "<group>"; };
+ A5FC84B11D1DDAC8006B5C46 /* DebuggerLocation.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DebuggerLocation.h; sourceTree = "<group>"; };
A5FD0065189AFE9C00633231 /* ScriptArguments.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ScriptArguments.cpp; sourceTree = "<group>"; };
A5FD0066189AFE9C00633231 /* ScriptArguments.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ScriptArguments.h; sourceTree = "<group>"; };
A5FD0069189B00A900633231 /* ScriptCallFrame.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ScriptCallFrame.cpp; sourceTree = "<group>"; };
@@ -5344,6 +5348,8 @@
149559ED0DDCDDF700648087 /* DebuggerCallFrame.cpp */,
1480DB9B0DDC227F003CFDF2 /* DebuggerCallFrame.h */,
6AD2CB4C19B9140100065719 /* DebuggerEvalEnabler.h */,
+ A5FC84B01D1DDAC8006B5C46 /* DebuggerLocation.cpp */,
+ A5FC84B11D1DDAC8006B5C46 /* DebuggerLocation.h */,
FEA0861F182B7A0400F6D851 /* DebuggerPrimitives.h */,
0F2D4DDB19832D34007D4B19 /* DebuggerScope.cpp */,
0F2D4DDC19832D34007D4B19 /* DebuggerScope.h */,
@@ -7695,6 +7701,7 @@
996B731C1BDA08DD00331B84 /* JSDataViewPrototype.lut.h in Headers */,
978801411471AD920041B016 /* JSDateMath.h in Headers */,
C2A7F688160432D400F76B98 /* JSDestructibleObject.h in Headers */,
+ A5FC84B21D1DDAD6006B5C46 /* DebuggerLocation.h in Headers */,
FE384EE61ADDB7AD0055DE2C /* JSDollarVM.h in Headers */,
FE384EE81ADDB7AD0055DE2C /* JSDollarVMPrototype.h in Headers */,
BC18C42D0E16F5CD00B34460 /* JSEnvironmentRecord.h in Headers */,
@@ -8774,6 +8781,7 @@
A57D23F11891B5B40031C7FA /* ContentSearchUtilities.cpp in Sources */,
52B717B51A0597E1007AF4F3 /* ControlFlowProfiler.cpp in Sources */,
0FBADF541BD1F4B800E073C1 /* CopiedBlock.cpp in Sources */,
+ A5FC84B31D1DDAD9006B5C46 /* DebuggerLocation.cpp in Sources */,
C240305514B404E60079EB64 /* CopiedSpace.cpp in Sources */,
0F6183301C45BF070072450B /* AirLowerMacros.cpp in Sources */,
C2239D1716262BDD005AC5FD /* CopyVisitor.cpp in Sources */,
Modified: trunk/Source/_javascript_Core/bytecode/CodeBlock.cpp (202716 => 202717)
--- trunk/Source/_javascript_Core/bytecode/CodeBlock.cpp 2016-06-30 23:12:03 UTC (rev 202716)
+++ trunk/Source/_javascript_Core/bytecode/CodeBlock.cpp 2016-06-30 23:24:58 UTC (rev 202717)
@@ -2483,7 +2483,12 @@
ConcurrentJITLocker locker(symbolTable->m_lock);
symbolTable->prepareForTypeProfiling(locker);
}
- constant = symbolTable->cloneScopePart(*m_vm);
+
+ SymbolTable* clone = symbolTable->cloneScopePart(*m_vm);
+ if (wasCompiledWithDebuggingOpcodes())
+ clone->setRareDataCodeBlock(this);
+
+ constant = clone;
}
}
Added: trunk/Source/_javascript_Core/debugger/DebuggerLocation.cpp (0 => 202717)
--- trunk/Source/_javascript_Core/debugger/DebuggerLocation.cpp (rev 0)
+++ trunk/Source/_javascript_Core/debugger/DebuggerLocation.cpp 2016-06-30 23:24:58 UTC (rev 202717)
@@ -0,0 +1,46 @@
+/*
+ * 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 "config.h"
+#include "DebuggerLocation.h"
+
+#include "Executable.h"
+
+namespace JSC {
+
+DebuggerLocation::DebuggerLocation(ScriptExecutable* executable)
+{
+ if (executable->isHostFunction())
+ return;
+
+ sourceID = executable->sourceID();
+ line = executable->firstLine();
+ column = executable->startColumn();
+ url = ""
+ if (url.isEmpty())
+ url = ""
+}
+
+} // namespace JSC
Added: trunk/Source/_javascript_Core/debugger/DebuggerLocation.h (0 => 202717)
--- trunk/Source/_javascript_Core/debugger/DebuggerLocation.h (rev 0)
+++ trunk/Source/_javascript_Core/debugger/DebuggerLocation.h 2016-06-30 23:24:58 UTC (rev 202717)
@@ -0,0 +1,53 @@
+/*
+ * 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 "DebuggerPrimitives.h"
+#include <wtf/text/WTFString.h>
+
+namespace JSC {
+
+class ScriptExecutable;
+
+struct DebuggerLocation {
+
+ DebuggerLocation() { }
+ DebuggerLocation(const String& 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
Modified: trunk/Source/_javascript_Core/debugger/DebuggerScope.cpp (202716 => 202717)
--- trunk/Source/_javascript_Core/debugger/DebuggerScope.cpp 2016-06-30 23:12:03 UTC (rev 202716)
+++ trunk/Source/_javascript_Core/debugger/DebuggerScope.cpp 2016-06-30 23:24:58 UTC (rev 202717)
@@ -210,6 +210,33 @@
return m_scope->isNestedLexicalScope();
}
+String DebuggerScope::name() const
+{
+ SymbolTable* symbolTable = m_scope->symbolTable();
+ if (!symbolTable)
+ return String();
+
+ CodeBlock* codeBlock = symbolTable->rareDataCodeBlock();
+ if (!codeBlock)
+ return String();
+
+ return String::fromUTF8(codeBlock->inferredName());
+}
+
+DebuggerLocation DebuggerScope::location() const
+{
+ SymbolTable* symbolTable = m_scope->symbolTable();
+ if (!symbolTable)
+ return DebuggerLocation();
+
+ CodeBlock* codeBlock = symbolTable->rareDataCodeBlock();
+ if (!codeBlock)
+ return DebuggerLocation();
+
+ ScriptExecutable* executable = codeBlock->ownerScriptExecutable();
+ return DebuggerLocation(executable);
+}
+
JSValue DebuggerScope::caughtValue(ExecState* exec) const
{
ASSERT(isCatchScope());
Modified: trunk/Source/_javascript_Core/debugger/DebuggerScope.h (202716 => 202717)
--- trunk/Source/_javascript_Core/debugger/DebuggerScope.h 2016-06-30 23:12:03 UTC (rev 202716)
+++ trunk/Source/_javascript_Core/debugger/DebuggerScope.h 2016-06-30 23:24:58 UTC (rev 202717)
@@ -26,6 +26,7 @@
#ifndef DebuggerScope_h
#define DebuggerScope_h
+#include "DebuggerLocation.h"
#include "JSObject.h"
namespace JSC {
@@ -88,6 +89,9 @@
bool isGlobalLexicalEnvironment() const;
bool isNestedLexicalScope() const;
+ String name() const;
+ DebuggerLocation location() const;
+
JSValue caughtValue(ExecState*) const;
private:
Modified: trunk/Source/_javascript_Core/inspector/InjectedScriptSource.js (202716 => 202717)
--- trunk/Source/_javascript_Core/inspector/InjectedScriptSource.js 2016-06-30 23:12:03 UTC (rev 202716)
+++ trunk/Source/_javascript_Core/inspector/InjectedScriptSource.js 2016-06-30 23:24:58 UTC (rev 202717)
@@ -1304,9 +1304,11 @@
_wrapScopeChain: function(callFrame)
{
var scopeChain = callFrame.scopeChain;
+ var scopeDescriptions = callFrame.scopeDescriptions();
+
var scopeChainProxy = [];
for (var i = 0; i < scopeChain.length; i++)
- scopeChainProxy[i] = InjectedScript.CallFrameProxy._createScopeJson(callFrame.scopeType(i), scopeChain[i], "backtrace");
+ scopeChainProxy[i] = InjectedScript.CallFrameProxy._createScopeJson(scopeChain[i], scopeDescriptions[i], "backtrace");
return scopeChainProxy;
}
}
@@ -1319,14 +1321,21 @@
4: "functionName", // FUNCTION_NAME_SCOPE
5: "globalLexicalEnvironment", // GLOBAL_LEXICAL_ENVIRONMENT_SCOPE
6: "nestedLexical", // NESTED_LEXICAL_SCOPE
-}
+};
-InjectedScript.CallFrameProxy._createScopeJson = function(scopeTypeCode, scopeObject, groupId)
+InjectedScript.CallFrameProxy._createScopeJson = function(object, {name, type, location}, groupId)
{
- return {
- object: injectedScript._wrapObject(scopeObject, groupId),
- type: InjectedScript.CallFrameProxy._scopeTypeNames[scopeTypeCode]
+ var scope = {
+ object: injectedScript._wrapObject(object, groupId),
+ type: InjectedScript.CallFrameProxy._scopeTypeNames[type],
};
+
+ if (name)
+ scope.name = name;
+ if (location)
+ scope.location = location;
+
+ return scope;
}
Modified: trunk/Source/_javascript_Core/inspector/JSJavaScriptCallFrame.cpp (202716 => 202717)
--- trunk/Source/_javascript_Core/inspector/JSJavaScriptCallFrame.cpp 2016-06-30 23:12:03 UTC (rev 202716)
+++ trunk/Source/_javascript_Core/inspector/JSJavaScriptCallFrame.cpp 2016-06-30 23:24:58 UTC (rev 202717)
@@ -28,9 +28,11 @@
#include "DebuggerScope.h"
#include "Error.h"
+#include "IdentifierInlines.h"
#include "JSCJSValue.h"
#include "JSCellInlines.h"
#include "JSJavaScriptCallFramePrototype.h"
+#include "ObjectConstructor.h"
#include "StructureInlines.h"
using namespace JSC;
@@ -92,45 +94,58 @@
return result;
}
-JSValue JSJavaScriptCallFrame::scopeType(ExecState* exec)
+static JSValue valueForScopeType(DebuggerScope* scope)
{
- if (!impl().scopeChain())
- return jsUndefined();
+ if (scope->isCatchScope())
+ return jsNumber(JSJavaScriptCallFrame::CATCH_SCOPE);
+ if (scope->isFunctionNameScope())
+ return jsNumber(JSJavaScriptCallFrame::FUNCTION_NAME_SCOPE);
+ if (scope->isWithScope())
+ return jsNumber(JSJavaScriptCallFrame::WITH_SCOPE);
+ if (scope->isNestedLexicalScope())
+ return jsNumber(JSJavaScriptCallFrame::NESTED_LEXICAL_SCOPE);
+ if (scope->isGlobalLexicalEnvironment())
+ return jsNumber(JSJavaScriptCallFrame::GLOBAL_LEXICAL_ENVIRONMENT_SCOPE);
+ if (scope->isGlobalScope())
+ return jsNumber(JSJavaScriptCallFrame::GLOBAL_SCOPE);
- if (!exec->argument(0).isInt32())
+ ASSERT(scope->isClosureScope());
+ return jsNumber(JSJavaScriptCallFrame::CLOSURE_SCOPE);
+}
+
+static JSValue valueForScopeLocation(ExecState* exec, const DebuggerLocation& location)
+{
+ if (location.sourceID == noSourceID)
+ return jsNull();
+
+ // Debugger.Location protocol object.
+ JSObject* result = constructEmptyObject(exec);
+ result->putDirect(exec->vm(), Identifier::fromString(exec, "scriptId"), jsString(exec, String::number(location.sourceID)));
+ result->putDirect(exec->vm(), Identifier::fromString(exec, "lineNumber"), jsNumber(location.line));
+ result->putDirect(exec->vm(), Identifier::fromString(exec, "columnNumber"), jsNumber(location.column));
+ return result;
+}
+
+JSValue JSJavaScriptCallFrame::scopeDescriptions(ExecState* exec)
+{
+ DebuggerScope* scopeChain = impl().scopeChain();
+ if (!scopeChain)
return jsUndefined();
- int index = exec->argument(0).asInt32();
- DebuggerScope* scopeChain = impl().scopeChain();
+ int index = 0;
+ JSArray* array = constructEmptyArray(exec, nullptr);
+
DebuggerScope::iterator end = scopeChain->end();
-
for (DebuggerScope::iterator iter = scopeChain->begin(); iter != end; ++iter) {
DebuggerScope* scope = iter.get();
-
- if (!index) {
- if (scope->isCatchScope())
- return jsNumber(JSJavaScriptCallFrame::CATCH_SCOPE);
- if (scope->isFunctionNameScope())
- return jsNumber(JSJavaScriptCallFrame::FUNCTION_NAME_SCOPE);
- if (scope->isWithScope())
- return jsNumber(JSJavaScriptCallFrame::WITH_SCOPE);
- if (scope->isNestedLexicalScope())
- return jsNumber(JSJavaScriptCallFrame::NESTED_LEXICAL_SCOPE);
- if (scope->isGlobalLexicalEnvironment())
- return jsNumber(JSJavaScriptCallFrame::GLOBAL_LEXICAL_ENVIRONMENT_SCOPE);
- if (scope->isGlobalScope()) {
- ASSERT(++iter == end);
- return jsNumber(JSJavaScriptCallFrame::GLOBAL_SCOPE);
- }
- ASSERT(scope->isClosureScope());
- return jsNumber(JSJavaScriptCallFrame::CLOSURE_SCOPE);
- }
-
- --index;
+ JSObject* description = constructEmptyObject(exec);
+ description->putDirect(exec->vm(), Identifier::fromString(exec, "type"), valueForScopeType(scope));
+ description->putDirect(exec->vm(), Identifier::fromString(exec, "name"), jsString(exec, scope->name()));
+ description->putDirect(exec->vm(), Identifier::fromString(exec, "location"), valueForScopeLocation(exec, scope->location()));
+ array->putDirectIndex(exec, index++, description);
}
- ASSERT_NOT_REACHED();
- return jsUndefined();
+ return array;
}
JSValue JSJavaScriptCallFrame::caller(ExecState* exec) const
Modified: trunk/Source/_javascript_Core/inspector/JSJavaScriptCallFrame.h (202716 => 202717)
--- trunk/Source/_javascript_Core/inspector/JSJavaScriptCallFrame.h 2016-06-30 23:12:03 UTC (rev 202716)
+++ trunk/Source/_javascript_Core/inspector/JSJavaScriptCallFrame.h 2016-06-30 23:24:58 UTC (rev 202717)
@@ -58,7 +58,7 @@
// Functions.
JSC::JSValue evaluateWithScopeExtension(JSC::ExecState*);
- JSC::JSValue scopeType(JSC::ExecState*);
+ JSC::JSValue scopeDescriptions(JSC::ExecState*);
// Attributes.
JSC::JSValue caller(JSC::ExecState*) const;
Modified: trunk/Source/_javascript_Core/inspector/JSJavaScriptCallFramePrototype.cpp (202716 => 202717)
--- trunk/Source/_javascript_Core/inspector/JSJavaScriptCallFramePrototype.cpp 2016-06-30 23:12:03 UTC (rev 202716)
+++ trunk/Source/_javascript_Core/inspector/JSJavaScriptCallFramePrototype.cpp 2016-06-30 23:24:58 UTC (rev 202717)
@@ -39,7 +39,7 @@
// Functions.
static EncodedJSValue JSC_HOST_CALL jsJavaScriptCallFramePrototypeFunctionEvaluateWithScopeExtension(ExecState*);
-static EncodedJSValue JSC_HOST_CALL jsJavaScriptCallFramePrototypeFunctionScopeType(ExecState*);
+static EncodedJSValue JSC_HOST_CALL jsJavaScriptCallFramePrototypeFunctionScopeDescriptions(ExecState*);
// Attributes.
static EncodedJSValue JSC_HOST_CALL jsJavaScriptCallFrameAttributeCaller(ExecState*);
@@ -61,7 +61,7 @@
vm.prototypeMap.addPrototype(this);
JSC_NATIVE_FUNCTION_WITHOUT_TRANSITION("evaluateWithScopeExtension", jsJavaScriptCallFramePrototypeFunctionEvaluateWithScopeExtension, DontEnum, 1);
- JSC_NATIVE_FUNCTION_WITHOUT_TRANSITION("scopeType", jsJavaScriptCallFramePrototypeFunctionScopeType, DontEnum, 1);
+ JSC_NATIVE_FUNCTION_WITHOUT_TRANSITION("scopeDescriptions", jsJavaScriptCallFramePrototypeFunctionScopeDescriptions, DontEnum, 0);
JSC_NATIVE_GETTER("caller", jsJavaScriptCallFrameAttributeCaller, DontEnum | Accessor);
JSC_NATIVE_GETTER("sourceID", jsJavaScriptCallFrameAttributeSourceID, DontEnum | Accessor);
@@ -84,7 +84,7 @@
return JSValue::encode(castedThis->evaluateWithScopeExtension(exec));
}
-EncodedJSValue JSC_HOST_CALL jsJavaScriptCallFramePrototypeFunctionScopeType(ExecState* exec)
+EncodedJSValue JSC_HOST_CALL jsJavaScriptCallFramePrototypeFunctionScopeDescriptions(ExecState* exec)
{
JSValue thisValue = exec->thisValue();
JSJavaScriptCallFrame* castedThis = jsDynamicCast<JSJavaScriptCallFrame*>(thisValue);
@@ -91,7 +91,7 @@
if (!castedThis)
return throwVMTypeError(exec);
- return JSValue::encode(castedThis->scopeType(exec));
+ return JSValue::encode(castedThis->scopeDescriptions(exec));
}
EncodedJSValue JSC_HOST_CALL jsJavaScriptCallFrameAttributeCaller(ExecState* exec)
Modified: trunk/Source/_javascript_Core/inspector/protocol/Debugger.json (202716 => 202717)
--- trunk/Source/_javascript_Core/inspector/protocol/Debugger.json 2016-06-30 23:12:03 UTC (rev 202716)
+++ trunk/Source/_javascript_Core/inspector/protocol/Debugger.json 2016-06-30 23:24:58 UTC (rev 202717)
@@ -81,8 +81,10 @@
"id": "Scope",
"type": "object",
"properties": [
+ { "name": "object", "$ref": "Runtime.RemoteObject", "description": "Object representing the scope. For <code>global</code> and <code>with</code> scopes it represents the actual object; for the rest of the scopes, it is artificial transient object enumerating scope variables as its properties." },
{ "name": "type", "type": "string", "enum": ["global", "with", "closure", "catch", "functionName", "globalLexicalEnvironment", "nestedLexical"], "description": "Scope type." },
- { "name": "object", "$ref": "Runtime.RemoteObject", "description": "Object representing the scope. For <code>global</code> and <code>with</code> scopes it represents the actual object; for the rest of the scopes, it is artificial transient object enumerating scope variables as its properties." }
+ { "name": "name", "type": "string", "optional": true, "description": "Name associated with the scope." },
+ { "name": "location", "$ref": "Location", "optional": true, "description": "Location if available of the scope definition." }
],
"description": "Scope description."
},
Modified: trunk/Source/_javascript_Core/runtime/JSScope.cpp (202716 => 202717)
--- trunk/Source/_javascript_Core/runtime/JSScope.cpp 2016-06-30 23:12:03 UTC (rev 202716)
+++ trunk/Source/_javascript_Core/runtime/JSScope.cpp 2016-06-30 23:24:58 UTC (rev 202717)
@@ -340,4 +340,12 @@
return nullptr;
}
+SymbolTable* JSScope::symbolTable()
+{
+ if (JSSymbolTableObject* symbolTableObject = jsDynamicCast<JSSymbolTableObject*>(this))
+ return symbolTableObject->symbolTable();
+
+ return nullptr;
+}
+
} // namespace JSC
Modified: trunk/Source/_javascript_Core/runtime/JSScope.h (202716 => 202717)
--- trunk/Source/_javascript_Core/runtime/JSScope.h 2016-06-30 23:12:03 UTC (rev 202716)
+++ trunk/Source/_javascript_Core/runtime/JSScope.h 2016-06-30 23:24:58 UTC (rev 202717)
@@ -32,8 +32,9 @@
namespace JSC {
class ScopeChainIterator;
+class SymbolTable;
+class VariableEnvironment;
class WatchpointSet;
-class VariableEnvironment;
class JSScope : public JSNonFinalObject {
public:
@@ -71,6 +72,8 @@
VM* vm();
JSObject* globalThis();
+ SymbolTable* symbolTable();
+
protected:
JSScope(VM&, Structure*, JSScope* next);
Modified: trunk/Source/_javascript_Core/runtime/JSSymbolTableObject.cpp (202716 => 202717)
--- trunk/Source/_javascript_Core/runtime/JSSymbolTableObject.cpp 2016-06-30 23:12:03 UTC (rev 202716)
+++ trunk/Source/_javascript_Core/runtime/JSSymbolTableObject.cpp 2016-06-30 23:24:58 UTC (rev 202717)
@@ -6,13 +6,13 @@
* are met:
*
* 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
+ * 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.
+ * documentation and/or other materials provided with the distribution.
* 3. Neither the name of Apple Inc. ("Apple") nor the names of
* its contributors may be used to endorse or promote products derived
- * from this software without specific prior written permission.
+ * from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
@@ -29,13 +29,13 @@
#include "config.h"
#include "JSSymbolTableObject.h"
-#include "JSGlobalObject.h"
-#include "JSLexicalEnvironment.h"
#include "JSCInlines.h"
#include "PropertyNameArray.h"
namespace JSC {
+const ClassInfo JSSymbolTableObject::s_info = { "SymbolTableObject", &Base::s_info, nullptr, CREATE_METHOD_TABLE(JSSymbolTableObject) };
+
void JSSymbolTableObject::visitChildren(JSCell* cell, SlotVisitor& visitor)
{
JSSymbolTableObject* thisObject = jsCast<JSSymbolTableObject*>(cell);
@@ -50,7 +50,7 @@
if (thisObject->symbolTable()->contains(propertyName.uid()))
return false;
- return JSObject::deleteProperty(thisObject, exec, propertyName);
+ return Base::deleteProperty(thisObject, exec, propertyName);
}
void JSSymbolTableObject::getOwnNonIndexPropertyNames(JSObject* object, ExecState* exec, PropertyNameArray& propertyNames, EnumerationMode mode)
@@ -67,8 +67,8 @@
}
}
}
-
- JSObject::getOwnNonIndexPropertyNames(thisObject, exec, propertyNames, mode);
+
+ Base::getOwnNonIndexPropertyNames(thisObject, exec, propertyNames, mode);
}
} // namespace JSC
Modified: trunk/Source/_javascript_Core/runtime/JSSymbolTableObject.h (202716 => 202717)
--- trunk/Source/_javascript_Core/runtime/JSSymbolTableObject.h 2016-06-30 23:12:03 UTC (rev 202716)
+++ trunk/Source/_javascript_Core/runtime/JSSymbolTableObject.h 2016-06-30 23:24:58 UTC (rev 202717)
@@ -36,8 +36,6 @@
namespace JSC {
-class JSSymbolTableObject;
-
class JSSymbolTableObject : public JSScope {
public:
typedef JSScope Base;
@@ -49,7 +47,9 @@
JS_EXPORT_PRIVATE static void getOwnNonIndexPropertyNames(JSObject*, ExecState*, PropertyNameArray&, EnumerationMode);
static ptrdiff_t offsetOfSymbolTable() { return OBJECT_OFFSETOF(JSSymbolTableObject, m_symbolTable); }
-
+
+ DECLARE_EXPORT_INFO;
+
protected:
JSSymbolTableObject(VM& vm, Structure* structure, JSScope* scope)
: Base(vm, structure, scope)
Modified: trunk/Source/_javascript_Core/runtime/SymbolTable.cpp (202716 => 202717)
--- trunk/Source/_javascript_Core/runtime/SymbolTable.cpp 2016-06-30 23:12:03 UTC (rev 202716)
+++ trunk/Source/_javascript_Core/runtime/SymbolTable.cpp 2016-06-30 23:24:58 UTC (rev 202717)
@@ -104,6 +104,9 @@
visitor.append(&thisSymbolTable->m_arguments);
visitor.append(&thisSymbolTable->m_singletonScope);
+ if (thisSymbolTable->m_rareData)
+ visitor.append(&thisSymbolTable->m_rareData->m_codeBlock);
+
// Save some memory. This is O(n) to rebuild and we do so on the fly.
ConcurrentJITLocker locker(thisSymbolTable->m_lock);
thisSymbolTable->m_localToEntry = nullptr;
@@ -159,28 +162,28 @@
if (ScopedArgumentsTable* arguments = this->arguments())
result->m_arguments.set(vm, result, arguments);
- if (m_typeProfilingRareData) {
- result->m_typeProfilingRareData = std::make_unique<TypeProfilingRareData>();
+ if (m_rareData) {
+ result->m_rareData = std::make_unique<SymbolTableRareData>();
{
- auto iter = m_typeProfilingRareData->m_uniqueIDMap.begin();
- auto end = m_typeProfilingRareData->m_uniqueIDMap.end();
+ auto iter = m_rareData->m_uniqueIDMap.begin();
+ auto end = m_rareData->m_uniqueIDMap.end();
for (; iter != end; ++iter)
- result->m_typeProfilingRareData->m_uniqueIDMap.set(iter->key, iter->value);
+ result->m_rareData->m_uniqueIDMap.set(iter->key, iter->value);
}
{
- auto iter = m_typeProfilingRareData->m_offsetToVariableMap.begin();
- auto end = m_typeProfilingRareData->m_offsetToVariableMap.end();
+ auto iter = m_rareData->m_offsetToVariableMap.begin();
+ auto end = m_rareData->m_offsetToVariableMap.end();
for (; iter != end; ++iter)
- result->m_typeProfilingRareData->m_offsetToVariableMap.set(iter->key, iter->value);
+ result->m_rareData->m_offsetToVariableMap.set(iter->key, iter->value);
}
{
- auto iter = m_typeProfilingRareData->m_uniqueTypeSetMap.begin();
- auto end = m_typeProfilingRareData->m_uniqueTypeSetMap.end();
+ auto iter = m_rareData->m_uniqueTypeSetMap.begin();
+ auto end = m_rareData->m_uniqueTypeSetMap.end();
for (; iter != end; ++iter)
- result->m_typeProfilingRareData->m_uniqueTypeSetMap.set(iter->key, iter->value);
+ result->m_rareData->m_uniqueTypeSetMap.set(iter->key, iter->value);
}
}
@@ -189,23 +192,40 @@
void SymbolTable::prepareForTypeProfiling(const ConcurrentJITLocker&)
{
- if (m_typeProfilingRareData)
+ if (m_rareData)
return;
- m_typeProfilingRareData = std::make_unique<TypeProfilingRareData>();
+ m_rareData = std::make_unique<SymbolTableRareData>();
for (auto iter = m_map.begin(), end = m_map.end(); iter != end; ++iter) {
- m_typeProfilingRareData->m_uniqueIDMap.set(iter->key, TypeProfilerNeedsUniqueIDGeneration);
- m_typeProfilingRareData->m_offsetToVariableMap.set(iter->value.varOffset(), iter->key);
+ m_rareData->m_uniqueIDMap.set(iter->key, TypeProfilerNeedsUniqueIDGeneration);
+ m_rareData->m_offsetToVariableMap.set(iter->value.varOffset(), iter->key);
}
}
+CodeBlock* SymbolTable::rareDataCodeBlock()
+{
+ if (!m_rareData)
+ return nullptr;
+
+ return m_rareData->m_codeBlock.get();
+}
+
+void SymbolTable::setRareDataCodeBlock(CodeBlock* codeBlock)
+{
+ if (!m_rareData)
+ m_rareData = std::make_unique<SymbolTableRareData>();
+
+ ASSERT(!m_rareData->m_codeBlock);
+ m_rareData->m_codeBlock.set(*codeBlock->vm(), this, codeBlock);
+}
+
GlobalVariableID SymbolTable::uniqueIDForVariable(const ConcurrentJITLocker&, UniquedStringImpl* key, VM& vm)
{
- RELEASE_ASSERT(m_typeProfilingRareData);
+ RELEASE_ASSERT(m_rareData);
- auto iter = m_typeProfilingRareData->m_uniqueIDMap.find(key);
- auto end = m_typeProfilingRareData->m_uniqueIDMap.end();
+ auto iter = m_rareData->m_uniqueIDMap.find(key);
+ auto end = m_rareData->m_uniqueIDMap.end();
if (iter == end)
return TypeProfilerNoGlobalIDExists;
@@ -212,8 +232,8 @@
GlobalVariableID id = iter->value;
if (id == TypeProfilerNeedsUniqueIDGeneration) {
id = vm.typeProfiler()->getNextUniqueVariableID();
- m_typeProfilingRareData->m_uniqueIDMap.set(key, id);
- m_typeProfilingRareData->m_uniqueTypeSetMap.set(key, TypeSet::create()); // Make a new global typeset for this corresponding ID.
+ m_rareData->m_uniqueIDMap.set(key, id);
+ m_rareData->m_uniqueTypeSetMap.set(key, TypeSet::create()); // Make a new global typeset for this corresponding ID.
}
return id;
@@ -221,10 +241,10 @@
GlobalVariableID SymbolTable::uniqueIDForOffset(const ConcurrentJITLocker& locker, VarOffset offset, VM& vm)
{
- RELEASE_ASSERT(m_typeProfilingRareData);
+ RELEASE_ASSERT(m_rareData);
- auto iter = m_typeProfilingRareData->m_offsetToVariableMap.find(offset);
- auto end = m_typeProfilingRareData->m_offsetToVariableMap.end();
+ auto iter = m_rareData->m_offsetToVariableMap.find(offset);
+ auto end = m_rareData->m_offsetToVariableMap.end();
if (iter == end)
return TypeProfilerNoGlobalIDExists;
@@ -233,12 +253,12 @@
RefPtr<TypeSet> SymbolTable::globalTypeSetForOffset(const ConcurrentJITLocker& locker, VarOffset offset, VM& vm)
{
- RELEASE_ASSERT(m_typeProfilingRareData);
+ RELEASE_ASSERT(m_rareData);
uniqueIDForOffset(locker, offset, vm); // Lazily create the TypeSet if necessary.
- auto iter = m_typeProfilingRareData->m_offsetToVariableMap.find(offset);
- auto end = m_typeProfilingRareData->m_offsetToVariableMap.end();
+ auto iter = m_rareData->m_offsetToVariableMap.find(offset);
+ auto end = m_rareData->m_offsetToVariableMap.end();
if (iter == end)
return nullptr;
@@ -247,12 +267,12 @@
RefPtr<TypeSet> SymbolTable::globalTypeSetForVariable(const ConcurrentJITLocker& locker, UniquedStringImpl* key, VM& vm)
{
- RELEASE_ASSERT(m_typeProfilingRareData);
+ RELEASE_ASSERT(m_rareData);
uniqueIDForVariable(locker, key, vm); // Lazily create the TypeSet if necessary.
- auto iter = m_typeProfilingRareData->m_uniqueTypeSetMap.find(key);
- auto end = m_typeProfilingRareData->m_uniqueTypeSetMap.end();
+ auto iter = m_rareData->m_uniqueTypeSetMap.find(key);
+ auto end = m_rareData->m_uniqueTypeSetMap.end();
if (iter == end)
return nullptr;
Modified: trunk/Source/_javascript_Core/runtime/SymbolTable.h (202716 => 202717)
--- trunk/Source/_javascript_Core/runtime/SymbolTable.h 2016-06-30 23:12:03 UTC (rev 202716)
+++ trunk/Source/_javascript_Core/runtime/SymbolTable.h 2016-06-30 23:24:58 UTC (rev 202717)
@@ -679,6 +679,9 @@
SymbolTable* cloneScopePart(VM&);
void prepareForTypeProfiling(const ConcurrentJITLocker&);
+
+ CodeBlock* rareDataCodeBlock();
+ void setRareDataCodeBlock(CodeBlock*);
InferredValue* singletonScope() { return m_singletonScope.get(); }
@@ -695,12 +698,13 @@
Map m_map;
ScopeOffset m_maxScopeOffset;
- struct TypeProfilingRareData {
+ struct SymbolTableRareData {
UniqueIDMap m_uniqueIDMap;
OffsetToVariableMap m_offsetToVariableMap;
UniqueTypeSetMap m_uniqueTypeSetMap;
+ WriteBarrier<CodeBlock> m_codeBlock;
};
- std::unique_ptr<TypeProfilingRareData> m_typeProfilingRareData;
+ std::unique_ptr<SymbolTableRareData> m_rareData;
bool m_usesNonStrictEval : 1;
bool m_nestedLexicalScope : 1; // Non-function LexicalScope.
Modified: trunk/Source/WebInspectorUI/ChangeLog (202716 => 202717)
--- trunk/Source/WebInspectorUI/ChangeLog 2016-06-30 23:12:03 UTC (rev 202716)
+++ trunk/Source/WebInspectorUI/ChangeLog 2016-06-30 23:24:58 UTC (rev 202717)
@@ -1,3 +1,65 @@
+2016-06-30 Joseph Pecoraro <pecor...@apple.com>
+
+ Web Inspector: Wrong function name next to scope
+ https://bugs.webkit.org/show_bug.cgi?id=158210
+ <rdar://problem/26543093>
+
+ Reviewed by Timothy Hatcher.
+
+ * 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&3 scope4&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 "var" and "let" 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: "Closure Scope (name)", 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 "Local Variables".
+
2016-06-30 Matt Baker <mattba...@apple.com>
Web Inspector: add pixel area column to layout timeline view
Modified: trunk/Source/WebInspectorUI/UserInterface/Controllers/DebuggerManager.js (202716 => 202717)
--- trunk/Source/WebInspectorUI/UserInterface/Controllers/DebuggerManager.js 2016-06-30 23:12:03 UTC (rev 202716)
+++ trunk/Source/WebInspectorUI/UserInterface/Controllers/DebuggerManager.js 2016-06-30 23:24:58 UTC (rev 202717)
@@ -662,7 +662,7 @@
}
var object = WebInspector.RemoteObject.fromPayload(payload.object);
- return new WebInspector.ScopeChainNode(type, [object]);
+ return new WebInspector.ScopeChainNode(type, [object], payload.name, payload.location);
}
_pauseReasonFromPayload(payload)
Modified: trunk/Source/WebInspectorUI/UserInterface/Models/CallFrame.js (202716 => 202717)
--- trunk/Source/WebInspectorUI/UserInterface/Models/CallFrame.js 2016-06-30 23:12:03 UTC (rev 202716)
+++ trunk/Source/WebInspectorUI/UserInterface/Models/CallFrame.js 2016-06-30 23:24:58 UTC (rev 202717)
@@ -45,46 +45,15 @@
// Public
- get id()
- {
- return this._id;
- }
+ 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; }
- 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;
- }
-
saveIdentityToCookie()
{
// Do nothing. The call frame is torn down when the inspector closes, and
@@ -112,6 +81,99 @@
this._scopeChain[i].objects[0].deprecatedGetAllProperties(propertiesCollected);
}
+ 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&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 && youngScope.hash === lastMerge.hash)
+ return false;
+
+ return true;
+ }
+
+ let lastScope = null;
+ let lastMerge = null;
+ for (let i = scopes.length - 1; i >= 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;
+ }
+
// Static
static functionNameFromPayload(payload)
Modified: trunk/Source/WebInspectorUI/UserInterface/Models/ScopeChainNode.js (202716 => 202717)
--- trunk/Source/WebInspectorUI/UserInterface/Models/ScopeChainNode.js 2016-06-30 23:12:03 UTC (rev 202716)
+++ trunk/Source/WebInspectorUI/UserInterface/Models/ScopeChainNode.js 2016-06-30 23:24:58 UTC (rev 202717)
@@ -25,7 +25,7 @@
WebInspector.ScopeChainNode = class ScopeChainNode extends WebInspector.Object
{
- constructor(type, objects)
+ constructor(type, objects, name, location)
{
super();
@@ -37,18 +37,31 @@
this._type = type || null;
this._objects = objects || [];
+ this._name = name || "";
+ this._location = location || null;
}
// Public
- get type()
+ get type() { return this._type; }
+ get objects() { return this._objects; }
+ get name() { return this._name; }
+ get location() { return this._location; }
+
+ get hash()
{
- return this._type;
+ 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;
}
- get objects()
+ convertToLocalScope()
{
- return this._objects;
+ this._type = WebInspector.ScopeChainNode.Type.Local;
}
};
Modified: trunk/Source/WebInspectorUI/UserInterface/Views/ScopeChainDetailsSidebarPanel.js (202716 => 202717)
--- trunk/Source/WebInspectorUI/UserInterface/Views/ScopeChainDetailsSidebarPanel.js 2016-06-30 23:12:03 UTC (rev 202716)
+++ trunk/Source/WebInspectorUI/UserInterface/Views/ScopeChainDetailsSidebarPanel.js 2016-06-30 23:24:58 UTC (rev 202717)
@@ -164,159 +164,92 @@
for (let type in WebInspector.ScopeChainNode.Type)
sectionCountByType.set(WebInspector.ScopeChainNode.Type[type], 0);
- // 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;
+ let scopeChain = callFrame.mergedScopeChain();
+ for (let scope of scopeChain) {
+ let title = null;
+ let extraPropertyDescriptor = null;
+ let collapsedByDefault = false;
- // Group scopes with the call frame containing them.
- // Creating a map that looks like:
- // CallFrame2 => [scope5, scope4]
- // CallFrame1 => [scope3, scope2, scope1]
- let reversedScopeChain = scopeChain.slice().reverse();
- let callFrameScopes = new Map;
- let lastLength = 0;
- for (let i = callFrames.length - 1; i >= 0; --i) {
- let nextCallFrame = callFrames[i];
- console.assert(nextCallFrame.scopeChain.length > lastLength);
- callFrameScopes.set(nextCallFrame, reversedScopeChain.slice(lastLength, nextCallFrame.scopeChain.length));
- lastLength = nextCallFrame.scopeChain.length;
- if (nextCallFrame === callFrame) {
- console.assert(lastLength === scopeChain.length);
+ 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("Local Variables");
+ if (callFrame.thisObject)
+ extraPropertyDescriptor = new WebInspector.PropertyDescriptor({name: "this", value: callFrame.thisObject});
break;
- }
- }
- // 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 => [scope4, scope5]
- // CallFrame1 => [scope1, scope2&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 && firstClosureScope)
- break;
+ case WebInspector.ScopeChainNode.Type.Closure:
+ if (scope.__baseClosureScope && scope.name)
+ title = WebInspector.UIString("Closure Variables (%s)").format(scope.name);
+ else
+ title = WebInspector.UIString("Closure Variables");
+ collapsedByDefault = false;
+ break;
- // Found first closure scope. Mark it so we can provide the function name later in the UI.
- if (isClosureScope && !firstClosureScope) {
- firstClosureScope = scope;
- firstClosureScope[WebInspector.ScopeChainDetailsSidebarPanel.CallFrameBaseClosureScopeSymbol] = true;
- continue;
- }
+ case WebInspector.ScopeChainNode.Type.Block:
+ title = WebInspector.UIString("Block Variables");
+ collapsedByDefault = false;
+ break;
- // Found 2 sequential top level closure scopes. Merge and mark it so we can provide the function name later in the UI.
- if (isClosureScope && 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);
+ case WebInspector.ScopeChainNode.Type.Catch:
+ title = WebInspector.UIString("Catch Variables");
+ collapsedByDefault = false;
+ break;
- 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();
- }
+ case WebInspector.ScopeChainNode.Type.FunctionName:
+ title = WebInspector.UIString("Function Name Variable");
+ collapsedByDefault = true;
+ break;
- // Now we can walk the list of call frames and their scopes.
- // We walk in top -> down order:
- // CallFrame1 => [scope1, scope2&3]
- // CallFrame2 => [scope5, scope4]
- for (let [call, scopes] of [...callFrameScopes.entries()].reverse()) {
- for (let scope of scopes) {
- let title = null;
- let extraPropertyDescriptor = null;
- let collapsedByDefault = false;
+ case WebInspector.ScopeChainNode.Type.With:
+ title = WebInspector.UIString("With Object Properties");
+ collapsedByDefault = foundLocalScope;
+ break;
- let count = sectionCountByType.get(scope.type);
- sectionCountByType.set(scope.type, ++count);
+ case WebInspector.ScopeChainNode.Type.Global:
+ title = WebInspector.UIString("Global Variables");
+ collapsedByDefault = true;
+ break;
- switch (scope.type) {
- case WebInspector.ScopeChainNode.Type.Local:
- foundLocalScope = true;
- collapsedByDefault = false;
- title = WebInspector.UIString("Local Variables");
- if (call.thisObject)
- extraPropertyDescriptor = new WebInspector.PropertyDescriptor({name: "this", value: call.thisObject});
- break;
+ case WebInspector.ScopeChainNode.Type.GlobalLexicalEnvironment:
+ title = WebInspector.UIString("Global Lexical Environment");
+ collapsedByDefault = true;
+ break;
+ }
- case WebInspector.ScopeChainNode.Type.Closure:
- if (scope[WebInspector.ScopeChainDetailsSidebarPanel.CallFrameBaseClosureScopeSymbol] && call.functionName)
- title = WebInspector.UIString("Closure Variables (%s)").format(call.functionName);
- else
- title = WebInspector.UIString("Closure Variables");
- collapsedByDefault = false;
- break;
+ let detailsSectionIdentifier = scope.type + "-" + sectionCountByType.get(scope.type);
- case WebInspector.ScopeChainNode.Type.Block:
- title = WebInspector.UIString("Block Variables");
- collapsedByDefault = false;
- break;
+ // FIXME: This just puts two ObjectTreeViews next to each other, but that means
+ // that properties are not nicely sorted between the two separate lists.
- case WebInspector.ScopeChainNode.Type.Catch:
- title = WebInspector.UIString("Catch Variables");
- collapsedByDefault = false;
- break;
+ 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);
- case WebInspector.ScopeChainNode.Type.FunctionName:
- title = WebInspector.UIString("Function Name Variable");
- collapsedByDefault = true;
- break;
+ objectTree.showOnlyProperties();
- case WebInspector.ScopeChainNode.Type.With:
- title = WebInspector.UIString("With Object Properties");
- collapsedByDefault = foundLocalScope;
- break;
-
- case WebInspector.ScopeChainNode.Type.Global:
- title = WebInspector.UIString("Global Variables");
- collapsedByDefault = true;
- break;
-
- case WebInspector.ScopeChainNode.Type.GlobalLexicalEnvironment:
- title = WebInspector.UIString("Global Lexical Environment");
- collapsedByDefault = true;
- break;
+ if (extraPropertyDescriptor) {
+ objectTree.appendExtraPropertyDescriptor(extraPropertyDescriptor);
+ extraPropertyDescriptor = null;
}
- let detailsSectionIdentifier = scope.type + "-" + sectionCountByType.get(scope.type);
+ 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);
- // FIXME: This just puts two ObjectTreeViews next to eachother, but that means
- // that properties are not nicely sorted between the two separate lists.
+ // FIXME: <https://webkit.org/b/140567> 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));
+ }
- 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);
- }
+ let detailsSection = new WebInspector.DetailsSection(detailsSectionIdentifier, title, null, null, collapsedByDefault);
+ detailsSection.groups[0].rows = rows;
+ detailsSections.push(detailsSection);
}
return Promise.resolve(detailsSections);
@@ -545,4 +478,3 @@
WebInspector.ScopeChainDetailsSidebarPanel._autoExpandProperties = new Set;
WebInspector.ScopeChainDetailsSidebarPanel.WatchExpressionsObjectGroupName = "watch-expressions";
-WebInspector.ScopeChainDetailsSidebarPanel.CallFrameBaseClosureScopeSymbol = Symbol("scope-chain-call-frame-base-closure-scope");