2 * Copyright (C) 2003, 2008, 2009 Apple Inc. All rights reserved.
4 * This library is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU Library General Public
6 * License as published by the Free Software Foundation; either
7 * version 2 of the License, or (at your option) any later version.
9 * This library is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * Library General Public License for more details.
14 * You should have received a copy of the GNU Library General Public License
15 * along with this library; see the file COPYING.LIB. If not, write to
16 * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
17 * Boston, MA 02110-1301, USA.
25 #include "Structure.h"
26 #include <wtf/FastAllocBase.h>
33 class ScopeChainIterator;
36 class ScopeChainNode : public JSCell {
38 ScopeChainNode(ScopeChainNode* next, JSObject* object, JSGlobalData* globalData, JSGlobalObject* globalObject, JSObject* globalThis)
39 : JSCell(*globalData, globalData->scopeChainNodeStructure.get())
40 , globalData(globalData)
41 , next(*globalData, this, next, WriteBarrier<ScopeChainNode>::MayBeNull)
42 , object(*globalData, this, object)
43 , globalObject(*globalData, this, globalObject)
44 , globalThis(*globalData, this, globalThis)
48 virtual ~ScopeChainNode();
51 void finishCreation(JSGlobalData* globalData, JSGlobalObject* globalObject)
53 Base::finishCreation(*globalData);
54 ASSERT_UNUSED(globalObject, globalObject);
60 static ScopeChainNode* create(ExecState* exec, ScopeChainNode* next, JSObject* object, JSGlobalData* globalData, JSGlobalObject* globalObject, JSObject* globalThis)
62 ScopeChainNode* node = new (allocateCell<ScopeChainNode>(*exec->heap())) ScopeChainNode(next, object, globalData, globalObject, globalThis);
63 node->finishCreation(globalData, globalObject);
66 static ScopeChainNode* create(ScopeChainNode* next, JSObject* object, JSGlobalData* globalData, JSGlobalObject* globalObject, JSObject* globalThis)
68 ScopeChainNode* node = new (allocateCell<ScopeChainNode>(globalData->heap)) ScopeChainNode(next, object, globalData, globalObject, globalThis);
69 node->finishCreation(globalData, globalObject);
73 JSGlobalData* globalData;
74 WriteBarrier<ScopeChainNode> next;
75 WriteBarrier<JSObject> object;
76 WriteBarrier<JSGlobalObject> globalObject;
77 WriteBarrier<JSObject> globalThis;
79 ScopeChainNode* push(JSObject*);
80 ScopeChainNode* pop();
82 ScopeChainIterator begin();
83 ScopeChainIterator end();
91 static Structure* createStructure(JSGlobalData& globalData, JSGlobalObject* globalObject, JSValue proto) { return Structure::create(globalData, globalObject, proto, TypeInfo(CompoundType, StructureFlags), &s_info); }
92 static void visitChildren(JSCell*, SlotVisitor&);
93 static JS_EXPORTDATA const ClassInfo s_info;
96 static const unsigned StructureFlags = OverridesVisitChildren;
99 inline ScopeChainNode* ScopeChainNode::push(JSObject* o)
102 return ScopeChainNode::create(this, o, globalData, globalObject.get(), globalThis.get());
105 inline ScopeChainNode* ScopeChainNode::pop()
111 class ScopeChainIterator {
113 ScopeChainIterator(ScopeChainNode* node)
118 WriteBarrier<JSObject> const & operator*() const { return m_node->object; }
119 WriteBarrier<JSObject> const * operator->() const { return &(operator*()); }
121 ScopeChainIterator& operator++() { m_node = m_node->next.get(); return *this; }
123 // postfix ++ intentionally omitted
125 bool operator==(const ScopeChainIterator& other) const { return m_node == other.m_node; }
126 bool operator!=(const ScopeChainIterator& other) const { return m_node != other.m_node; }
129 ScopeChainNode* m_node;
132 inline ScopeChainIterator ScopeChainNode::begin()
134 return ScopeChainIterator(this);
137 inline ScopeChainIterator ScopeChainNode::end()
139 return ScopeChainIterator(0);
142 ALWAYS_INLINE JSGlobalData& ExecState::globalData() const
144 ASSERT(scopeChain()->globalData);
145 return *scopeChain()->globalData;
148 ALWAYS_INLINE JSGlobalObject* ExecState::lexicalGlobalObject() const
150 return scopeChain()->globalObject.get();
153 ALWAYS_INLINE JSObject* ExecState::globalThisValue() const
155 return scopeChain()->globalThis.get();
158 ALWAYS_INLINE ScopeChainNode* Register::scopeChain() const
160 return static_cast<ScopeChainNode*>(jsValue().asCell());
163 ALWAYS_INLINE Register& Register::operator=(ScopeChainNode* scopeChain)
165 *this = JSValue(scopeChain);
171 #endif // ScopeChain_h