• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 MarkStack;
34     class ScopeChainIterator;
35 
36     class ScopeChainNode : public JSCell {
37     public:
ScopeChainNode(ScopeChainNode * next,JSObject * object,JSGlobalData * globalData,JSGlobalObject * globalObject,JSObject * globalThis)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)
42             , object(*globalData, this, object)
43             , globalObject(*globalData, this, globalObject)
44             , globalThis(*globalData, this, globalThis)
45         {
46             ASSERT(globalData);
47             ASSERT(globalObject);
48         }
49 
50         JSGlobalData* globalData;
51         WriteBarrier<ScopeChainNode> next;
52         WriteBarrier<JSObject> object;
53         WriteBarrier<JSGlobalObject> globalObject;
54         WriteBarrier<JSObject> globalThis;
55 
56         ScopeChainNode* push(JSObject*);
57         ScopeChainNode* pop();
58 
59         ScopeChainIterator begin();
60         ScopeChainIterator end();
61 
62         int localDepth();
63 
64 #ifndef NDEBUG
65         void print();
66 #endif
67 
createStructure(JSGlobalData & globalData,JSValue proto)68         static Structure* createStructure(JSGlobalData& globalData, JSValue proto) { return Structure::create(globalData, proto, TypeInfo(CompoundType, StructureFlags), AnonymousSlotCount, &s_info); }
69         virtual void markChildren(MarkStack&);
70     private:
71         static const unsigned StructureFlags = OverridesMarkChildren;
72         static const ClassInfo s_info;
73     };
74 
push(JSObject * o)75     inline ScopeChainNode* ScopeChainNode::push(JSObject* o)
76     {
77         ASSERT(o);
78         return new (globalData) ScopeChainNode(this, o, globalData, globalObject.get(), globalThis.get());
79     }
80 
pop()81     inline ScopeChainNode* ScopeChainNode::pop()
82     {
83         ASSERT(next);
84         return next.get();
85     }
86 
87     class ScopeChainIterator {
88     public:
ScopeChainIterator(ScopeChainNode * node)89         ScopeChainIterator(ScopeChainNode* node)
90             : m_node(node)
91         {
92         }
93 
94         WriteBarrier<JSObject> const & operator*() const { return m_node->object; }
95         WriteBarrier<JSObject> const * operator->() const { return &(operator*()); }
96 
97         ScopeChainIterator& operator++() { m_node = m_node->next.get(); return *this; }
98 
99         // postfix ++ intentionally omitted
100 
101         bool operator==(const ScopeChainIterator& other) const { return m_node == other.m_node; }
102         bool operator!=(const ScopeChainIterator& other) const { return m_node != other.m_node; }
103 
104     private:
105         ScopeChainNode* m_node;
106     };
107 
begin()108     inline ScopeChainIterator ScopeChainNode::begin()
109     {
110         return ScopeChainIterator(this);
111     }
112 
end()113     inline ScopeChainIterator ScopeChainNode::end()
114     {
115         return ScopeChainIterator(0);
116     }
117 
globalData()118     ALWAYS_INLINE JSGlobalData& ExecState::globalData() const
119     {
120         ASSERT(scopeChain()->globalData);
121         return *scopeChain()->globalData;
122     }
123 
lexicalGlobalObject()124     ALWAYS_INLINE JSGlobalObject* ExecState::lexicalGlobalObject() const
125     {
126         return scopeChain()->globalObject.get();
127     }
128 
globalThisValue()129     ALWAYS_INLINE JSObject* ExecState::globalThisValue() const
130     {
131         return scopeChain()->globalThis.get();
132     }
133 
scopeChain()134     ALWAYS_INLINE ScopeChainNode* Register::scopeChain() const
135     {
136         return static_cast<ScopeChainNode*>(jsValue().asCell());
137     }
138 
139     ALWAYS_INLINE Register& Register::operator=(ScopeChainNode* scopeChain)
140     {
141         *this = JSValue(scopeChain);
142         return *this;
143     }
144 
145 } // namespace JSC
146 
147 #endif // ScopeChain_h
148