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