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