JavaScriptCore:
[WebKit-https.git] / JavaScriptCore / kjs / property_map.h
1 // -*- mode: c++; c-basic-offset: 4 -*-
2 /*
3  *  Copyright (C) 2004, 2005, 2006, 2007, 2008 Apple Inc. All rights reserved.
4  *
5  *  This library is free software; you can redistribute it and/or
6  *  modify it under the terms of the GNU Library General Public
7  *  License as published by the Free Software Foundation; either
8  *  version 2 of the License, or (at your option) any later version.
9  *
10  *  This library is distributed in the hope that it will be useful,
11  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
12  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13  *  Library General Public License for more details.
14  *
15  *  You should have received a copy of the GNU Library General Public License
16  *  along with this library; see the file COPYING.LIB.  If not, write to
17  *  the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
18  *  Boston, MA 02110-1301, USA.
19  *
20  */
21
22 #ifndef KJS_PROPERTY_MAP_H_
23 #define KJS_PROPERTY_MAP_H_
24
25 #include "identifier.h"
26 #include "protect.h"
27 #include <wtf/OwnArrayPtr.h>
28
29 namespace KJS {
30
31     class JSObject;
32     class JSValue;
33     class PropertyNameArray;
34     
35     struct PropertyMapEntry;
36     struct PropertyMapHashTable;
37
38     class SavedProperty : Noncopyable {
39     public:
40         // Since we use this in arrays, we allocate it uninitialized
41         // and then explicitly initialize. This means we can allocate
42         // the array without initializing every saved property in the
43         // array twice. To accomplish this, the class uses data members
44         // with types that don't have constructors.
45         SavedProperty();
46         void init(UString::Rep* name, JSValue*, unsigned attributes);
47         ~SavedProperty();
48
49         UString::Rep* name() const;
50         JSValue* value() const;
51         unsigned attributes() const;
52
53     private:
54         UString::Rep* m_name;
55         JSValue* m_value;
56         unsigned m_attributes;
57     };
58
59     struct SavedProperties {
60         SavedProperties();
61         ~SavedProperties();
62         
63         unsigned count;
64         OwnArrayPtr<SavedProperty> properties;
65     };
66
67     class PropertyMap : Noncopyable {
68     public:
69         PropertyMap();
70         ~PropertyMap();
71         
72         void clear();
73         
74         void put(const Identifier&, JSValue*, unsigned attributes, bool checkReadOnly = false);
75         void remove(const Identifier&);
76         JSValue* get(const Identifier&) const;
77         JSValue* get(const Identifier&, unsigned& attributes) const;
78         JSValue** getLocation(const Identifier& name);
79
80         void mark() const;
81         void getEnumerablePropertyNames(PropertyNameArray&) const;
82
83         void save(SavedProperties&) const;
84         void restore(const SavedProperties&);
85
86         bool hasGetterSetterProperties() const { return m_getterSetterFlag; }
87         void setHasGetterSetterProperties(bool f) { m_getterSetterFlag = f; }
88
89         bool containsGettersOrSetters() const;
90
91     private:
92         typedef PropertyMapEntry Entry;
93         typedef PropertyMapHashTable Table;
94
95         static bool keysMatch(const UString::Rep*, const UString::Rep*);
96         void expand();
97         void rehash();
98         void rehash(unsigned newTableSize);
99         void createTable();
100         
101         void insert(const Entry&);
102         
103         void checkConsistency();
104         
105         UString::Rep* m_singleEntryKey;
106         union {
107             JSValue* singleEntryValue;
108             Table* table;
109         } m_u;
110
111         short m_singleEntryAttributes;
112         bool m_getterSetterFlag : 1;
113         bool m_usingTable : 1;
114     };
115
116     inline PropertyMap::PropertyMap() 
117         : m_singleEntryKey(0)
118         , m_getterSetterFlag(false)
119         , m_usingTable(false)
120
121     {
122     }
123
124     inline SavedProperty::SavedProperty()
125 #ifndef NDEBUG
126         : m_name(0)
127         , m_value(0)
128         , m_attributes(0)
129 #endif
130     {
131     }
132
133     inline void SavedProperty::init(UString::Rep* name, JSValue* value, unsigned attributes)
134     {
135         ASSERT(name);
136         ASSERT(value);
137
138         ASSERT(!m_name);
139         ASSERT(!m_value);
140         ASSERT(!m_attributes);
141
142         m_name = name;
143         m_value = value;
144         m_attributes = attributes;
145         name->ref();
146         gcProtect(value);
147     }
148
149     inline SavedProperty::~SavedProperty()
150     {
151         ASSERT(m_name);
152         ASSERT(m_value);
153
154         m_name->deref();
155         gcUnprotect(m_value);
156     }
157
158     inline UString::Rep* SavedProperty::name() const
159     {
160         ASSERT(m_name);
161         ASSERT(m_value);
162
163         return m_name;
164     }
165
166     inline JSValue* SavedProperty::value() const
167     {
168         ASSERT(m_name);
169         ASSERT(m_value);
170
171         return m_value;
172     }
173
174     inline unsigned SavedProperty::attributes() const
175     {
176         ASSERT(m_name);
177         ASSERT(m_value);
178
179         return m_attributes;
180     }
181
182 } // namespace
183
184 #endif // _KJS_PROPERTY_MAP_H_