]>
git.saurik.com Git - apple/javascriptcore.git/blob - runtime/ScopeChain.h
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.
24 #include "FastAllocBase.h"
32 class ScopeChainIterator
;
34 class ScopeChainNode
: public FastAllocBase
{
36 ScopeChainNode(ScopeChainNode
* next
, JSObject
* object
, JSGlobalData
* globalData
, JSGlobalObject
* globalObject
, JSObject
* globalThis
)
39 , globalData(globalData
)
40 , globalObject(globalObject
)
41 , globalThis(globalThis
)
48 // Due to the number of subtle and timing dependent bugs that have occurred due
49 // to deleted but still "valid" ScopeChainNodes we now deliberately clobber the
50 // contents in debug builds.
63 JSGlobalData
* globalData
;
64 JSGlobalObject
* globalObject
;
68 void deref() { ASSERT(refCount
); if (--refCount
== 0) { release();} }
69 void ref() { ASSERT(refCount
); ++refCount
; }
72 // Before calling "push" on a bare ScopeChainNode, a client should
73 // logically "copy" the node. Later, the client can "deref" the head
74 // of its chain of ScopeChainNodes to reclaim all the nodes it added
75 // after the logical copy, leaving nodes added before the logical copy
76 // (nodes shared with other clients) untouched.
77 ScopeChainNode
* copy()
83 ScopeChainNode
* push(JSObject
*);
84 ScopeChainNode
* pop();
86 ScopeChainIterator
begin() const;
87 ScopeChainIterator
end() const;
94 inline ScopeChainNode
* ScopeChainNode::push(JSObject
* o
)
97 return new ScopeChainNode(this, o
, globalData
, globalObject
, globalThis
);
100 inline ScopeChainNode
* ScopeChainNode::pop()
103 ScopeChainNode
* result
= next
;
113 inline void ScopeChainNode::release()
115 // This function is only called by deref(),
116 // Deref ensures these conditions are true.
117 ASSERT(refCount
== 0);
118 ScopeChainNode
* n
= this;
120 ScopeChainNode
* next
= n
->next
;
123 } while (n
&& --n
->refCount
== 0);
126 class ScopeChainIterator
{
128 ScopeChainIterator(const ScopeChainNode
* node
)
133 JSObject
* const & operator*() const { return m_node
->object
; }
134 JSObject
* const * operator->() const { return &(operator*()); }
136 ScopeChainIterator
& operator++() { m_node
= m_node
->next
; return *this; }
138 // postfix ++ intentionally omitted
140 bool operator==(const ScopeChainIterator
& other
) const { return m_node
== other
.m_node
; }
141 bool operator!=(const ScopeChainIterator
& other
) const { return m_node
!= other
.m_node
; }
144 const ScopeChainNode
* m_node
;
147 inline ScopeChainIterator
ScopeChainNode::begin() const
149 return ScopeChainIterator(this);
152 inline ScopeChainIterator
ScopeChainNode::end() const
154 return ScopeChainIterator(0);
157 class NoScopeChain
{};
162 ScopeChain(NoScopeChain
)
167 ScopeChain(JSObject
* o
, JSGlobalData
* globalData
, JSGlobalObject
* globalObject
, JSObject
* globalThis
)
168 : m_node(new ScopeChainNode(0, o
, globalData
, globalObject
, globalThis
))
172 ScopeChain(const ScopeChain
& c
)
173 : m_node(c
.m_node
->copy())
177 ScopeChain
& operator=(const ScopeChain
& c
);
179 explicit ScopeChain(ScopeChainNode
* node
)
180 : m_node(node
->copy())
193 void swap(ScopeChain
&);
195 ScopeChainNode
* node() const { return m_node
; }
197 JSObject
* top() const { return m_node
->object
; }
199 ScopeChainIterator
begin() const { return m_node
->begin(); }
200 ScopeChainIterator
end() const { return m_node
->end(); }
202 void push(JSObject
* o
) { m_node
= m_node
->push(o
); }
204 void pop() { m_node
= m_node
->pop(); }
205 void clear() { m_node
->deref(); m_node
= 0; }
207 JSGlobalObject
* globalObject() const { return m_node
->globalObject
; }
209 void markAggregate(MarkStack
&) const;
211 // Caution: this should only be used if the codeblock this is being used
212 // with needs a full scope chain, otherwise this returns the depth of
213 // the preceeding call frame
215 // Returns the depth of the current call frame's scope chain
216 int localDepth() const;
219 void print() const { m_node
->print(); }
223 ScopeChainNode
* m_node
;
226 inline void ScopeChain::swap(ScopeChain
& o
)
228 ScopeChainNode
* tmp
= m_node
;
233 inline ScopeChain
& ScopeChain::operator=(const ScopeChain
& c
)
242 #endif // ScopeChain_h