]>
git.saurik.com Git - apple/javascriptcore.git/blob - runtime/ScopeChain.h
32b5e9235cd358cc8fe2657b02c6dbd6ac1b1711
2 * Copyright (C) 2003, 2008 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.
24 #include <wtf/Assertions.h>
31 class ScopeChainIterator
;
33 class ScopeChainNode
{
35 ScopeChainNode(ScopeChainNode
* next
, JSObject
* object
, JSGlobalData
* globalData
, JSObject
* globalThis
)
38 , globalData(globalData
)
39 , globalThis(globalThis
)
47 JSGlobalData
* globalData
;
51 void deref() { ASSERT(refCount
); if (--refCount
== 0) { release();} }
52 void ref() { ASSERT(refCount
); ++refCount
; }
55 // Before calling "push" on a bare ScopeChainNode, a client should
56 // logically "copy" the node. Later, the client can "deref" the head
57 // of its chain of ScopeChainNodes to reclaim all the nodes it added
58 // after the logical copy, leaving nodes added before the logical copy
59 // (nodes shared with other clients) untouched.
60 ScopeChainNode
* copy()
66 ScopeChainNode
* push(JSObject
*);
67 ScopeChainNode
* pop();
69 ScopeChainIterator
begin() const;
70 ScopeChainIterator
end() const;
72 JSGlobalObject
* globalObject() const; // defined in JSGlobalObject.h
73 JSObject
* globalThisObject() const { return globalThis
; }
80 inline ScopeChainNode
* ScopeChainNode::push(JSObject
* o
)
83 return new ScopeChainNode(this, o
, globalData
, globalThis
);
86 inline ScopeChainNode
* ScopeChainNode::pop()
89 ScopeChainNode
* result
= next
;
99 inline void ScopeChainNode::release()
101 // This function is only called by deref(),
102 // Deref ensures these conditions are true.
103 ASSERT(refCount
== 0);
104 ScopeChainNode
* n
= this;
106 ScopeChainNode
* next
= n
->next
;
109 } while (n
&& --n
->refCount
== 0);
112 class ScopeChainIterator
{
114 ScopeChainIterator(const ScopeChainNode
* node
)
119 JSObject
* const & operator*() const { return m_node
->object
; }
120 JSObject
* const * operator->() const { return &(operator*()); }
122 ScopeChainIterator
& operator++() { m_node
= m_node
->next
; return *this; }
124 // postfix ++ intentionally omitted
126 bool operator==(const ScopeChainIterator
& other
) const { return m_node
== other
.m_node
; }
127 bool operator!=(const ScopeChainIterator
& other
) const { return m_node
!= other
.m_node
; }
130 const ScopeChainNode
* m_node
;
133 inline ScopeChainIterator
ScopeChainNode::begin() const
135 return ScopeChainIterator(this);
138 inline ScopeChainIterator
ScopeChainNode::end() const
140 return ScopeChainIterator(0);
143 class NoScopeChain
{};
148 ScopeChain(NoScopeChain
)
153 ScopeChain(JSObject
* o
, JSGlobalData
* globalData
, JSObject
* globalThis
)
154 : m_node(new ScopeChainNode(0, o
, globalData
, globalThis
))
158 ScopeChain(const ScopeChain
& c
)
159 : m_node(c
.m_node
->copy())
163 ScopeChain
& operator=(const ScopeChain
& c
);
165 explicit ScopeChain(ScopeChainNode
* node
)
166 : m_node(node
->copy())
176 void swap(ScopeChain
&);
178 ScopeChainNode
* node() const { return m_node
; }
180 JSObject
* top() const { return m_node
->object
; }
182 ScopeChainIterator
begin() const { return m_node
->begin(); }
183 ScopeChainIterator
end() const { return m_node
->end(); }
185 void push(JSObject
* o
) { m_node
= m_node
->push(o
); }
187 void pop() { m_node
= m_node
->pop(); }
188 void clear() { m_node
->deref(); m_node
= 0; }
190 JSGlobalObject
* globalObject() const { return m_node
->globalObject(); }
194 // Caution: this should only be used if the codeblock this is being used
195 // with needs a full scope chain, otherwise this returns the depth of
196 // the preceeding call frame
198 // Returns the depth of the current call frame's scope chain
199 int localDepth() const;
202 void print() const { m_node
->print(); }
206 ScopeChainNode
* m_node
;
209 inline void ScopeChain::swap(ScopeChain
& o
)
211 ScopeChainNode
* tmp
= m_node
;
216 inline ScopeChain
& ScopeChain::operator=(const ScopeChain
& c
)
225 #endif // ScopeChain_h