]>
git.saurik.com Git - apple/javascriptcore.git/blob - runtime/ScopeChain.h
17aff24ec102fa152e2e686fd9d3712fab9a4db6
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 "FastAllocBase.h"
31 class ScopeChainIterator
;
33 class ScopeChainNode
: public FastAllocBase
{
35 ScopeChainNode(ScopeChainNode
* next
, JSObject
* object
, JSGlobalData
* globalData
, JSObject
* globalThis
)
38 , globalData(globalData
)
39 , globalThis(globalThis
)
45 // Due to the number of subtle and timing dependent bugs that have occurred due
46 // to deleted but still "valid" ScopeChainNodes we now deliberately clobber the
47 // contents in debug builds.
59 JSGlobalData
* globalData
;
63 void deref() { ASSERT(refCount
); if (--refCount
== 0) { release();} }
64 void ref() { ASSERT(refCount
); ++refCount
; }
67 // Before calling "push" on a bare ScopeChainNode, a client should
68 // logically "copy" the node. Later, the client can "deref" the head
69 // of its chain of ScopeChainNodes to reclaim all the nodes it added
70 // after the logical copy, leaving nodes added before the logical copy
71 // (nodes shared with other clients) untouched.
72 ScopeChainNode
* copy()
78 ScopeChainNode
* push(JSObject
*);
79 ScopeChainNode
* pop();
81 ScopeChainIterator
begin() const;
82 ScopeChainIterator
end() const;
84 JSGlobalObject
* globalObject() const; // defined in JSGlobalObject.h
85 JSObject
* globalThisObject() const { return globalThis
; }
92 inline ScopeChainNode
* ScopeChainNode::push(JSObject
* o
)
95 return new ScopeChainNode(this, o
, globalData
, globalThis
);
98 inline ScopeChainNode
* ScopeChainNode::pop()
101 ScopeChainNode
* result
= next
;
111 inline void ScopeChainNode::release()
113 // This function is only called by deref(),
114 // Deref ensures these conditions are true.
115 ASSERT(refCount
== 0);
116 ScopeChainNode
* n
= this;
118 ScopeChainNode
* next
= n
->next
;
121 } while (n
&& --n
->refCount
== 0);
124 class ScopeChainIterator
{
126 ScopeChainIterator(const ScopeChainNode
* node
)
131 JSObject
* const & operator*() const { return m_node
->object
; }
132 JSObject
* const * operator->() const { return &(operator*()); }
134 ScopeChainIterator
& operator++() { m_node
= m_node
->next
; return *this; }
136 // postfix ++ intentionally omitted
138 bool operator==(const ScopeChainIterator
& other
) const { return m_node
== other
.m_node
; }
139 bool operator!=(const ScopeChainIterator
& other
) const { return m_node
!= other
.m_node
; }
142 const ScopeChainNode
* m_node
;
145 inline ScopeChainIterator
ScopeChainNode::begin() const
147 return ScopeChainIterator(this);
150 inline ScopeChainIterator
ScopeChainNode::end() const
152 return ScopeChainIterator(0);
155 class NoScopeChain
{};
160 ScopeChain(NoScopeChain
)
165 ScopeChain(JSObject
* o
, JSGlobalData
* globalData
, JSObject
* globalThis
)
166 : m_node(new ScopeChainNode(0, o
, globalData
, globalThis
))
170 ScopeChain(const ScopeChain
& c
)
171 : m_node(c
.m_node
->copy())
175 ScopeChain
& operator=(const ScopeChain
& c
);
177 explicit ScopeChain(ScopeChainNode
* node
)
178 : m_node(node
->copy())
191 void swap(ScopeChain
&);
193 ScopeChainNode
* node() const { return m_node
; }
195 JSObject
* top() const { return m_node
->object
; }
197 ScopeChainIterator
begin() const { return m_node
->begin(); }
198 ScopeChainIterator
end() const { return m_node
->end(); }
200 void push(JSObject
* o
) { m_node
= m_node
->push(o
); }
202 void pop() { m_node
= m_node
->pop(); }
203 void clear() { m_node
->deref(); m_node
= 0; }
205 JSGlobalObject
* globalObject() const { return m_node
->globalObject(); }
209 // Caution: this should only be used if the codeblock this is being used
210 // with needs a full scope chain, otherwise this returns the depth of
211 // the preceeding call frame
213 // Returns the depth of the current call frame's scope chain
214 int localDepth() const;
217 void print() const { m_node
->print(); }
221 ScopeChainNode
* m_node
;
224 inline void ScopeChain::swap(ScopeChain
& o
)
226 ScopeChainNode
* tmp
= m_node
;
231 inline ScopeChain
& ScopeChain::operator=(const ScopeChain
& c
)
240 #endif // ScopeChain_h