fbbe4995fda2e1b557e982fde24c92ff7bd5e158
[WebKit.git] / JavaScriptCore / kjs / StructureID.h
1 // -*- mode: c++; c-basic-offset: 4 -*-
2 /*
3  * Copyright (C) 2008 Apple Inc. All rights reserved.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions
7  * are met:
8  * 1. Redistributions of source code must retain the above copyright
9  *    notice, this list of conditions and the following disclaimer.
10  * 2. Redistributions in binary form must reproduce the above copyright
11  *    notice, this list of conditions and the following disclaimer in the
12  *    documentation and/or other materials provided with the distribution.
13  *
14  * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
15  * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
16  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
17  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE COMPUTER, INC. OR
18  * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
19  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
20  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
21  * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
22  * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
23  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
24  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
25  */
26
27 #ifndef StructureID_h
28 #define StructureID_h
29
30 #include "JSType.h"
31 #include "JSValue.h"
32 #include "PropertyMap.h"
33 #include "TypeInfo.h"
34 #include "ustring.h"
35 #include <wtf/HashFunctions.h>
36 #include <wtf/HashTraits.h>
37 #include <wtf/OwnArrayPtr.h>
38 #include <wtf/PassRefPtr.h>
39 #include <wtf/RefCounted.h>
40
41 namespace JSC {
42
43     class JSValue;
44     class PropertyNameArray;
45     class PropertyNameArrayData;
46     class StructureIDChain;
47
48     struct TransitionTableHash {
49         typedef std::pair<RefPtr<UString::Rep>, unsigned> TransitionTableKey;
50         static unsigned hash(const TransitionTableKey& p)
51         {
52             return p.first->computedHash();
53         }
54
55         static bool equal(const TransitionTableKey& a, const TransitionTableKey& b)
56         {
57             return a == b;
58         }
59
60         static const bool safeToCompareToEmptyOrDeleted = true;
61     };
62
63     struct TransitionTableHashTraits {
64         typedef WTF::HashTraits<RefPtr<UString::Rep> > FirstTraits;
65         typedef WTF::GenericHashTraits<unsigned> SecondTraits;
66         typedef std::pair<FirstTraits::TraitType, SecondTraits::TraitType> TraitType;
67
68         static const bool emptyValueIsZero = FirstTraits::emptyValueIsZero && SecondTraits::emptyValueIsZero;
69         static TraitType emptyValue() { return std::make_pair(FirstTraits::emptyValue(), SecondTraits::emptyValue()); }
70
71         static const bool needsDestruction = FirstTraits::needsDestruction || SecondTraits::needsDestruction;
72
73         static void constructDeletedValue(TraitType& slot) { FirstTraits::constructDeletedValue(slot.first); }
74         static bool isDeletedValue(const TraitType& value) { return FirstTraits::isDeletedValue(value.first); }
75     };
76
77     class StructureID : public RefCounted<StructureID> {
78     public:
79         friend class CTI;
80         static PassRefPtr<StructureID> create(JSValue* prototype, const TypeInfo& typeInfo)
81         {
82             return adoptRef(new StructureID(prototype, typeInfo));
83         }
84
85         static PassRefPtr<StructureID> changePrototypeTransition(StructureID*, JSValue* prototype);
86         static PassRefPtr<StructureID> addPropertyTransition(StructureID*, const Identifier& propertyName, JSValue*, unsigned attributes, JSObject* slotBase, PutPropertySlot&, PropertyStorage&);
87         static PassRefPtr<StructureID> getterSetterTransition(StructureID*);
88         static PassRefPtr<StructureID> toDictionaryTransition(StructureID*);
89         static PassRefPtr<StructureID> fromDictionaryTransition(StructureID*);
90
91         ~StructureID();
92
93         void mark()
94         {
95             if (!m_prototype->marked())
96                 m_prototype->mark();
97         }
98
99         bool isDictionary() const { return m_isDictionary; }
100
101         const TypeInfo& typeInfo() const { return m_typeInfo; }
102
103         // For use when first creating a new structure.
104         TypeInfo& mutableTypeInfo() { return m_typeInfo; }
105
106         JSValue* storedPrototype() const { return m_prototype; }
107         JSValue* prototypeForLookup(ExecState*); 
108
109         StructureID* previousID() const { return m_previous.get(); }
110
111         StructureIDChain* createCachedPrototypeChain();
112         void setCachedPrototypeChain(PassRefPtr<StructureIDChain> cachedPrototypeChain) { m_cachedPrototypeChain = cachedPrototypeChain; }
113         StructureIDChain* cachedPrototypeChain() const { return m_cachedPrototypeChain.get(); }
114
115         const PropertyMap& propertyMap() const { return m_propertyMap; }
116         PropertyMap& propertyMap() { return m_propertyMap; }
117
118         void setCachedTransistionOffset(size_t offset) { m_cachedTransistionOffset = offset; }
119         size_t cachedTransistionOffset() const { return m_cachedTransistionOffset; }
120
121         void getEnumerablePropertyNames(ExecState*, PropertyNameArray&, JSObject*);
122         void clearEnumerationCache();
123
124         static void transitionTo(StructureID* oldStructureID, StructureID* newStructureID, JSObject* slotBase);
125
126     private:
127         typedef std::pair<RefPtr<UString::Rep>, unsigned> TransitionTableKey;
128         typedef HashMap<TransitionTableKey, StructureID*, TransitionTableHash, TransitionTableHashTraits> TransitionTable;
129
130         StructureID(JSValue* prototype, const TypeInfo&);
131         
132         static const size_t s_maxTransitionLength = 64;
133
134         TypeInfo m_typeInfo;
135
136         bool m_isDictionary;
137
138         JSValue* m_prototype;
139         RefPtr<StructureIDChain> m_cachedPrototypeChain;
140
141         RefPtr<StructureID> m_previous;
142         UString::Rep* m_nameInPrevious;
143         unsigned m_attributesInPrevious;
144
145         size_t m_transitionCount;
146         TransitionTable m_transitionTable;
147
148         RefPtr<PropertyNameArrayData> m_cachedPropertyNameArrayData;
149
150         PropertyMap m_propertyMap;
151
152         size_t m_cachedTransistionOffset;
153     };
154
155     class StructureIDChain : public RefCounted<StructureIDChain> {
156     public:
157         static PassRefPtr<StructureIDChain> create(StructureID* structureID) { return adoptRef(new StructureIDChain(structureID)); }
158
159         RefPtr<StructureID>* head() { return m_vector.get(); }
160
161     private:
162         StructureIDChain(StructureID* structureID);
163
164         OwnArrayPtr<RefPtr<StructureID> > m_vector;
165     };
166
167     bool structureIDChainsAreEqual(StructureIDChain*, StructureIDChain*);
168
169 } // namespace JSC
170
171 #endif // StructureID_h