1 | // -*- c-basic-offset: 2 -*- |
2 | /* |
3 | * This file is part of the KDE libraries |
4 | * Copyright (C) 2004, 2005, 2006, 2007 Apple Computer, Inc. |
5 | * Copyright (C) 2007 Christopher E. Hyde <C.Hyde@parableuk.force9.co.uk> |
6 | * |
7 | * This library is free software; you can redistribute it and/or |
8 | * modify it under the terms of the GNU Library General Public |
9 | * License as published by the Free Software Foundation; either |
10 | * version 2 of the License, or (at your option) any later version. |
11 | * |
12 | * This library is distributed in the hope that it will be useful, |
13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of |
14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
15 | * Library General Public License for more details. |
16 | * |
17 | * You should have received a copy of the GNU Library General Public License |
18 | * along with this library; see the file COPYING.LIB. If not, write to |
19 | * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, |
20 | * Boston, MA 02110-1301, USA. |
21 | * |
22 | */ |
23 | |
24 | #ifndef KJS_PROPERTY_MAP_H_ |
25 | #define KJS_PROPERTY_MAP_H_ |
26 | |
27 | #include "identifier.h" |
28 | #include <wtf/OwnArrayPtr.h> |
29 | |
30 | namespace KJS { |
31 | |
32 | class PropertyNameArray; |
33 | class JSValue; |
34 | |
35 | class SavedProperty; |
36 | |
37 | struct PropertyMapHashTable; |
38 | |
39 | // ECMA 262-3 8.6.1 |
40 | // Property attributes |
41 | enum Attribute { None = 0, |
42 | ReadOnly = 1 << 1, // property can be only read, not written |
43 | DontEnum = 1 << 2, // property doesn't appear in (for .. in ..) |
44 | DontDelete = 1 << 3, // property can't be deleted |
45 | Internal = 1 << 4, // an internal property, set to bypass checks |
46 | Function = 1 << 5, // property is a function - only used by static hashtables |
47 | GetterSetter = 1 << 6, // property is a getter or setter |
48 | DontMark = 1 << 7}; // used in locals arrays only --- indicates that the slot |
49 | // does not contain a value, and hence should not be marked. |
50 | |
51 | |
52 | /* |
53 | * Saved Properties |
54 | */ |
55 | class SavedProperties { |
56 | friend class PropertyMap; |
57 | public: |
58 | SavedProperties(); |
59 | ~SavedProperties(); |
60 | |
61 | private: |
62 | int _count; |
63 | OwnArrayPtr<SavedProperty> _properties; |
64 | }; |
65 | |
66 | /* |
67 | * A hashtable entry for the @ref PropertyMap. |
68 | */ |
69 | struct PropertyMapHashTableEntry |
70 | { |
71 | PropertyMapHashTableEntry() : key(0) { } |
72 | UString::Rep *key; |
73 | JSValue *value; |
74 | int attributes; |
75 | int index; |
76 | }; |
77 | |
78 | /** |
79 | * Javascript Property Map. |
80 | */ |
81 | class KJS_EXPORT PropertyMap { |
82 | friend class JSObject; |
83 | public: |
84 | enum PropertyMode { |
85 | ExcludeDontEnumProperties, |
86 | IncludeDontEnumProperties |
87 | }; |
88 | |
89 | PropertyMap(); |
90 | ~PropertyMap(); |
91 | |
92 | void clear(); |
93 | |
94 | void put(const Identifier &name, JSValue *value, int attributes, bool roCheck = false); |
95 | void remove(const Identifier &name); |
96 | JSValue *get(const Identifier &name) const; |
97 | JSValue *get(const Identifier &name, unsigned &attributes) const; |
98 | JSValue **getLocation(const Identifier &name); |
99 | |
100 | // Returns a location where this property can be set, if it |
101 | // exists, is writeable, and not a setter. |
102 | // Warning: this pointer may become invalid after any further modifications |
103 | JSValue **getWriteLocation(const Identifier &name); |
104 | |
105 | void mark() const; |
106 | static inline bool checkEnumerable(unsigned int attr, PropertyMode mode) |
107 | { |
108 | return (!(attr & DontEnum) || mode == PropertyMap::IncludeDontEnumProperties); |
109 | } |
110 | void getPropertyNames(PropertyNameArray&, PropertyMode mode = ExcludeDontEnumProperties) const; |
111 | |
112 | void save(SavedProperties &) const; |
113 | void restore(const SavedProperties &p); |
114 | |
115 | bool isEmpty() const; |
116 | |
117 | bool hasGetterSetterProperties() const { return m_getterSetterFlag; } |
118 | void setHasGetterSetterProperties(bool f) { m_getterSetterFlag = f; } |
119 | |
120 | void setExtensible(bool extensible) { m_extensible = extensible; } |
121 | bool isExtensible() const { return m_extensible; } |
122 | |
123 | // This /computes/ whether the table has getters or setters, while the above is |
124 | // used to cache the result. In other words, one usually does |
125 | // setHasGetterSetterProperties(containsGettersOrSetters()) whenver |
126 | // there is a reason to believe that the result has changed |
127 | bool containsGettersOrSetters() const; |
128 | private: |
129 | static bool keysMatch(const UString::Rep *, const UString::Rep *); |
130 | void expand(); |
131 | void rehash(); |
132 | void rehash(int newTableSize); |
133 | void createTable(); |
134 | |
135 | void insert(UString::Rep *, JSValue *value, int attributes, int index); |
136 | |
137 | void checkConsistency(); |
138 | |
139 | typedef PropertyMapHashTableEntry Entry; |
140 | typedef PropertyMapHashTable Table; |
141 | |
142 | UString::Rep* m_singleEntryKey; |
143 | union { |
144 | JSValue* singleEntryValue; |
145 | Table* table; |
146 | } m_u; |
147 | |
148 | |
149 | short m_singleEntryAttributes; |
150 | |
151 | bool m_getterSetterFlag : 1; |
152 | bool m_usingTable : 1; |
153 | bool m_extensible : 1; |
154 | |
155 | // We also stick some of the object's |
156 | // bitflags here. Kind of ugly, but saves memory... |
157 | bool m_objLocalInjected : 1; |
158 | }; |
159 | |
160 | inline PropertyMap::PropertyMap() : |
161 | m_singleEntryKey(0), |
162 | m_getterSetterFlag(false), |
163 | m_usingTable(false), |
164 | m_extensible(true), |
165 | m_objLocalInjected(false) |
166 | {} |
167 | } // namespace |
168 | |
169 | #endif // _KJS_PROPERTY_MAP_H_ |
170 | |