Fixed the Inspector to be able to properly distinguish between scope types.
authormark.lam@apple.com <mark.lam@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Thu, 2 Oct 2014 15:15:03 +0000 (15:15 +0000)
committermark.lam@apple.com <mark.lam@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Thu, 2 Oct 2014 15:15:03 +0000 (15:15 +0000)
<https://webkit.org/b/137279>

Source/JavaScriptCore:

Reviewed by Geoffrey Garen.

The pre-existing code incorrectly labels Catch Scopes and Function Name Scopes
as With Scopes.  This patch will fix this.

* bytecode/BytecodeList.json:
* bytecompiler/BytecodeGenerator.cpp:
(JSC::BytecodeGenerator::emitPushFunctionNameScope):
(JSC::BytecodeGenerator::emitPushCatchScope):
- These now passes stores the desired JSNameScope::Type in a bytecode operand.
* debugger/DebuggerScope.cpp:
(JSC::DebuggerScope::isCatchScope):
(JSC::DebuggerScope::isFunctionNameScope):
- Added queries to be able to explicitly test if the scope is a CatchScope
  or FunctionNameScope.  The FunctionNameScope is the case where the
  NameScope is used to capture the function name of a function expression.
* debugger/DebuggerScope.h:
* inspector/InjectedScriptSource.js:
* inspector/JSJavaScriptCallFrame.cpp:
(Inspector::JSJavaScriptCallFrame::scopeType):
* inspector/JSJavaScriptCallFrame.h:
* inspector/JSJavaScriptCallFramePrototype.cpp:
(Inspector::JSJavaScriptCallFramePrototype::finishCreation):
(Inspector::jsJavaScriptCallFrameConstantFUNCTION_NAME_SCOPE):
* inspector/protocol/Debugger.json:
* jit/CCallHelpers.h:
(JSC::CCallHelpers::setupArgumentsWithExecState):
* jit/JIT.h:
* jit/JITInlines.h:
(JSC::JIT::callOperation):
* jit/JITOpcodes.cpp:
(JSC::JIT::emit_op_push_name_scope):
* jit/JITOpcodes32_64.cpp:
(JSC::JIT::emit_op_push_name_scope):
* jit/JITOperations.cpp:
* jit/JITOperations.h:
* llint/LLIntSlowPaths.cpp:
(JSC::LLInt::LLINT_SLOW_PATH_DECL):
* llint/LowLevelInterpreter.asm:
* runtime/JSFunction.cpp:
(JSC::JSFunction::addNameScopeIfNeeded):
* runtime/JSNameScope.h:
(JSC::JSNameScope::create):
(JSC::JSNameScope::isFunctionNameScope):
(JSC::JSNameScope::isCatchScope):
(JSC::JSNameScope::JSNameScope):
- Now stores the JSNameScope::Type in a field.

Source/WebInspectorUI:

Reviewed by Geoffrey Garen and Joseph Pecoraro.

* Localizations/en.lproj/localizedStrings.js:
* UserInterface/Controllers/DebuggerManager.js:
* UserInterface/Models/ScopeChainNode.js:
* UserInterface/Views/ScopeChainDetailsSidebarPanel.js:
- Added handling of the FunctionNameScope case.

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@174216 268f45cc-cd09-0410-ab3c-d52691b4dbfc

26 files changed:
Source/JavaScriptCore/ChangeLog
Source/JavaScriptCore/bytecode/BytecodeList.json
Source/JavaScriptCore/bytecompiler/BytecodeGenerator.cpp
Source/JavaScriptCore/debugger/DebuggerScope.cpp
Source/JavaScriptCore/debugger/DebuggerScope.h
Source/JavaScriptCore/inspector/InjectedScriptSource.js
Source/JavaScriptCore/inspector/JSJavaScriptCallFrame.cpp
Source/JavaScriptCore/inspector/JSJavaScriptCallFrame.h
Source/JavaScriptCore/inspector/JSJavaScriptCallFramePrototype.cpp
Source/JavaScriptCore/inspector/protocol/Debugger.json
Source/JavaScriptCore/jit/CCallHelpers.h
Source/JavaScriptCore/jit/JIT.h
Source/JavaScriptCore/jit/JITInlines.h
Source/JavaScriptCore/jit/JITOpcodes.cpp
Source/JavaScriptCore/jit/JITOpcodes32_64.cpp
Source/JavaScriptCore/jit/JITOperations.cpp
Source/JavaScriptCore/jit/JITOperations.h
Source/JavaScriptCore/llint/LLIntSlowPaths.cpp
Source/JavaScriptCore/llint/LowLevelInterpreter.asm
Source/JavaScriptCore/runtime/JSFunction.cpp
Source/JavaScriptCore/runtime/JSNameScope.h
Source/WebInspectorUI/ChangeLog
Source/WebInspectorUI/Localizations/en.lproj/localizedStrings.js
Source/WebInspectorUI/UserInterface/Controllers/DebuggerManager.js
Source/WebInspectorUI/UserInterface/Models/ScopeChainNode.js
Source/WebInspectorUI/UserInterface/Views/ScopeChainDetailsSidebarPanel.js

index f1a7ac7..bd237b4 100644 (file)
@@ -1,3 +1,56 @@
+2014-10-02  Mark Lam  <mark.lam@apple.com>
+
+        Fixed the Inspector to be able to properly distinguish between scope types.
+        <https://webkit.org/b/137279>
+
+        Reviewed by Geoffrey Garen.
+
+        The pre-existing code incorrectly labels Catch Scopes and Function Name Scopes
+        as With Scopes.  This patch will fix this.
+
+        * bytecode/BytecodeList.json:
+        * bytecompiler/BytecodeGenerator.cpp:
+        (JSC::BytecodeGenerator::emitPushFunctionNameScope):
+        (JSC::BytecodeGenerator::emitPushCatchScope):
+        - These now passes stores the desired JSNameScope::Type in a bytecode operand.
+        * debugger/DebuggerScope.cpp:
+        (JSC::DebuggerScope::isCatchScope):
+        (JSC::DebuggerScope::isFunctionNameScope):
+        - Added queries to be able to explicitly test if the scope is a CatchScope
+          or FunctionNameScope.  The FunctionNameScope is the case where the
+          NameScope is used to capture the function name of a function expression.
+        * debugger/DebuggerScope.h:
+        * inspector/InjectedScriptSource.js:
+        * inspector/JSJavaScriptCallFrame.cpp:
+        (Inspector::JSJavaScriptCallFrame::scopeType):
+        * inspector/JSJavaScriptCallFrame.h:
+        * inspector/JSJavaScriptCallFramePrototype.cpp:
+        (Inspector::JSJavaScriptCallFramePrototype::finishCreation):
+        (Inspector::jsJavaScriptCallFrameConstantFUNCTION_NAME_SCOPE):
+        * inspector/protocol/Debugger.json:
+        * jit/CCallHelpers.h:
+        (JSC::CCallHelpers::setupArgumentsWithExecState):
+        * jit/JIT.h:
+        * jit/JITInlines.h:
+        (JSC::JIT::callOperation):
+        * jit/JITOpcodes.cpp:
+        (JSC::JIT::emit_op_push_name_scope):
+        * jit/JITOpcodes32_64.cpp:
+        (JSC::JIT::emit_op_push_name_scope):
+        * jit/JITOperations.cpp:
+        * jit/JITOperations.h:
+        * llint/LLIntSlowPaths.cpp:
+        (JSC::LLInt::LLINT_SLOW_PATH_DECL):
+        * llint/LowLevelInterpreter.asm:
+        * runtime/JSFunction.cpp:
+        (JSC::JSFunction::addNameScopeIfNeeded):
+        * runtime/JSNameScope.h:
+        (JSC::JSNameScope::create):
+        (JSC::JSNameScope::isFunctionNameScope):
+        (JSC::JSNameScope::isCatchScope):
+        (JSC::JSNameScope::JSNameScope):
+        - Now stores the JSNameScope::Type in a field.
+
 2014-10-01  Commit Queue  <commit-queue@webkit.org>
 
         Unreviewed, rolling out r174180, r174183, and r174186.
index 04e76dc..850a956 100644 (file)
             { "name" : "op_put_to_scope", "length" : 7 },
             { "name" : "op_push_with_scope", "length" : 2 },
             { "name" : "op_pop_scope", "length" : 1 },
-            { "name" : "op_push_name_scope", "length" : 4 },
+            { "name" : "op_push_name_scope", "length" : 5 },
             { "name" : "op_catch", "length" : 2 },
             { "name" : "op_throw", "length" : 2 },
             { "name" : "op_throw_static_error", "length" : 3 },
index 571f39a..3e68154 100644 (file)
@@ -2294,6 +2294,7 @@ void BytecodeGenerator::emitPushFunctionNameScope(const Identifier& property, Re
     instructions().append(addConstant(property));
     instructions().append(value->index());
     instructions().append(attributes);
+    instructions().append(JSNameScope::FunctionNameScope);
 }
 
 void BytecodeGenerator::emitPushCatchScope(const Identifier& property, RegisterID* value, unsigned attributes)
@@ -2307,6 +2308,7 @@ void BytecodeGenerator::emitPushCatchScope(const Identifier& property, RegisterI
     instructions().append(addConstant(property));
     instructions().append(value->index());
     instructions().append(attributes);
+    instructions().append(JSNameScope::CatchScope);
 }
 
 void BytecodeGenerator::beginSwitch(RegisterID* scrutineeRegister, SwitchInfo::SwitchType type)
index 86fd976..e9b5016 100644 (file)
@@ -28,6 +28,7 @@
 
 #include "JSLexicalEnvironment.h"
 #include "JSCInlines.h"
+#include "JSNameScope.h"
 #include "JSWithScope.h"
 
 namespace JSC {
@@ -154,6 +155,16 @@ void DebuggerScope::invalidateChain()
     }
 }
 
+bool DebuggerScope::isCatchScope() const
+{
+    return m_scope->isNameScopeObject() && reinterpret_cast<JSNameScope*>(m_scope.get())->isCatchScope();
+}
+
+bool DebuggerScope::isFunctionNameScope() const
+{
+    return m_scope->isNameScopeObject() && reinterpret_cast<JSNameScope*>(m_scope.get())->isFunctionNameScope();
+}
+
 bool DebuggerScope::isWithScope() const
 {
     return m_scope->isWithScope();
index 4c32116..32a72f7 100644 (file)
@@ -84,6 +84,8 @@ public:
     void invalidateChain();
     bool isValid() const { return !!m_scope; }
 
+    bool isCatchScope() const;
+    bool isFunctionNameScope() const;
     bool isWithScope() const;
     bool isGlobalScope() const;
     bool isFunctionOrEvalScope() const;
index db331cf..04e9049 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2007 Apple Inc.  All rights reserved.
+ * Copyright (C) 2007, 2014 Apple Inc.  All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -1018,6 +1018,7 @@ InjectedScript.CallFrameProxy._createScopeJson = function(scopeTypeCode, scopeOb
     const WITH_SCOPE = 2;
     const CLOSURE_SCOPE = 3;
     const CATCH_SCOPE = 4;
+    const FUNCTION_NAME_SCOPE = 5;
 
     /** @type {!Object.<number, string>} */
     var scopeTypeNames = {};
@@ -1026,6 +1027,7 @@ InjectedScript.CallFrameProxy._createScopeJson = function(scopeTypeCode, scopeOb
     scopeTypeNames[WITH_SCOPE] = "with";
     scopeTypeNames[CLOSURE_SCOPE] = "closure";
     scopeTypeNames[CATCH_SCOPE] = "catch";
+    scopeTypeNames[FUNCTION_NAME_SCOPE] = "functionName";
 
     return {
         object: injectedScript._wrapObject(scopeObject, groupId),
index 036920d..3f12554 100644 (file)
@@ -111,13 +111,16 @@ JSValue JSJavaScriptCallFrame::scopeType(ExecState* exec)
         }
 
         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->isGlobalScope()) {
                 ASSERT(++iter == end);
                 return jsNumber(JSJavaScriptCallFrame::GLOBAL_SCOPE);
             }
-            // FIXME: We should be identifying and returning CATCH_SCOPE appropriately.
             ASSERT(scope->isFunctionOrEvalScope());
             return jsNumber(JSJavaScriptCallFrame::CLOSURE_SCOPE);
         }
index dbbb93f..05a3307 100644 (file)
@@ -77,6 +77,7 @@ public:
     static const unsigned short WITH_SCOPE = 2;
     static const unsigned short CLOSURE_SCOPE = 3;
     static const unsigned short CATCH_SCOPE = 4;
+    static const unsigned short FUNCTION_NAME_SCOPE = 5;
 
 protected:
     static const unsigned StructureFlags = Base::StructureFlags;
index 409c68c..26adf0a 100644 (file)
@@ -59,6 +59,7 @@ static EncodedJSValue JSC_HOST_CALL jsJavaScriptCallFrameConstantLOCAL_SCOPE(Exe
 static EncodedJSValue JSC_HOST_CALL jsJavaScriptCallFrameConstantWITH_SCOPE(ExecState*);
 static EncodedJSValue JSC_HOST_CALL jsJavaScriptCallFrameConstantCLOSURE_SCOPE(ExecState*);
 static EncodedJSValue JSC_HOST_CALL jsJavaScriptCallFrameConstantCATCH_SCOPE(ExecState*);
+static EncodedJSValue JSC_HOST_CALL jsJavaScriptCallFrameConstantFUNCTION_NAME_SCOPE(ExecState*);
 
 const ClassInfo JSJavaScriptCallFramePrototype::s_info = { "JavaScriptCallFrame", &Base::s_info, 0, CREATE_METHOD_TABLE(JSJavaScriptCallFramePrototype) };
 
@@ -94,6 +95,7 @@ void JSJavaScriptCallFramePrototype::finishCreation(VM& vm, JSGlobalObject* glob
     JSC_NATIVE_NON_INDEX_ACCESSOR("WITH_SCOPE", jsJavaScriptCallFrameConstantWITH_SCOPE, DontEnum | Accessor);
     JSC_NATIVE_NON_INDEX_ACCESSOR("CLOSURE_SCOPE", jsJavaScriptCallFrameConstantCLOSURE_SCOPE, DontEnum | Accessor);
     JSC_NATIVE_NON_INDEX_ACCESSOR("CATCH_SCOPE", jsJavaScriptCallFrameConstantCATCH_SCOPE, DontEnum | Accessor);
+    JSC_NATIVE_NON_INDEX_ACCESSOR("FUNCTION_NAME_SCOPE", jsJavaScriptCallFrameConstantFUNCTION_NAME_SCOPE, DontEnum | Accessor);
 }
 
 EncodedJSValue JSC_HOST_CALL jsJavaScriptCallFramePrototypeFunctionEvaluate(ExecState* exec)
@@ -231,6 +233,11 @@ EncodedJSValue JSC_HOST_CALL jsJavaScriptCallFrameConstantCATCH_SCOPE(ExecState*
     return JSValue::encode(jsNumber(JSJavaScriptCallFrame::CATCH_SCOPE));
 }
 
+EncodedJSValue JSC_HOST_CALL jsJavaScriptCallFrameConstantFUNCTION_NAME_SCOPE(ExecState*)
+{
+    return JSValue::encode(jsNumber(JSJavaScriptCallFrame::FUNCTION_NAME_SCOPE));
+}
+
 } // namespace Inspector
 
 #endif // ENABLE(INSPECTOR)
index 3b7c4bd..247be8c 100644 (file)
@@ -80,7 +80,7 @@
             "id": "Scope",
             "type": "object",
             "properties": [
-                { "name": "type", "type": "string", "enum": ["global", "local", "with", "closure", "catch"], "description": "Scope type." },
+                { "name": "type", "type": "string", "enum": ["global", "local", "with", "closure", "catch", "functionName"], "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." }
             ],
             "description": "Scope description."
index c58db6c..21adddb 100644 (file)
@@ -474,6 +474,17 @@ public:
         addCallArgument(arg4);
     }
 
+    ALWAYS_INLINE void setupArgumentsWithExecState(TrustedImmPtr arg1, GPRReg arg2, GPRReg arg3, TrustedImm32 arg4, TrustedImm32 arg5)
+    {
+        resetCallArguments();
+        addCallArgument(GPRInfo::callFrameRegister);
+        addCallArgument(arg1);
+        addCallArgument(arg2);
+        addCallArgument(arg3);
+        addCallArgument(arg4);
+        addCallArgument(arg5);
+    }
+
     ALWAYS_INLINE void setupArgumentsWithExecState(TrustedImmPtr arg1, GPRReg arg2, GPRReg arg3, TrustedImm32 arg4, TrustedImmPtr arg5)
     {
         resetCallArguments();
@@ -1285,6 +1296,17 @@ public:
         move(GPRInfo::callFrameRegister, GPRInfo::argumentGPR0);
     }
 
+#if CPU(X86_64) || CPU(ARM64)
+    ALWAYS_INLINE void setupArgumentsWithExecState(TrustedImmPtr arg1, GPRReg arg2, TrustedImm32 arg3, TrustedImm32 arg4)
+    {
+        move(arg2, GPRInfo::argumentGPR2); // In case arg2 is argumentGPR1.
+        move(arg1, GPRInfo::argumentGPR1);
+        move(arg3, GPRInfo::argumentGPR3);
+        move(arg4, GPRInfo::argumentGPR4);
+        move(GPRInfo::callFrameRegister, GPRInfo::argumentGPR0);
+    }
+#endif
+
     ALWAYS_INLINE void setupArgumentsWithExecState(TrustedImmPtr arg1, GPRReg arg2, TrustedImmPtr arg3)
     {
         move(arg2, GPRInfo::argumentGPR2); // In case arg2 is argumentGPR1.
@@ -1364,6 +1386,13 @@ public:
         setupArgumentsWithExecState(arg1, arg2, arg3);
     }
 
+    ALWAYS_INLINE void setupArgumentsWithExecState(TrustedImmPtr arg1, GPRReg arg2, GPRReg arg3, TrustedImm32 arg4, TrustedImm32 arg5)
+    {
+        poke(arg5, POKE_ARGUMENT_OFFSET + 1);
+        poke(arg4, POKE_ARGUMENT_OFFSET);
+        setupArgumentsWithExecState(arg1, arg2, arg3);
+    }
+
     ALWAYS_INLINE void setupArgumentsWithExecState(TrustedImmPtr arg1, GPRReg arg2, GPRReg arg3, TrustedImm32 arg4, TrustedImmPtr arg5)
     {
         poke(arg5, POKE_ARGUMENT_OFFSET + 1);
@@ -1645,6 +1674,15 @@ public:
         move(GPRInfo::callFrameRegister, GPRInfo::argumentGPR0);
     }
     
+    ALWAYS_INLINE void setupArgumentsWithExecState(TrustedImmPtr arg1, GPRReg arg2, GPRReg arg3, TrustedImm32 arg4, TrustedImm32 arg5)
+    {
+        setupTwoStubArgsGPR<GPRInfo::argumentGPR2, GPRInfo::argumentGPR3>(arg2, arg3);
+        move(arg1, GPRInfo::argumentGPR1);
+        move(arg4, GPRInfo::argumentGPR4);
+        move(arg5, GPRInfo::argumentGPR5);
+        move(GPRInfo::callFrameRegister, GPRInfo::argumentGPR0);
+    }
+
     ALWAYS_INLINE void setupArgumentsWithExecState(GPRReg arg1, GPRReg arg2, GPRReg arg3, TrustedImm32 arg4)
     {
         setupThreeStubArgsGPR<GPRInfo::argumentGPR1, GPRInfo::argumentGPR2, GPRInfo::argumentGPR3>(arg1, arg2, arg3);
index 53d429a..a95f1d9 100644 (file)
@@ -719,7 +719,7 @@ namespace JSC {
         MacroAssembler::Call callOperation(V_JITOperation_ECC, RegisterID, RegisterID);
         MacroAssembler::Call callOperation(V_JITOperation_ECICC, RegisterID, const Identifier*, RegisterID, RegisterID);
         MacroAssembler::Call callOperation(J_JITOperation_EE, RegisterID);
-        MacroAssembler::Call callOperation(V_JITOperation_EIdJZ, const Identifier*, RegisterID, int32_t);
+        MacroAssembler::Call callOperation(V_JITOperation_EIdJZZ, const Identifier*, RegisterID, int32_t, int32_t);
         MacroAssembler::Call callOperation(V_JITOperation_EJ, RegisterID);
 #if USE(JSVALUE64)
         MacroAssembler::Call callOperationNoExceptionCheck(V_JITOperation_EJ, RegisterID);
@@ -751,7 +751,7 @@ namespace JSC {
         MacroAssembler::Call callOperation(P_JITOperation_EJS, GPRReg, GPRReg, size_t);
         MacroAssembler::Call callOperation(S_JITOperation_EJ, RegisterID, RegisterID);
         MacroAssembler::Call callOperation(S_JITOperation_EJJ, RegisterID, RegisterID, RegisterID, RegisterID);
-        MacroAssembler::Call callOperation(V_JITOperation_EIdJZ, const Identifier*, RegisterID, RegisterID, int32_t);
+        MacroAssembler::Call callOperation(V_JITOperation_EIdJZZ, const Identifier*, RegisterID, RegisterID, int32_t, int32_t);
         MacroAssembler::Call callOperation(V_JITOperation_EJ, RegisterID, RegisterID);
         MacroAssembler::Call callOperation(V_JITOperation_EJJJ, RegisterID, RegisterID, RegisterID, RegisterID, RegisterID, RegisterID);
         MacroAssembler::Call callOperation(V_JITOperation_EJZ, RegisterID, RegisterID, int32_t);
index 321c33d..cce4109 100644 (file)
@@ -441,9 +441,9 @@ ALWAYS_INLINE MacroAssembler::Call JIT::callOperation(S_JITOperation_EJJ operati
     return appendCallWithExceptionCheck(operation);
 }
 
-ALWAYS_INLINE MacroAssembler::Call JIT::callOperation(V_JITOperation_EIdJZ operation, const Identifier* identOp1, RegisterID regOp2, int32_t op3)
+ALWAYS_INLINE MacroAssembler::Call JIT::callOperation(V_JITOperation_EIdJZZ operation, const Identifier* identOp1, RegisterID regOp2, int32_t op3, int32_t op4)
 {
-    setupArgumentsWithExecState(TrustedImmPtr(identOp1), regOp2, TrustedImm32(op3));
+    setupArgumentsWithExecState(TrustedImmPtr(identOp1), regOp2, TrustedImm32(op3), TrustedImm32(op4));
     return appendCallWithExceptionCheck(operation);
 }
 
@@ -575,9 +575,9 @@ ALWAYS_INLINE MacroAssembler::Call JIT::callOperation(V_JITOperation_EJ operatio
     return appendCallWithExceptionCheck(operation);
 }
 
-ALWAYS_INLINE MacroAssembler::Call JIT::callOperation(V_JITOperation_EIdJZ operation, const Identifier* identOp1, RegisterID regOp2Tag, RegisterID regOp2Payload, int32_t op3)
+ALWAYS_INLINE MacroAssembler::Call JIT::callOperation(V_JITOperation_EIdJZZ operation, const Identifier* identOp1, RegisterID regOp2Tag, RegisterID regOp2Payload, int32_t op3, int32_t op4)
 {
-    setupArgumentsWithExecState(TrustedImmPtr(identOp1), regOp2Payload, regOp2Tag, TrustedImm32(op3));
+    setupArgumentsWithExecState(TrustedImmPtr(identOp1), regOp2Payload, regOp2Tag, TrustedImm32(op3), TrustedImm32(op4));
     return appendCallWithExceptionCheck(operation);
 }
 
index 393e7d4..fa698f3 100644 (file)
@@ -525,7 +525,7 @@ void JIT::emit_op_to_number(Instruction* currentInstruction)
 void JIT::emit_op_push_name_scope(Instruction* currentInstruction)
 {
     emitGetVirtualRegister(currentInstruction[2].u.operand, regT0);
-    callOperation(operationPushNameScope, &m_codeBlock->identifier(currentInstruction[1].u.operand), regT0, currentInstruction[3].u.operand);
+    callOperation(operationPushNameScope, &m_codeBlock->identifier(currentInstruction[1].u.operand), regT0, currentInstruction[3].u.operand, currentInstruction[4].u.operand);
 }
 
 void JIT::emit_op_catch(Instruction* currentInstruction)
index 0d60f2f..1c85a51 100644 (file)
@@ -805,7 +805,7 @@ void JIT::emitSlow_op_to_number(Instruction* currentInstruction, Vector<SlowCase
 void JIT::emit_op_push_name_scope(Instruction* currentInstruction)
 {
     emitLoad(currentInstruction[2].u.operand, regT1, regT0);
-    callOperation(operationPushNameScope, &m_codeBlock->identifier(currentInstruction[1].u.operand), regT1, regT0, currentInstruction[3].u.operand);
+    callOperation(operationPushNameScope, &m_codeBlock->identifier(currentInstruction[1].u.operand), regT1, regT0, currentInstruction[3].u.operand, currentInstruction[4].u.operand);
 }
 
 void JIT::emit_op_catch(Instruction* currentInstruction)
index 3da0cde..088dff9 100644 (file)
@@ -1308,12 +1308,13 @@ void JIT_OPERATION operationPutGetterSetter(ExecState* exec, JSCell* object, Ide
 }
 #endif
 
-void JIT_OPERATION operationPushNameScope(ExecState* exec, Identifier* identifier, EncodedJSValue encodedValue, int32_t attibutes)
+void JIT_OPERATION operationPushNameScope(ExecState* exec, Identifier* identifier, EncodedJSValue encodedValue, int32_t attibutes, int32_t type)
 {
     VM& vm = exec->vm();
     NativeCallFrameTracer tracer(&vm, exec);
 
-    JSNameScope* scope = JSNameScope::create(exec, *identifier, JSValue::decode(encodedValue), attibutes);
+    JSNameScope::Type scopeType = static_cast<JSNameScope::Type>(type);
+    JSNameScope* scope = JSNameScope::create(exec, *identifier, JSValue::decode(encodedValue), attibutes, scopeType);
 
     exec->setScope(scope);
 }
index 0bfbd59..0e1e05d 100644 (file)
@@ -164,7 +164,7 @@ typedef void JIT_OPERATION (*V_JITOperation_ECJJ)(ExecState*, JSCell*, EncodedJS
 typedef void JIT_OPERATION (*V_JITOperation_ECPSPS)(ExecState*, JSCell*, void*, size_t, void*, size_t);
 typedef void JIT_OPERATION (*V_JITOperation_ECZ)(ExecState*, JSCell*, int32_t);
 typedef void JIT_OPERATION (*V_JITOperation_ECC)(ExecState*, JSCell*, JSCell*);
-typedef void JIT_OPERATION (*V_JITOperation_EIdJZ)(ExecState*, Identifier*, EncodedJSValue, int32_t);
+typedef void JIT_OPERATION (*V_JITOperation_EIdJZZ)(ExecState*, Identifier*, EncodedJSValue, int32_t, int32_t);
 typedef void JIT_OPERATION (*V_JITOperation_EJ)(ExecState*, EncodedJSValue);
 typedef void JIT_OPERATION (*V_JITOperation_EJCI)(ExecState*, EncodedJSValue, JSCell*, StringImpl*);
 typedef void JIT_OPERATION (*V_JITOperation_EJIdJJ)(ExecState*, EncodedJSValue, Identifier*, EncodedJSValue, EncodedJSValue);
@@ -277,7 +277,7 @@ void JIT_OPERATION operationPutGetterSetter(ExecState*, EncodedJSValue, Identifi
 #else
 void JIT_OPERATION operationPutGetterSetter(ExecState*, JSCell*, Identifier*, JSCell*, JSCell*) WTF_INTERNAL;
 #endif
-void JIT_OPERATION operationPushNameScope(ExecState*, Identifier*, EncodedJSValue, int32_t) WTF_INTERNAL;
+void JIT_OPERATION operationPushNameScope(ExecState*, Identifier*, EncodedJSValue, int32_t, int32_t) WTF_INTERNAL;
 void JIT_OPERATION operationPushWithScope(ExecState*, EncodedJSValue) WTF_INTERNAL;
 void JIT_OPERATION operationPopScope(ExecState*) WTF_INTERNAL;
 void JIT_OPERATION operationProfileDidCall(ExecState*, EncodedJSValue) WTF_INTERNAL;
index 20c13a2..ebc76b0 100644 (file)
@@ -1300,7 +1300,8 @@ LLINT_SLOW_PATH_DECL(slow_path_push_name_scope)
 {
     LLINT_BEGIN();
     CodeBlock* codeBlock = exec->codeBlock();
-    JSNameScope* scope = JSNameScope::create(exec, codeBlock->identifier(pc[1].u.operand), LLINT_OP(2).jsValue(), pc[3].u.operand);
+    JSNameScope::Type type = static_cast<JSNameScope::Type>(pc[4].u.operand);
+    JSNameScope* scope = JSNameScope::create(exec, codeBlock->identifier(pc[1].u.operand), LLINT_OP(2).jsValue(), pc[3].u.operand, type);
     exec->setScope(scope);
     LLINT_END();
 }
index 13944b6..3347ae7 100644 (file)
@@ -1246,7 +1246,7 @@ _llint_op_pop_scope:
 _llint_op_push_name_scope:
     traceExecution()
     callSlowPath(_llint_slow_path_push_name_scope)
-    dispatch(4)
+    dispatch(5)
 
 
 _llint_op_throw:
index 43643c0..dc37719 100644 (file)
@@ -116,7 +116,7 @@ void JSFunction::addNameScopeIfNeeded(VM& vm)
         return;
     if (!functionNameScopeIsDynamic(executable->usesEval(), executable->isStrictMode()))
         return;
-    setScope(vm, JSNameScope::create(vm, scope()->globalObject(), executable->name(), this, ReadOnly | DontDelete, scope()));
+    setScope(vm, JSNameScope::create(vm, scope()->globalObject(), executable->name(), this, ReadOnly | DontDelete, scope(), JSNameScope::FunctionNameScope));
 }
 
 JSFunction* JSFunction::createBuiltinFunction(VM& vm, FunctionExecutable* executable, JSGlobalObject* globalObject)
index f2046c7..2775346 100644 (file)
@@ -36,17 +36,22 @@ class JSNameScope : public JSEnvironmentRecord {
 public:
     typedef JSEnvironmentRecord Base;
 
-    static JSNameScope* create(ExecState* exec, const Identifier& identifier, JSValue value, unsigned attributes)
+    enum Type {
+        CatchScope,
+        FunctionNameScope
+    };
+
+    static JSNameScope* create(ExecState* exec, const Identifier& identifier, JSValue value, unsigned attributes, Type type)
     {
         VM& vm = exec->vm();
-        JSNameScope* scopeObject = new (NotNull, allocateCell<JSNameScope>(vm.heap)) JSNameScope(vm, exec->lexicalGlobalObject(), exec->scope());
+        JSNameScope* scopeObject = new (NotNull, allocateCell<JSNameScope>(vm.heap)) JSNameScope(vm, exec->lexicalGlobalObject(), exec->scope(), type);
         scopeObject->finishCreation(vm, identifier, value, attributes);
         return scopeObject;
     }
 
-    static JSNameScope* create(VM& vm, JSGlobalObject* globalObject, const Identifier& identifier, JSValue value, unsigned attributes, JSScope* next)
+    static JSNameScope* create(VM& vm, JSGlobalObject* globalObject, const Identifier& identifier, JSValue value, unsigned attributes, JSScope* next, Type type)
     {
-        JSNameScope* scopeObject = new (NotNull, allocateCell<JSNameScope>(vm.heap)) JSNameScope(vm, globalObject, next);
+        JSNameScope* scopeObject = new (NotNull, allocateCell<JSNameScope>(vm.heap)) JSNameScope(vm, globalObject, next, type);
         scopeObject->finishCreation(vm, identifier, value, attributes);
         return scopeObject;
     }
@@ -60,6 +65,9 @@ public:
 
     DECLARE_INFO;
 
+    bool isFunctionNameScope() { return m_type == FunctionNameScope; }
+    bool isCatchScope() { return m_type == CatchScope; }
+
 protected:
     void finishCreation(VM& vm, const Identifier& identifier, JSValue value, unsigned attributes)
     {
@@ -71,17 +79,19 @@ protected:
     static const unsigned StructureFlags = OverridesGetOwnPropertySlot | Base::StructureFlags;
 
 private:
-    JSNameScope(VM& vm, JSGlobalObject* globalObject, JSScope* next)
+    JSNameScope(VM& vm, JSGlobalObject* globalObject, JSScope* next, Type type)
         : Base(
             vm,
             globalObject->nameScopeStructure(),
             reinterpret_cast<Register*>(&m_registerStore + 1),
             next
         )
+        , m_type(type)
     {
     }
 
     WriteBarrier<Unknown> m_registerStore;
+    Type m_type;
 };
 
 }
index 85c46d9..87b2e02 100644 (file)
@@ -1,3 +1,16 @@
+2014-10-02  Mark Lam  <mark.lam@apple.com>
+
+        Fixed the Inspector to be able to properly distinguish between scope types.
+        <https://webkit.org/b/137279>
+
+        Reviewed by Geoffrey Garen and Joseph Pecoraro.
+
+        * Localizations/en.lproj/localizedStrings.js:
+        * UserInterface/Controllers/DebuggerManager.js:
+        * UserInterface/Models/ScopeChainNode.js:
+        * UserInterface/Views/ScopeChainDetailsSidebarPanel.js:
+        - Added handling of the FunctionNameScope case.
+
 2014-10-02  Andres Gomez  <agomez@igalia.com>
 
         Web Inspector: [GTK] Missing icons and enhancing the proportion and visibility of some icons
index a2b4911..806034b 100644 (file)
Binary files a/Source/WebInspectorUI/Localizations/en.lproj/localizedStrings.js and b/Source/WebInspectorUI/Localizations/en.lproj/localizedStrings.js differ
index 1732d33..b49a1e5 100644 (file)
@@ -572,6 +572,9 @@ WebInspector.DebuggerManager.prototype = {
         case "catch":
             type = WebInspector.ScopeChainNode.Type.Catch;
             break;
+        case "functionName":
+            type = WebInspector.ScopeChainNode.Type.FunctionName;
+            break;
         default:
             console.error("Unknown type: " + payload.type);
         }
index 0ba8bc7..4781c23 100644 (file)
@@ -42,7 +42,8 @@ WebInspector.ScopeChainNode.Type = {
     Global: "scope-chain-type-global",
     With: "scope-chain-type-with",
     Closure: "scope-chain-type-closure",
-    Catch: "scope-chain-type-catch"
+    Catch: "scope-chain-type-catch",
+    FunctionName: "scope-chain-type-functionName"
 };
 
 WebInspector.ScopeChainNode.prototype = {
index ae9fdce..d0ffc65 100644 (file)
@@ -121,6 +121,12 @@ WebInspector.ScopeChainDetailsSidebarPanel.prototype = {
                     collapsedByDefault = false;
                     break;
 
+                case WebInspector.ScopeChainNode.Type.FunctionName:
+                    title = WebInspector.UIString("Function Name Variable");
+                    dontHighlightNonEnumerableProperties = true;
+                    collapsedByDefault = true;
+                    break;
+
                 case WebInspector.ScopeChainNode.Type.With:
                     title = WebInspector.UIString("With Object Properties");
                     collapsedByDefault = foundLocalScope;