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)
49 void finishCreation(JSGlobalData* globalData, JSGlobalObject* globalObject)
51 Base::finishCreation(*globalData);
52 ASSERT_UNUSED(globalObject, globalObject);
58 static ScopeChainNode* create(ExecState* exec, ScopeChainNode* next, JSObject* object, JSGlobalData* globalData, JSGlobalObject* globalObject, JSObject* globalThis)
60 ScopeChainNode* node = new (allocateCell<ScopeChainNode>(*exec->heap())) ScopeChainNode(next, object, globalData, globalObject, globalThis);
61 node->finishCreation(globalData, globalObject);
64 static ScopeChainNode* create(ScopeChainNode* next, JSObject* object, JSGlobalData* globalData, JSGlobalObject* globalObject, JSObject* globalThis)
66 ScopeChainNode* node = new (allocateCell<ScopeChainNode>(globalData->heap)) ScopeChainNode(next, object, globalData, globalObject, globalThis);
67 node->finishCreation(globalData, globalObject);
71 JSGlobalData* globalData;
72 WriteBarrier<ScopeChainNode> next;
73 WriteBarrier<JSObject> object;
74 WriteBarrier<JSGlobalObject> globalObject;
75 WriteBarrier<JSObject> globalThis;
77 ScopeChainNode* push(JSObject*);
78 ScopeChainNode* pop();
80 ScopeChainIterator begin();
81 ScopeChainIterator end();
89 static Structure* createStructure(JSGlobalData& globalData, JSGlobalObject* globalObject, JSValue proto) { return Structure::create(globalData, globalObject, proto, TypeInfo(CompoundType, StructureFlags), &s_info); }
90 virtual void visitChildren(SlotVisitor&);
91 static JS_EXPORTDATA const ClassInfo s_info;
94 static const unsigned StructureFlags = OverridesVisitChildren;
97 inline ScopeChainNode* ScopeChainNode::push(JSObject* o)
100 return ScopeChainNode::create(this, o, globalData, globalObject.get(), globalThis.get());
103 inline ScopeChainNode* ScopeChainNode::pop()
109 class ScopeChainIterator {
111 ScopeChainIterator(ScopeChainNode* node)
116 WriteBarrier<JSObject> const & operator*() const { return m_node->object; }
117 WriteBarrier<JSObject> const * operator->() const { return &(operator*()); }
119 ScopeChainIterator& operator++() { m_node = m_node->next.get(); return *this; }
121 // postfix ++ intentionally omitted
123 bool operator==(const ScopeChainIterator& other) const { return m_node == other.m_node; }
124 bool operator!=(const ScopeChainIterator& other) const { return m_node != other.m_node; }
127 ScopeChainNode* m_node;
130 inline ScopeChainIterator ScopeChainNode::begin()
132 return ScopeChainIterator(this);
135 inline ScopeChainIterator ScopeChainNode::end()
137 return ScopeChainIterator(0);
140 ALWAYS_INLINE JSGlobalData& ExecState::globalData() const
142 ASSERT(scopeChain()->globalData);
143 return *scopeChain()->globalData;
146 ALWAYS_INLINE JSGlobalObject* ExecState::lexicalGlobalObject() const
148 return scopeChain()->globalObject.get();
151 ALWAYS_INLINE JSObject* ExecState::globalThisValue() const
153 return scopeChain()->globalThis.get();
156 ALWAYS_INLINE ScopeChainNode* Register::scopeChain() const
158 return static_cast<ScopeChainNode*>(jsValue().asCell());
161 ALWAYS_INLINE Register& Register::operator=(ScopeChainNode* scopeChain)
163 *this = JSValue(scopeChain);
169 #endif // ScopeChain_h