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 LLIntOffsetsExtractor
;
34 class ScopeChainIterator
;
37 class ScopeChainNode
: public JSCell
{
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
)
50 void finishCreation(JSGlobalData
* globalData
, JSGlobalObject
* globalObject
)
52 Base::finishCreation(*globalData
);
53 ASSERT_UNUSED(globalObject
, globalObject
);
59 static ScopeChainNode
* create(ExecState
* exec
, ScopeChainNode
* next
, JSObject
* object
, JSGlobalData
* globalData
, JSGlobalObject
* globalObject
, JSObject
* globalThis
)
61 ScopeChainNode
* node
= new (NotNull
, allocateCell
<ScopeChainNode
>(*exec
->heap())) ScopeChainNode(next
, object
, globalData
, globalObject
, globalThis
);
62 node
->finishCreation(globalData
, globalObject
);
65 static ScopeChainNode
* create(ScopeChainNode
* next
, JSObject
* object
, JSGlobalData
* globalData
, JSGlobalObject
* globalObject
, JSObject
* globalThis
)
67 ScopeChainNode
* node
= new (NotNull
, allocateCell
<ScopeChainNode
>(globalData
->heap
)) ScopeChainNode(next
, object
, globalData
, globalObject
, globalThis
);
68 node
->finishCreation(globalData
, globalObject
);
72 JSGlobalData
* globalData
;
73 WriteBarrier
<ScopeChainNode
> next
;
74 WriteBarrier
<JSObject
> object
;
75 WriteBarrier
<JSGlobalObject
> globalObject
;
76 WriteBarrier
<JSObject
> globalThis
;
78 ScopeChainNode
* push(JSObject
*);
79 ScopeChainNode
* pop();
81 ScopeChainIterator
begin();
82 ScopeChainIterator
end();
90 static Structure
* createStructure(JSGlobalData
& globalData
, JSGlobalObject
* globalObject
, JSValue proto
) { return Structure::create(globalData
, globalObject
, proto
, TypeInfo(CompoundType
, StructureFlags
), &s_info
); }
91 static void visitChildren(JSCell
*, SlotVisitor
&);
92 static JS_EXPORTDATA
const ClassInfo s_info
;
95 friend class LLIntOffsetsExtractor
;
97 static const unsigned StructureFlags
= OverridesVisitChildren
;
100 inline ScopeChainNode
* ScopeChainNode::push(JSObject
* o
)
103 return ScopeChainNode::create(this, o
, globalData
, globalObject
.get(), globalThis
.get());
106 inline ScopeChainNode
* ScopeChainNode::pop()
112 class ScopeChainIterator
{
114 ScopeChainIterator(ScopeChainNode
* node
)
119 WriteBarrier
<JSObject
> const & operator*() const { return m_node
->object
; }
120 WriteBarrier
<JSObject
> const * operator->() const { return &(operator*()); }
122 ScopeChainIterator
& operator++() { m_node
= m_node
->next
.get(); 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 ScopeChainNode
* m_node
;
133 inline ScopeChainIterator
ScopeChainNode::begin()
135 return ScopeChainIterator(this);
138 inline ScopeChainIterator
ScopeChainNode::end()
140 return ScopeChainIterator(0);
143 ALWAYS_INLINE JSGlobalData
& ExecState::globalData() const
145 ASSERT(scopeChain()->globalData
);
146 return *scopeChain()->globalData
;
149 ALWAYS_INLINE JSGlobalObject
* ExecState::lexicalGlobalObject() const
151 return scopeChain()->globalObject
.get();
154 ALWAYS_INLINE JSObject
* ExecState::globalThisValue() const
156 return scopeChain()->globalThis
.get();
159 ALWAYS_INLINE ScopeChainNode
* Register::scopeChain() const
161 return static_cast<ScopeChainNode
*>(jsValue().asCell());
164 ALWAYS_INLINE Register
& Register::operator=(ScopeChainNode
* scopeChain
)
166 *this = JSValue(scopeChain
);
172 #endif // ScopeChain_h