Rename activation to be more in line with spec language
[WebKit-https.git] / Source / JavaScriptCore / runtime / JSScope.h
index 2aa9cc6..e753931 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2012 Apple Inc. All Rights Reserved.
+ * Copyright (C) 2012, 2013, 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
 namespace JSC {
 
 class ScopeChainIterator;
+class VariableWatchpointSet;
+
+enum ResolveMode {
+    ThrowIfNotFound,
+    DoNotThrowIfNotFound
+};
+
+enum ResolveType {
+    // Lexical scope guaranteed a certain type of variable access.
+    GlobalProperty,
+    GlobalVar,
+    ClosureVar,
+
+    // Ditto, but at least one intervening scope used non-strict eval, which
+    // can inject an intercepting var delcaration at runtime.
+    GlobalPropertyWithVarInjectionChecks,
+    GlobalVarWithVarInjectionChecks,
+    ClosureVarWithVarInjectionChecks,
+
+    // Lexical scope didn't prove anything -- probably because of a 'with' scope.
+    Dynamic
+};
+
+const char* resolveModeName(ResolveMode mode);
+const char* resolveTypeName(ResolveType type);
+
+inline ResolveType makeType(ResolveType type, bool needsVarInjectionChecks)
+{
+    if (!needsVarInjectionChecks)
+        return type;
+
+    switch (type) {
+    case GlobalProperty:
+        return GlobalPropertyWithVarInjectionChecks;
+    case GlobalVar:
+        return GlobalVarWithVarInjectionChecks;
+    case ClosureVar:
+        return ClosureVarWithVarInjectionChecks;
+    case GlobalPropertyWithVarInjectionChecks:
+    case GlobalVarWithVarInjectionChecks:
+    case ClosureVarWithVarInjectionChecks:
+    case Dynamic:
+        return type;
+    }
+
+    RELEASE_ASSERT_NOT_REACHED();
+    return type;
+}
+
+inline bool needsVarInjectionChecks(ResolveType type)
+{
+    switch (type) {
+    case GlobalProperty:
+    case GlobalVar:
+    case ClosureVar:
+        return false;
+    case GlobalPropertyWithVarInjectionChecks:
+    case GlobalVarWithVarInjectionChecks:
+    case ClosureVarWithVarInjectionChecks:
+    case Dynamic:
+        return true;
+    default:
+        RELEASE_ASSERT_NOT_REACHED();
+        return true;
+    }
+}
+
+struct ResolveOp {
+    ResolveOp(ResolveType type, size_t depth, Structure* structure, JSLexicalEnvironment* lexicalEnvironment, VariableWatchpointSet* watchpointSet, uintptr_t operand)
+        : type(type)
+        , depth(depth)
+        , structure(structure)
+        , lexicalEnvironment(lexicalEnvironment)
+        , watchpointSet(watchpointSet)
+        , operand(operand)
+    {
+    }
+
+    ResolveType type;
+    size_t depth;
+    Structure* structure;
+    JSLexicalEnvironment* lexicalEnvironment;
+    VariableWatchpointSet* watchpointSet;
+    uintptr_t operand;
+};
+
+class ResolveModeAndType {
+    typedef unsigned Operand;
+public:
+    static const size_t shift = sizeof(Operand) * 8 / 2;
+    static const unsigned mask = (1 << shift) - 1;
+
+    ResolveModeAndType(ResolveMode resolveMode, ResolveType resolveType)
+        : m_operand((resolveMode << shift) | resolveType)
+    {
+    }
+
+    explicit ResolveModeAndType(unsigned operand)
+        : m_operand(operand)
+    {
+    }
+
+    ResolveMode mode() { return static_cast<ResolveMode>(m_operand >> shift); }
+    ResolveType type() { return static_cast<ResolveType>(m_operand & mask); }
+    unsigned operand() { return m_operand; }
+
+private:
+    Operand m_operand;
+};
+
+enum GetOrPut { Get, Put };
 
 class JSScope : public JSNonFinalObject {
 public:
@@ -39,52 +150,32 @@ public:
     friend class LLIntOffsetsExtractor;
     static size_t offsetOfNext();
 
-    JS_EXPORT_PRIVATE static JSObject* objectAtScope(JSScope*);
-
-    static JSValue resolve(CallFrame*, const Identifier&);
-    static JSValue resolveSkip(CallFrame*, const Identifier&, int skip);
-    static JSValue resolveGlobal(
-        CallFrame*,
-        const Identifier&,
-        JSGlobalObject* globalObject,
-        WriteBarrierBase<Structure>* cachedStructure,
-        PropertyOffset* cachedOffset
-    );
-    static JSValue resolveGlobalDynamic(
-        CallFrame*,
-        const Identifier&,
-        int skip,
-        WriteBarrierBase<Structure>* cachedStructure,
-        PropertyOffset* cachedOffset
-    );
-    static JSValue resolveBase(CallFrame*, const Identifier&, bool isStrict);
-    static JSValue resolveWithBase(CallFrame*, const Identifier&, Register* base);
-    static JSValue resolveWithThis(CallFrame*, const Identifier&, Register* base);
+    static JSObject* objectAtScope(JSScope*);
 
-    static void visitChildren(JSCell*, SlotVisitor&);
+    static JSValue resolve(ExecState*, JSScope*, const Identifier&);
+    static ResolveOp abstractResolve(ExecState*, bool hasTopActivation, JSScope*, const Identifier&, GetOrPut, ResolveType);
 
-    bool isDynamicScope(bool& requiresDynamicChecks) const;
+    static void visitChildren(JSCell*, SlotVisitor&);
 
     ScopeChainIterator begin();
     ScopeChainIterator end();
     JSScope* next();
-    int localDepth();
+    int depth();
 
     JSGlobalObject* globalObject();
-    JSGlobalData* globalData();
+    VM* vm();
     JSObject* globalThis();
 
 protected:
-    JSScope(JSGlobalData&, Structure*, JSScope* next);
-    static const unsigned StructureFlags = OverridesVisitChildren | Base::StructureFlags;
+    JSScope(VM&, Structure*, JSScope* next);
 
 private:
     WriteBarrier<JSScope> m_next;
 };
 
-inline JSScope::JSScope(JSGlobalData& globalData, Structure* structure, JSScope* next)
-    : Base(globalData, structure)
-    , m_next(globalData, this, next, WriteBarrier<JSScope>::MayBeNull)
+inline JSScope::JSScope(VM& vm, Structure* structure, JSScope* next)
+    : Base(vm, structure)
+    , m_next(vm, this, next, WriteBarrier<JSScope>::MayBeNull)
 {
 }
 
@@ -129,9 +220,9 @@ inline JSGlobalObject* JSScope::globalObject()
     return structure()->globalObject();
 }
 
-inline JSGlobalData* JSScope::globalData()
+inline VM* JSScope::vm()
 { 
-    return MarkedBlock::blockFor(this)->globalData();
+    return MarkedBlock::blockFor(this)->vm();
 }
 
 inline Register& Register::operator=(JSScope* scope)
@@ -145,10 +236,10 @@ inline JSScope* Register::scope() const
     return jsCast<JSScope*>(jsValue());
 }
 
-inline JSGlobalData& ExecState::globalData() const
+inline VM& ExecState::vm() const
 {
-    ASSERT(scope()->globalData());
-    return *scope()->globalData();
+    ASSERT(scope()->vm());
+    return *scope()->vm();
 }
 
 inline JSGlobalObject* ExecState::lexicalGlobalObject() const