ScopeChain.h 4.38 KB
Newer Older
darin's avatar
darin committed
1
/*
2
 *  Copyright (C) 2003, 2008, 2009 Apple Inc. All rights reserved.
darin's avatar
darin committed
3 4 5 6 7 8 9 10 11 12 13 14 15
 *
 *  This library is free software; you can redistribute it and/or
 *  modify it under the terms of the GNU Library General Public
 *  License as published by the Free Software Foundation; either
 *  version 2 of the License, or (at your option) any later version.
 *
 *  This library is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 *  Library General Public License for more details.
 *
 *  You should have received a copy of the GNU Library General Public License
 *  along with this library; see the file COPYING.LIB.  If not, write to
mjs's avatar
mjs committed
16
 *  the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
17
 *  Boston, MA 02110-1301, USA.
darin's avatar
darin committed
18 19 20
 *
 */

21 22
#ifndef ScopeChain_h
#define ScopeChain_h
darin's avatar
darin committed
23

24
#include "JSCell.h"
25
#include "Structure.h"
26
#include <wtf/FastAllocBase.h>
eseidel's avatar
eseidel committed
27

28
namespace JSC {
darin's avatar
darin committed
29

30
    class JSGlobalData;
31
    class JSGlobalObject;
darin's avatar
darin committed
32
    class JSObject;
33
    class MarkStack;
34
    class ScopeChainIterator;
darin's avatar
darin committed
35
    
36
    class ScopeChainNode : public JSCell {
37
    public:
38
        ScopeChainNode(ScopeChainNode* next, JSObject* object, JSGlobalData* globalData, JSGlobalObject* globalObject, JSObject* globalThis)
39
            : JSCell(globalData->scopeChainNodeStructure.get())
darin@apple.com's avatar
darin@apple.com committed
40
            , globalData(globalData)
41 42 43 44
            , next(*globalData, this, next)
            , object(*globalData, this, object)
            , globalObject(*globalData, this, globalObject)
            , globalThis(*globalData, this, globalThis)
45
        {
darin@apple.com's avatar
darin@apple.com committed
46
            ASSERT(globalData);
47
            ASSERT(globalObject);
48
        }
darin's avatar
darin committed
49

darin@apple.com's avatar
darin@apple.com committed
50
        JSGlobalData* globalData;
51 52 53 54
        WriteBarrier<ScopeChainNode> next;
        WriteBarrier<JSObject> object;
        WriteBarrier<JSGlobalObject> globalObject;
        WriteBarrier<JSObject> globalThis;
55 56 57 58

        ScopeChainNode* push(JSObject*);
        ScopeChainNode* pop();

59 60 61 62
        ScopeChainIterator begin();
        ScopeChainIterator end();

        int localDepth();
weinig@apple.com's avatar
weinig@apple.com committed
63

64
#ifndef NDEBUG        
65
        void print();
66
#endif
67
        
68
        static PassRefPtr<Structure> createStructure(JSGlobalData& globalData, JSValue proto) { return Structure::create(globalData, proto, TypeInfo(CompoundType, StructureFlags), AnonymousSlotCount, 0); }
69 70 71
        virtual void markChildren(MarkStack&);
    private:
        static const unsigned StructureFlags = OverridesMarkChildren;
darin's avatar
darin committed
72
    };
darin's avatar
darin committed
73

74 75 76
    inline ScopeChainNode* ScopeChainNode::push(JSObject* o)
    {
        ASSERT(o);
77
        return new (globalData) ScopeChainNode(this, o, globalData, globalObject.get(), globalThis.get());
78 79 80 81 82
    }

    inline ScopeChainNode* ScopeChainNode::pop()
    {
        ASSERT(next);
83
        return next.get();
84 85
    }

mjs's avatar
mjs committed
86 87
    class ScopeChainIterator {
    public:
88
        ScopeChainIterator(ScopeChainNode* node)
89 90 91
            : m_node(node)
        {
        }
mjs's avatar
mjs committed
92

93 94
        WriteBarrier<JSObject> const & operator*() const { return m_node->object; }
        WriteBarrier<JSObject> const * operator->() const { return &(operator*()); }
mjs's avatar
mjs committed
95
    
96
        ScopeChainIterator& operator++() { m_node = m_node->next.get(); return *this; }
mjs's avatar
mjs committed
97 98 99 100 101 102 103

        // postfix ++ intentionally omitted

        bool operator==(const ScopeChainIterator& other) const { return m_node == other.m_node; }
        bool operator!=(const ScopeChainIterator& other) const { return m_node != other.m_node; }

    private:
104
        ScopeChainNode* m_node;
mjs's avatar
mjs committed
105 106
    };

107
    inline ScopeChainIterator ScopeChainNode::begin()
108 109 110 111
    {
        return ScopeChainIterator(this); 
    }

112
    inline ScopeChainIterator ScopeChainNode::end()
113 114 115 116
    { 
        return ScopeChainIterator(0); 
    }

117
    ALWAYS_INLINE JSGlobalData& ExecState::globalData() const
118
    {
119 120
        ASSERT(scopeChain()->globalData);
        return *scopeChain()->globalData;
eseidel's avatar
eseidel committed
121 122
    }

123 124 125 126 127 128
    ALWAYS_INLINE JSGlobalObject* ExecState::lexicalGlobalObject() const
    {
        return scopeChain()->globalObject.get();
    }
    
    ALWAYS_INLINE JSObject* ExecState::globalThisValue() const
129
    {
130
        return scopeChain()->globalThis.get();
131
    }
132 133 134 135 136 137 138 139 140 141 142
    
    ALWAYS_INLINE ScopeChainNode* Register::scopeChain() const
    {
        return static_cast<ScopeChainNode*>(jsValue().asCell());
    }
    
    ALWAYS_INLINE Register& Register::operator=(ScopeChainNode* scopeChain)
    {
        *this = JSValue(scopeChain);
        return *this;
    }
143

144
} // namespace JSC
darin's avatar
darin committed
145

146
#endif // ScopeChain_h