diff options
Diffstat (limited to 'Source/JavaScriptCore/runtime/JSScope.h')
-rw-r--r-- | Source/JavaScriptCore/runtime/JSScope.h | 171 |
1 files changed, 171 insertions, 0 deletions
diff --git a/Source/JavaScriptCore/runtime/JSScope.h b/Source/JavaScriptCore/runtime/JSScope.h new file mode 100644 index 000000000..011aff57e --- /dev/null +++ b/Source/JavaScriptCore/runtime/JSScope.h @@ -0,0 +1,171 @@ +/* + * Copyright (C) 2012 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. + */ + +#ifndef JSScope_h +#define JSScope_h + +#include "JSObject.h" + +namespace JSC { + +class ScopeChainIterator; + +class JSScope : public JSNonFinalObject { +public: + typedef JSNonFinalObject Base; + + 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 void visitChildren(JSCell*, SlotVisitor&); + + bool isDynamicScope(bool& requiresDynamicChecks) const; + + ScopeChainIterator begin(); + ScopeChainIterator end(); + JSScope* next(); + int localDepth(); + + JSGlobalObject* globalObject(); + JSGlobalData* globalData(); + JSObject* globalThis(); + +protected: + JSScope(JSGlobalData&, Structure*, JSScope* next); + static const unsigned StructureFlags = OverridesVisitChildren | Base::StructureFlags; + +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) +{ +} + +class ScopeChainIterator { +public: + ScopeChainIterator(JSScope* node) + : m_node(node) + { + } + + JSObject* get() const { return JSScope::objectAtScope(m_node); } + JSObject* operator->() const { return JSScope::objectAtScope(m_node); } + + ScopeChainIterator& operator++() { m_node = m_node->next(); return *this; } + + // postfix ++ intentionally omitted + + bool operator==(const ScopeChainIterator& other) const { return m_node == other.m_node; } + bool operator!=(const ScopeChainIterator& other) const { return m_node != other.m_node; } + +private: + JSScope* m_node; +}; + +inline ScopeChainIterator JSScope::begin() +{ + return ScopeChainIterator(this); +} + +inline ScopeChainIterator JSScope::end() +{ + return ScopeChainIterator(0); +} + +inline JSScope* JSScope::next() +{ + return m_next.get(); +} + +inline JSGlobalObject* JSScope::globalObject() +{ + return structure()->globalObject(); +} + +inline JSGlobalData* JSScope::globalData() +{ + return Heap::heap(this)->globalData(); +} + +inline Register& Register::operator=(JSScope* scope) +{ + *this = JSValue(scope); + return *this; +} + +inline JSScope* Register::scope() const +{ + return jsCast<JSScope*>(jsValue()); +} + +inline JSGlobalData& ExecState::globalData() const +{ + ASSERT(scope()->globalData()); + return *scope()->globalData(); +} + +inline JSGlobalObject* ExecState::lexicalGlobalObject() const +{ + return scope()->globalObject(); +} + +inline JSObject* ExecState::globalThisValue() const +{ + return scope()->globalThis(); +} + +inline size_t JSScope::offsetOfNext() +{ + return OBJECT_OFFSETOF(JSScope, m_next); +} + +} // namespace JSC + +#endif // JSScope_h |