We should have different JSTypes for JSGlobalLexicalEnvironment and JSLexicalEnvironm...
authorsbarati@apple.com <sbarati@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Tue, 15 Mar 2016 20:41:00 +0000 (20:41 +0000)
committersbarati@apple.com <sbarati@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Tue, 15 Mar 2016 20:41:00 +0000 (20:41 +0000)
https://bugs.webkit.org/show_bug.cgi?id=152406

Reviewed by Mark Lam.

This makes testing for a JSGlobalLexicalEnvironment faster
because we can just check the Cell's type instead of using
jsDynamicCast. I also changed code that does jsDynamicCast<JSGlobalObject*>
instead of isGlobalObject().

* interpreter/Interpreter.cpp:
(JSC::Interpreter::execute):
* jit/JITOperations.cpp:
* llint/LLIntSlowPaths.cpp:
(JSC::LLInt::LLINT_SLOW_PATH_DECL):
* runtime/CommonSlowPaths.cpp:
(JSC::SLOW_PATH_DECL):
* runtime/CommonSlowPaths.h:
(JSC::CommonSlowPaths::tryCachePutToScopeGlobal):
(JSC::CommonSlowPaths::tryCacheGetFromScopeGlobal):
* runtime/JSGlobalLexicalEnvironment.h:
(JSC::JSGlobalLexicalEnvironment::createStructure):
* runtime/JSLexicalEnvironment.h:
(JSC::JSLexicalEnvironment::createStructure):
(JSC::JSLexicalEnvironment::JSLexicalEnvironment):
* runtime/JSModuleEnvironment.h:
(JSC::JSModuleEnvironment::createStructure):
(JSC::JSModuleEnvironment::offsetOfModuleRecord):
* runtime/JSObject.h:
(JSC::JSObject::isGlobalObject):
(JSC::JSObject::isJSLexicalEnvironment):
(JSC::JSObject::isGlobalLexicalEnvironment):
(JSC::JSObject::isErrorInstance):
* runtime/JSScope.cpp:
(JSC::abstractAccess):
(JSC::isUnscopable):
(JSC::JSScope::resolve):
(JSC::JSScope::collectVariablesUnderTDZ):
(JSC::JSScope::isVarScope):
(JSC::JSScope::isLexicalScope):
(JSC::JSScope::isModuleScope):
(JSC::JSScope::isCatchScope):
(JSC::JSScope::isFunctionNameScopeObject):
(JSC::JSScope::isNestedLexicalScope):
(JSC::JSScope::constantScopeForCodeBlock):
(JSC::isScopeType): Deleted.
(JSC::JSScope::isGlobalLexicalEnvironment): Deleted.
* runtime/JSScope.h:
* runtime/JSType.h:

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

13 files changed:
Source/JavaScriptCore/ChangeLog
Source/JavaScriptCore/interpreter/Interpreter.cpp
Source/JavaScriptCore/jit/JITOperations.cpp
Source/JavaScriptCore/llint/LLIntSlowPaths.cpp
Source/JavaScriptCore/runtime/CommonSlowPaths.cpp
Source/JavaScriptCore/runtime/CommonSlowPaths.h
Source/JavaScriptCore/runtime/JSGlobalLexicalEnvironment.h
Source/JavaScriptCore/runtime/JSLexicalEnvironment.h
Source/JavaScriptCore/runtime/JSModuleEnvironment.h
Source/JavaScriptCore/runtime/JSObject.h
Source/JavaScriptCore/runtime/JSScope.cpp
Source/JavaScriptCore/runtime/JSScope.h
Source/JavaScriptCore/runtime/JSType.h

index a0c3b7e..4a742d6 100644 (file)
@@ -1,3 +1,55 @@
+2016-03-15  Saam Barati  <sbarati@apple.com>
+
+        We should have different JSTypes for JSGlobalLexicalEnvironment and JSLexicalEnvironment and JSModuleEnvironment
+        https://bugs.webkit.org/show_bug.cgi?id=152406
+
+        Reviewed by Mark Lam.
+
+        This makes testing for a JSGlobalLexicalEnvironment faster
+        because we can just check the Cell's type instead of using
+        jsDynamicCast. I also changed code that does jsDynamicCast<JSGlobalObject*>
+        instead of isGlobalObject().
+
+        * interpreter/Interpreter.cpp:
+        (JSC::Interpreter::execute):
+        * jit/JITOperations.cpp:
+        * llint/LLIntSlowPaths.cpp:
+        (JSC::LLInt::LLINT_SLOW_PATH_DECL):
+        * runtime/CommonSlowPaths.cpp:
+        (JSC::SLOW_PATH_DECL):
+        * runtime/CommonSlowPaths.h:
+        (JSC::CommonSlowPaths::tryCachePutToScopeGlobal):
+        (JSC::CommonSlowPaths::tryCacheGetFromScopeGlobal):
+        * runtime/JSGlobalLexicalEnvironment.h:
+        (JSC::JSGlobalLexicalEnvironment::createStructure):
+        * runtime/JSLexicalEnvironment.h:
+        (JSC::JSLexicalEnvironment::createStructure):
+        (JSC::JSLexicalEnvironment::JSLexicalEnvironment):
+        * runtime/JSModuleEnvironment.h:
+        (JSC::JSModuleEnvironment::createStructure):
+        (JSC::JSModuleEnvironment::offsetOfModuleRecord):
+        * runtime/JSObject.h:
+        (JSC::JSObject::isGlobalObject):
+        (JSC::JSObject::isJSLexicalEnvironment):
+        (JSC::JSObject::isGlobalLexicalEnvironment):
+        (JSC::JSObject::isErrorInstance):
+        * runtime/JSScope.cpp:
+        (JSC::abstractAccess):
+        (JSC::isUnscopable):
+        (JSC::JSScope::resolve):
+        (JSC::JSScope::collectVariablesUnderTDZ):
+        (JSC::JSScope::isVarScope):
+        (JSC::JSScope::isLexicalScope):
+        (JSC::JSScope::isModuleScope):
+        (JSC::JSScope::isCatchScope):
+        (JSC::JSScope::isFunctionNameScopeObject):
+        (JSC::JSScope::isNestedLexicalScope):
+        (JSC::JSScope::constantScopeForCodeBlock):
+        (JSC::isScopeType): Deleted.
+        (JSC::JSScope::isGlobalLexicalEnvironment): Deleted.
+        * runtime/JSScope.h:
+        * runtime/JSType.h:
+
 2016-03-15  Filip Pizlo  <fpizlo@apple.com>
 
         Remove the Baker barrier from JSC
index 233fd1c..8f04361 100644 (file)
@@ -1202,7 +1202,8 @@ JSValue Interpreter::execute(EvalExecutable* eval, CallFrame* callFrame, JSValue
                 variableObject = node;
                 break;
             } 
-            if (JSLexicalEnvironment* lexicalEnvironment = jsDynamicCast<JSLexicalEnvironment*>(node)) {
+            if (node->isJSLexicalEnvironment()) {
+                JSLexicalEnvironment* lexicalEnvironment = jsCast<JSLexicalEnvironment*>(node);
                 if (lexicalEnvironment->symbolTable()->scopeType() == SymbolTable::ScopeType::VarScope) {
                     variableObject = node;
                     break;
index 46a9746..2d7b93b 100644 (file)
@@ -1891,7 +1891,7 @@ EncodedJSValue JIT_OPERATION operationGetFromScope(ExecState* exec, Instruction*
     }
 
     JSValue result = JSValue();
-    if (jsDynamicCast<JSGlobalLexicalEnvironment*>(scope)) {
+    if (scope->isGlobalLexicalEnvironment()) {
         // When we can't statically prove we need a TDZ check, we must perform the check on the slow path.
         result = slot.getValue(exec, ident);
         if (result == jsTDZValue()) {
@@ -1932,7 +1932,7 @@ void JIT_OPERATION operationPutToScope(ExecState* exec, Instruction* bytecodePC)
 
     bool hasProperty = scope->hasProperty(exec, ident);
     if (hasProperty
-        && jsDynamicCast<JSGlobalLexicalEnvironment*>(scope)
+        && scope->isGlobalLexicalEnvironment()
         && getPutInfo.initializationMode() != Initialization) {
         // When we can't statically prove we need a TDZ check, we must perform the check on the slow path.
         PropertySlot slot(scope, PropertySlot::InternalMethodType::Get);
index 303a709..846bdba 100644 (file)
@@ -1422,7 +1422,7 @@ LLINT_SLOW_PATH_DECL(slow_path_get_from_scope)
     }
 
     JSValue result = JSValue();
-    if (jsDynamicCast<JSGlobalLexicalEnvironment*>(scope)) {
+    if (scope->isGlobalLexicalEnvironment()) {
         // When we can't statically prove we need a TDZ check, we must perform the check on the slow path.
         result = slot.getValue(exec, ident);
         if (result == jsTDZValue())
@@ -1459,7 +1459,7 @@ LLINT_SLOW_PATH_DECL(slow_path_put_to_scope)
 
     bool hasProperty = scope->hasProperty(exec, ident);
     if (hasProperty
-        && jsDynamicCast<JSGlobalLexicalEnvironment*>(scope)
+        && scope->isGlobalLexicalEnvironment()
         && getPutInfo.initializationMode() != Initialization) {
         // When we can't statically prove we need a TDZ check, we must perform the check on the slow path.
         PropertySlot slot(scope, PropertySlot::InternalMethodType::Get);
index 4b63d4e..a19e5e2 100644 (file)
@@ -769,7 +769,7 @@ SLOW_PATH_DECL(slow_path_resolve_scope)
     BEGIN();
     const Identifier& ident = exec->codeBlock()->identifier(pc[3].u.operand);
     JSScope* scope = exec->uncheckedR(pc[2].u.operand).Register::scope();
-    JSValue resolvedScope = JSScope::resolve(exec, scope, ident);
+    JSObject* resolvedScope = JSScope::resolve(exec, scope, ident);
 
     ResolveType resolveType = static_cast<ResolveType>(pc[4].u.operand);
 
@@ -777,13 +777,8 @@ SLOW_PATH_DECL(slow_path_resolve_scope)
     ASSERT(resolveType != ModuleVar);
 
     if (resolveType == UnresolvedProperty || resolveType == UnresolvedPropertyWithVarInjectionChecks) {
-        if (JSGlobalLexicalEnvironment* globalLexicalEnvironment = jsDynamicCast<JSGlobalLexicalEnvironment*>(resolvedScope)) {
-            if (resolveType == UnresolvedProperty)
-                pc[4].u.operand = GlobalLexicalVar;
-            else
-                pc[4].u.operand = GlobalLexicalVarWithVarInjectionChecks;
-            pc[6].u.pointer = globalLexicalEnvironment;
-        } else if (JSGlobalObject* globalObject = jsDynamicCast<JSGlobalObject*>(resolvedScope)) {
+        if (resolvedScope->isGlobalObject()) {
+            JSGlobalObject* globalObject = jsCast<JSGlobalObject*>(resolvedScope);
             if (globalObject->hasProperty(exec, ident)) {
                 if (resolveType == UnresolvedProperty)
                     pc[4].u.operand = GlobalProperty;
@@ -792,6 +787,13 @@ SLOW_PATH_DECL(slow_path_resolve_scope)
 
                 pc[6].u.pointer = globalObject;
             }
+        } else if (resolvedScope->isGlobalLexicalEnvironment()) {
+            JSGlobalLexicalEnvironment* globalLexicalEnvironment = jsCast<JSGlobalLexicalEnvironment*>(resolvedScope);
+            if (resolveType == UnresolvedProperty)
+                pc[4].u.operand = GlobalLexicalVar;
+            else
+                pc[4].u.operand = GlobalLexicalVarWithVarInjectionChecks;
+            pc[6].u.pointer = globalLexicalEnvironment;
         }
     }
 
index 705d861..43a88c4 100644 (file)
@@ -100,18 +100,19 @@ inline void tryCachePutToScopeGlobal(
         return;
 
     if (resolveType == UnresolvedProperty || resolveType == UnresolvedPropertyWithVarInjectionChecks) {
-        if (JSGlobalLexicalEnvironment* globalLexicalEnvironment = jsDynamicCast<JSGlobalLexicalEnvironment*>(scope)) {
+        if (scope->isGlobalObject()) {
+            ResolveType newResolveType = resolveType == UnresolvedProperty ? GlobalProperty : GlobalPropertyWithVarInjectionChecks;
+            resolveType = newResolveType;
+            getPutInfo = GetPutInfo(getPutInfo.resolveMode(), newResolveType, getPutInfo.initializationMode());
+            pc[4].u.operand = getPutInfo.operand();
+        } else if (scope->isGlobalLexicalEnvironment()) {
+            JSGlobalLexicalEnvironment* globalLexicalEnvironment = jsCast<JSGlobalLexicalEnvironment*>(scope);
             ResolveType newResolveType = resolveType == UnresolvedProperty ? GlobalLexicalVar : GlobalLexicalVarWithVarInjectionChecks;
             pc[4].u.operand = GetPutInfo(getPutInfo.resolveMode(), newResolveType, getPutInfo.initializationMode()).operand();
             SymbolTableEntry entry = globalLexicalEnvironment->symbolTable()->get(ident.impl());
             ASSERT(!entry.isNull());
             pc[5].u.watchpointSet = entry.watchpointSet();
             pc[6].u.pointer = static_cast<void*>(globalLexicalEnvironment->variableAt(entry.scopeOffset()).slot());
-        } else if (jsDynamicCast<JSGlobalObject*>(scope)) {
-            ResolveType newResolveType = resolveType == UnresolvedProperty ? GlobalProperty : GlobalPropertyWithVarInjectionChecks;
-            resolveType = newResolveType;
-            getPutInfo = GetPutInfo(getPutInfo.resolveMode(), newResolveType, getPutInfo.initializationMode());
-            pc[4].u.operand = getPutInfo.operand();
         }
     }
     
@@ -142,17 +143,18 @@ inline void tryCacheGetFromScopeGlobal(
     ResolveType resolveType = getPutInfo.resolveType();
 
     if (resolveType == UnresolvedProperty || resolveType == UnresolvedPropertyWithVarInjectionChecks) {
-        if (JSGlobalLexicalEnvironment* globalLexicalEnvironment = jsDynamicCast<JSGlobalLexicalEnvironment*>(scope)) {
+        if (scope->isGlobalObject()) {
+            ResolveType newResolveType = resolveType == UnresolvedProperty ? GlobalProperty : GlobalPropertyWithVarInjectionChecks;
+            resolveType = newResolveType; // Allow below caching mechanism to kick in.
+            pc[4].u.operand = GetPutInfo(getPutInfo.resolveMode(), newResolveType, getPutInfo.initializationMode()).operand();
+        } else if (scope->isGlobalLexicalEnvironment()) {
+            JSGlobalLexicalEnvironment* globalLexicalEnvironment = jsCast<JSGlobalLexicalEnvironment*>(scope);
             ResolveType newResolveType = resolveType == UnresolvedProperty ? GlobalLexicalVar : GlobalLexicalVarWithVarInjectionChecks;
             pc[4].u.operand = GetPutInfo(getPutInfo.resolveMode(), newResolveType, getPutInfo.initializationMode()).operand();
             SymbolTableEntry entry = globalLexicalEnvironment->symbolTable()->get(ident.impl());
             ASSERT(!entry.isNull());
             pc[5].u.watchpointSet = entry.watchpointSet();
             pc[6].u.pointer = static_cast<void*>(globalLexicalEnvironment->variableAt(entry.scopeOffset()).slot());
-        } else if (jsDynamicCast<JSGlobalObject*>(scope)) {
-            ResolveType newResolveType = resolveType == UnresolvedProperty ? GlobalProperty : GlobalPropertyWithVarInjectionChecks;
-            resolveType = newResolveType; // Allow below caching mechanism to kick in.
-            pc[4].u.operand = GetPutInfo(getPutInfo.resolveMode(), newResolveType, getPutInfo.initializationMode()).operand();
         }
     }
 
index 8d4fd2e..40beed4 100644 (file)
@@ -55,7 +55,7 @@ public:
 
     static Structure* createStructure(VM& vm, JSGlobalObject* globalObject)
     {
-        return Structure::create(vm, globalObject, jsNull(), TypeInfo(ClosureObjectType, StructureFlags), info());
+        return Structure::create(vm, globalObject, jsNull(), TypeInfo(GlobalLexicalEnvironmentType, StructureFlags), info());
     }
 
 protected:
index 515e117..5cd4186 100644 (file)
@@ -75,7 +75,7 @@ public:
 
     DECLARE_INFO;
 
-    static Structure* createStructure(VM& vm, JSGlobalObject* globalObject) { return Structure::create(vm, globalObject, jsNull(), TypeInfo(ClosureObjectType, StructureFlags), info()); }
+    static Structure* createStructure(VM& vm, JSGlobalObject* globalObject) { return Structure::create(vm, globalObject, jsNull(), TypeInfo(LexicalEnvironmentType, StructureFlags), info()); }
 };
 
 inline JSLexicalEnvironment::JSLexicalEnvironment(VM& vm, Structure* structure, JSScope* currentScope, SymbolTable* symbolTable)
index 434bb7c..e8434dc 100644 (file)
@@ -55,7 +55,7 @@ public:
 
     static Structure* createStructure(VM& vm, JSGlobalObject* globalObject)
     {
-        return Structure::create(vm, globalObject, jsNull(), TypeInfo(ObjectType, StructureFlags), info());
+        return Structure::create(vm, globalObject, jsNull(), TypeInfo(ModuleEnvironmentType, StructureFlags), info());
     }
 
     static size_t offsetOfModuleRecord(SymbolTable* symbolTable)
index 5d7fa38..0b7258a 100644 (file)
@@ -641,6 +641,8 @@ public:
     JS_EXPORT_PRIVATE static bool defineOwnProperty(JSObject*, ExecState*, PropertyName, const PropertyDescriptor&, bool shouldThrow);
 
     bool isGlobalObject() const;
+    bool isJSLexicalEnvironment() const;
+    bool isGlobalLexicalEnvironment() const;
     bool isErrorInstance() const;
     bool isWithScope() const;
 
@@ -1076,6 +1078,16 @@ inline bool JSObject::isGlobalObject() const
     return type() == GlobalObjectType;
 }
 
+inline bool JSObject::isJSLexicalEnvironment() const
+{
+    return type() == LexicalEnvironmentType || type() == ModuleEnvironmentType;
+}
+
+inline bool JSObject::isGlobalLexicalEnvironment() const
+{
+    return type() == GlobalLexicalEnvironmentType;
+}
+
 inline bool JSObject::isErrorInstance() const
 {
     return type() == ErrorInstanceType;
index b13f3ff..b1cd79a 100644 (file)
@@ -48,7 +48,8 @@ void JSScope::visitChildren(JSCell* cell, SlotVisitor& visitor)
 // Returns true if we found enough information to terminate optimization.
 static inline bool abstractAccess(ExecState* exec, JSScope* scope, const Identifier& ident, GetOrPut getOrPut, size_t depth, bool& needsVarInjectionChecks, ResolveOp& op, InitializationMode initializationMode)
 {
-    if (JSLexicalEnvironment* lexicalEnvironment = jsDynamicCast<JSLexicalEnvironment*>(scope)) {
+    if (scope->isJSLexicalEnvironment()) {
+        JSLexicalEnvironment* lexicalEnvironment = jsCast<JSLexicalEnvironment*>(scope);
         if (ident == exec->propertyNames().arguments) {
             // We know the property will be at this lexical environment scope, but we don't know how to cache it.
             op = ResolveOp(Dynamic, 0, 0, 0, 0, 0);
@@ -67,7 +68,8 @@ static inline bool abstractAccess(ExecState* exec, JSScope* scope, const Identif
             return true;
         }
 
-        if (JSModuleEnvironment* moduleEnvironment = jsDynamicCast<JSModuleEnvironment*>(scope)) {
+        if (scope->type() == ModuleEnvironmentType) {
+            JSModuleEnvironment* moduleEnvironment = jsCast<JSModuleEnvironment*>(scope);
             JSModuleRecord* moduleRecord = moduleEnvironment->moduleRecord();
             JSModuleRecord::Resolution resolution = moduleRecord->resolveImport(exec, ident);
             if (resolution.type == JSModuleRecord::Resolution::Type::Resolved) {
@@ -85,7 +87,8 @@ static inline bool abstractAccess(ExecState* exec, JSScope* scope, const Identif
         return false;
     }
 
-    if (JSGlobalLexicalEnvironment* globalLexicalEnvironment = jsDynamicCast<JSGlobalLexicalEnvironment*>(scope)) {
+    if (scope->isGlobalLexicalEnvironment()) {
+        JSGlobalLexicalEnvironment* globalLexicalEnvironment = jsCast<JSGlobalLexicalEnvironment*>(scope);
         SymbolTableEntry entry = globalLexicalEnvironment->symbolTable()->get(ident.impl());
         if (!entry.isNull()) {
             if (getOrPut == Put && entry.isReadOnly() && initializationMode != Initialization) {
@@ -112,7 +115,8 @@ static inline bool abstractAccess(ExecState* exec, JSScope* scope, const Identif
         return false;
     }
 
-    if (JSGlobalObject* globalObject = jsDynamicCast<JSGlobalObject*>(scope)) {
+    if (scope->isGlobalObject()) {
+        JSGlobalObject* globalObject = jsCast<JSGlobalObject*>(scope);
         SymbolTableEntry entry = globalObject->symbolTable()->get(ident.impl());
         if (!entry.isNull()) {
             if (getOrPut == Put && entry.isReadOnly()) {
@@ -190,7 +194,7 @@ static inline bool isUnscopable(ExecState* exec, JSScope* scope, JSObject* objec
     return blocked.toBoolean(exec);
 }
 
-JSValue JSScope::resolve(ExecState* exec, JSScope* scope, const Identifier& ident)
+JSObject* JSScope::resolve(ExecState* exec, JSScope* scope, const Identifier& ident)
 {
     ScopeChainIterator end = scope->end();
     ScopeChainIterator it = scope->begin();
@@ -246,51 +250,44 @@ void JSScope::collectVariablesUnderTDZ(JSScope* scope, VariableEnvironment& resu
     }
 }
 
-template <typename EnvironmentType, SymbolTable::ScopeType scopeType>
-inline static bool isScopeType(JSScope* scope)
-{
-    EnvironmentType* environment = jsDynamicCast<EnvironmentType*>(scope);
-    if (!environment)
-        return false;
-
-    return environment->symbolTable()->scopeType() == scopeType;
-}
-
 bool JSScope::isVarScope()
 {
-    return isScopeType<JSLexicalEnvironment, SymbolTable::ScopeType::VarScope>(this);
+    if (type() != LexicalEnvironmentType)
+        return false;
+    return jsCast<JSLexicalEnvironment*>(this)->symbolTable()->scopeType() == SymbolTable::ScopeType::VarScope;
 }
 
 bool JSScope::isLexicalScope()
 {
-    return isScopeType<JSLexicalEnvironment, SymbolTable::ScopeType::LexicalScope>(this);
+    if (!isJSLexicalEnvironment())
+        return false;
+    return jsCast<JSLexicalEnvironment*>(this)->symbolTable()->scopeType() == SymbolTable::ScopeType::LexicalScope;
 }
 
 bool JSScope::isModuleScope()
 {
-    return isScopeType<JSModuleEnvironment, SymbolTable::ScopeType::LexicalScope>(this);
+    return type() == ModuleEnvironmentType;
 }
 
 bool JSScope::isCatchScope()
 {
-    return isScopeType<JSLexicalEnvironment, SymbolTable::ScopeType::CatchScope>(this);
+    if (type() != LexicalEnvironmentType)
+        return false;
+    return jsCast<JSLexicalEnvironment*>(this)->symbolTable()->scopeType() == SymbolTable::ScopeType::CatchScope;
 }
 
 bool JSScope::isFunctionNameScopeObject()
 {
-    return isScopeType<JSLexicalEnvironment, SymbolTable::ScopeType::FunctionNameScope>(this);
-}
-
-bool JSScope::isGlobalLexicalEnvironment()
-{
-    return isScopeType<JSGlobalLexicalEnvironment, SymbolTable::ScopeType::GlobalLexicalScope>(this);
+    if (type() != LexicalEnvironmentType)
+        return false;
+    return jsCast<JSLexicalEnvironment*>(this)->symbolTable()->scopeType() == SymbolTable::ScopeType::FunctionNameScope;
 }
 
 bool JSScope::isNestedLexicalScope()
 {
-    if (JSLexicalEnvironment* environment = jsDynamicCast<JSLexicalEnvironment*>(this))
-        return environment->symbolTable()->isNestedLexicalScope();
-    return false;
+    if (!isJSLexicalEnvironment())
+        return false;
+    return jsCast<JSLexicalEnvironment*>(this)->symbolTable()->isNestedLexicalScope();
 }
 
 JSScope* JSScope::constantScopeForCodeBlock(ResolveType type, CodeBlock* codeBlock)
index 4b17972..05de939 100644 (file)
@@ -45,7 +45,7 @@ public:
 
     static JSObject* objectAtScope(JSScope*);
 
-    static JSValue resolve(ExecState*, JSScope*, const Identifier&);
+    static JSObject* resolve(ExecState*, JSScope*, const Identifier&);
     static ResolveOp abstractResolve(ExecState*, size_t depthOffset, JSScope*, const Identifier&, GetOrPut, ResolveType, InitializationMode);
 
     static bool hasConstantScope(ResolveType);
@@ -58,7 +58,6 @@ public:
     bool isVarScope();
     bool isLexicalScope();
     bool isModuleScope();
-    bool isGlobalLexicalEnvironment();
     bool isCatchScope();
     bool isFunctionNameScopeObject();
 
index 9954a63..fff4042 100644 (file)
@@ -76,7 +76,9 @@ enum JSType : uint8_t {
     DataViewType,
 
     GlobalObjectType,
-    ClosureObjectType,
+    LexicalEnvironmentType,
+    GlobalLexicalEnvironmentType,
+    ModuleEnvironmentType,
     RegExpObjectType,
     ProxyObjectType,