]> git.saurik.com Git - apple/javascriptcore.git/blob - runtime/ScopeChain.h
7fbb888e3b4ae62114f9b9271e1e2cf2071167e3
[apple/javascriptcore.git] / runtime / ScopeChain.h
1 /*
2 * Copyright (C) 2003, 2008, 2009 Apple Inc. All rights reserved.
3 *
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.
8 *
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.
13 *
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.
18 *
19 */
20
21 #ifndef ScopeChain_h
22 #define ScopeChain_h
23
24 #include "JSCell.h"
25 #include "Structure.h"
26 #include <wtf/FastAllocBase.h>
27
28 namespace JSC {
29
30 class JSGlobalData;
31 class JSGlobalObject;
32 class JSObject;
33 class MarkStack;
34 class ScopeChainIterator;
35 typedef MarkStack SlotVisitor;
36
37 class ScopeChainNode : public JSCell {
38 public:
39 ScopeChainNode(ScopeChainNode* next, JSObject* object, JSGlobalData* globalData, JSGlobalObject* globalObject, JSObject* globalThis)
40 : JSCell(*globalData, globalData->scopeChainNodeStructure.get())
41 , globalData(globalData)
42 , next(*globalData, this, next, WriteBarrier<ScopeChainNode>::MayBeNull)
43 , object(*globalData, this, object)
44 , globalObject(*globalData, this, globalObject)
45 , globalThis(*globalData, this, globalThis)
46 {
47 ASSERT(globalData);
48 ASSERT(globalObject);
49 }
50
51 JSGlobalData* globalData;
52 WriteBarrier<ScopeChainNode> next;
53 WriteBarrier<JSObject> object;
54 WriteBarrier<JSGlobalObject> globalObject;
55 WriteBarrier<JSObject> globalThis;
56
57 ScopeChainNode* push(JSObject*);
58 ScopeChainNode* pop();
59
60 ScopeChainIterator begin();
61 ScopeChainIterator end();
62
63 int localDepth();
64
65 #ifndef NDEBUG
66 void print();
67 #endif
68
69 static Structure* createStructure(JSGlobalData& globalData, JSValue proto) { return Structure::create(globalData, proto, TypeInfo(CompoundType, StructureFlags), AnonymousSlotCount, &s_info); }
70 virtual void visitChildren(SlotVisitor&);
71 static JS_EXPORTDATA const ClassInfo s_info;
72
73 private:
74 static const unsigned StructureFlags = OverridesVisitChildren;
75 };
76
77 inline ScopeChainNode* ScopeChainNode::push(JSObject* o)
78 {
79 ASSERT(o);
80 return new (globalData) ScopeChainNode(this, o, globalData, globalObject.get(), globalThis.get());
81 }
82
83 inline ScopeChainNode* ScopeChainNode::pop()
84 {
85 ASSERT(next);
86 return next.get();
87 }
88
89 class ScopeChainIterator {
90 public:
91 ScopeChainIterator(ScopeChainNode* node)
92 : m_node(node)
93 {
94 }
95
96 WriteBarrier<JSObject> const & operator*() const { return m_node->object; }
97 WriteBarrier<JSObject> const * operator->() const { return &(operator*()); }
98
99 ScopeChainIterator& operator++() { m_node = m_node->next.get(); return *this; }
100
101 // postfix ++ intentionally omitted
102
103 bool operator==(const ScopeChainIterator& other) const { return m_node == other.m_node; }
104 bool operator!=(const ScopeChainIterator& other) const { return m_node != other.m_node; }
105
106 private:
107 ScopeChainNode* m_node;
108 };
109
110 inline ScopeChainIterator ScopeChainNode::begin()
111 {
112 return ScopeChainIterator(this);
113 }
114
115 inline ScopeChainIterator ScopeChainNode::end()
116 {
117 return ScopeChainIterator(0);
118 }
119
120 ALWAYS_INLINE JSGlobalData& ExecState::globalData() const
121 {
122 ASSERT(scopeChain()->globalData);
123 return *scopeChain()->globalData;
124 }
125
126 ALWAYS_INLINE JSGlobalObject* ExecState::lexicalGlobalObject() const
127 {
128 return scopeChain()->globalObject.get();
129 }
130
131 ALWAYS_INLINE JSObject* ExecState::globalThisValue() const
132 {
133 return scopeChain()->globalThis.get();
134 }
135
136 ALWAYS_INLINE ScopeChainNode* Register::scopeChain() const
137 {
138 return static_cast<ScopeChainNode*>(jsValue().asCell());
139 }
140
141 ALWAYS_INLINE Register& Register::operator=(ScopeChainNode* scopeChain)
142 {
143 *this = JSValue(scopeChain);
144 return *this;
145 }
146
147 } // namespace JSC
148
149 #endif // ScopeChain_h