tizen beta release
[framework/web/webkit-efl.git] / Source / JavaScriptCore / 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 ScopeChainIterator;
34     class SlotVisitor;
35     
36     class ScopeChainNode : public JSCell {
37     private:
38         ScopeChainNode(ScopeChainNode* next, JSObject* object, JSGlobalData* globalData, JSGlobalObject* globalObject, JSObject* globalThis)
39             : JSCell(*globalData, globalData->scopeChainNodeStructure.get())
40             , globalData(globalData)
41             , next(*globalData, this, next, WriteBarrier<ScopeChainNode>::MayBeNull)
42             , object(*globalData, this, object)
43             , globalObject(*globalData, this, globalObject)
44             , globalThis(*globalData, this, globalThis)
45         {
46         }
47
48         virtual ~ScopeChainNode();
49
50     protected:
51         void finishCreation(JSGlobalData* globalData, JSGlobalObject* globalObject)
52         {
53             Base::finishCreation(*globalData);
54             ASSERT_UNUSED(globalObject, globalObject);
55         }
56
57     public:
58         typedef JSCell Base;
59
60         static ScopeChainNode* create(ExecState* exec, ScopeChainNode* next, JSObject* object, JSGlobalData* globalData, JSGlobalObject* globalObject, JSObject* globalThis)
61         {
62             ScopeChainNode* node = new (allocateCell<ScopeChainNode>(*exec->heap())) ScopeChainNode(next, object, globalData, globalObject, globalThis);
63             node->finishCreation(globalData, globalObject);
64             return node;
65         }
66         static ScopeChainNode* create(ScopeChainNode* next, JSObject* object, JSGlobalData* globalData, JSGlobalObject* globalObject, JSObject* globalThis)
67         {
68             ScopeChainNode* node = new (allocateCell<ScopeChainNode>(globalData->heap)) ScopeChainNode(next, object, globalData, globalObject, globalThis);
69             node->finishCreation(globalData, globalObject);
70             return node;
71         }
72         
73         JSGlobalData* globalData;
74         WriteBarrier<ScopeChainNode> next;
75         WriteBarrier<JSObject> object;
76         WriteBarrier<JSGlobalObject> globalObject;
77         WriteBarrier<JSObject> globalThis;
78
79         ScopeChainNode* push(JSObject*);
80         ScopeChainNode* pop();
81
82         ScopeChainIterator begin();
83         ScopeChainIterator end();
84
85         int localDepth();
86
87 #ifndef NDEBUG        
88         void print();
89 #endif
90         
91         static Structure* createStructure(JSGlobalData& globalData, JSGlobalObject* globalObject, JSValue proto) { return Structure::create(globalData, globalObject, proto, TypeInfo(CompoundType, StructureFlags), &s_info); }
92         static void visitChildren(JSCell*, SlotVisitor&);
93         static JS_EXPORTDATA const ClassInfo s_info;
94
95     private:
96         static const unsigned StructureFlags = OverridesVisitChildren;
97     };
98
99     inline ScopeChainNode* ScopeChainNode::push(JSObject* o)
100     {
101         ASSERT(o);
102         return ScopeChainNode::create(this, o, globalData, globalObject.get(), globalThis.get());
103     }
104
105     inline ScopeChainNode* ScopeChainNode::pop()
106     {
107         ASSERT(next);
108         return next.get();
109     }
110
111     class ScopeChainIterator {
112     public:
113         ScopeChainIterator(ScopeChainNode* node)
114             : m_node(node)
115         {
116         }
117
118         WriteBarrier<JSObject> const & operator*() const { return m_node->object; }
119         WriteBarrier<JSObject> const * operator->() const { return &(operator*()); }
120     
121         ScopeChainIterator& operator++() { m_node = m_node->next.get(); return *this; }
122
123         // postfix ++ intentionally omitted
124
125         bool operator==(const ScopeChainIterator& other) const { return m_node == other.m_node; }
126         bool operator!=(const ScopeChainIterator& other) const { return m_node != other.m_node; }
127
128     private:
129         ScopeChainNode* m_node;
130     };
131
132     inline ScopeChainIterator ScopeChainNode::begin()
133     {
134         return ScopeChainIterator(this); 
135     }
136
137     inline ScopeChainIterator ScopeChainNode::end()
138     { 
139         return ScopeChainIterator(0); 
140     }
141
142     ALWAYS_INLINE JSGlobalData& ExecState::globalData() const
143     {
144         ASSERT(scopeChain()->globalData);
145         return *scopeChain()->globalData;
146     }
147
148     ALWAYS_INLINE JSGlobalObject* ExecState::lexicalGlobalObject() const
149     {
150         return scopeChain()->globalObject.get();
151     }
152     
153     ALWAYS_INLINE JSObject* ExecState::globalThisValue() const
154     {
155         return scopeChain()->globalThis.get();
156     }
157     
158     ALWAYS_INLINE ScopeChainNode* Register::scopeChain() const
159     {
160         return static_cast<ScopeChainNode*>(jsValue().asCell());
161     }
162     
163     ALWAYS_INLINE Register& Register::operator=(ScopeChainNode* scopeChain)
164     {
165         *this = JSValue(scopeChain);
166         return *this;
167     }
168
169 } // namespace JSC
170
171 #endif // ScopeChain_h