File indexing completed on 2024-05-12 15:43:32
0001 /* 0002 * This file is part of the KDE libraries 0003 * Copyright (C) 2004, 2005, 2006, 2007 Apple Computer, Inc. 0004 * Copyright (C) 2007 Christopher E. Hyde <C.Hyde@parableuk.force9.co.uk> 0005 * 0006 * This library is free software; you can redistribute it and/or 0007 * modify it under the terms of the GNU Library General Public 0008 * License as published by the Free Software Foundation; either 0009 * version 2 of the License, or (at your option) any later version. 0010 * 0011 * This library is distributed in the hope that it will be useful, 0012 * but WITHOUT ANY WARRANTY; without even the implied warranty of 0013 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 0014 * Library General Public License for more details. 0015 * 0016 * You should have received a copy of the GNU Library General Public License 0017 * along with this library; see the file COPYING.LIB. If not, write to 0018 * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, 0019 * Boston, MA 02110-1301, USA. 0020 * 0021 */ 0022 0023 #ifndef KJS_PROPERTY_MAP_H_ 0024 #define KJS_PROPERTY_MAP_H_ 0025 0026 #include "identifier.h" 0027 #include <wtf/OwnArrayPtr.h> 0028 0029 namespace KJS 0030 { 0031 0032 class PropertyNameArray; 0033 class JSValue; 0034 0035 class SavedProperty; 0036 0037 struct PropertyMapHashTable; 0038 0039 // ECMA 262-3 8.6.1 0040 // Property attributes 0041 enum Attribute { None = 0, 0042 ReadOnly = 1 << 1, // property can be only read, not written 0043 DontEnum = 1 << 2, // property doesn't appear in (for .. in ..) 0044 DontDelete = 1 << 3, // property can't be deleted 0045 Internal = 1 << 4, // an internal property, set to bypass checks 0046 Function = 1 << 5, // property is a function - only used by static hashtables 0047 GetterSetter = 1 << 6, // property is a getter or setter 0048 DontMark = 1 << 7 0049 }; // used in locals arrays only --- indicates that the slot 0050 // does not contain a value, and hence should not be marked. 0051 0052 /* 0053 * Saved Properties 0054 */ 0055 class SavedProperties 0056 { 0057 friend class PropertyMap; 0058 public: 0059 SavedProperties(); 0060 ~SavedProperties(); 0061 0062 private: 0063 int _count; 0064 OwnArrayPtr<SavedProperty> _properties; 0065 }; 0066 0067 /* 0068 * A hashtable entry for the @ref PropertyMap. 0069 */ 0070 struct PropertyMapHashTableEntry { 0071 PropertyMapHashTableEntry() : key(nullptr) { } 0072 UString::Rep *key; 0073 JSValue *value; 0074 int attributes; 0075 int index; 0076 }; 0077 0078 /** 0079 * Javascript Property Map. 0080 */ 0081 class KJS_EXPORT PropertyMap 0082 { 0083 friend class JSObject; 0084 public: 0085 enum PropertyMode { 0086 ExcludeDontEnumProperties, 0087 IncludeDontEnumProperties 0088 }; 0089 0090 PropertyMap(); 0091 ~PropertyMap(); 0092 0093 void clear(); 0094 0095 void put(const Identifier &name, JSValue *value, int attributes, bool roCheck = false); 0096 void remove(const Identifier &name); 0097 JSValue *get(const Identifier &name) const; 0098 JSValue *get(const Identifier &name, unsigned &attributes) const; 0099 JSValue **getLocation(const Identifier &name); 0100 0101 // Returns a location where this property can be set, if it 0102 // exists, is writeable, and not a setter. 0103 // Warning: this pointer may become invalid after any further modifications 0104 JSValue **getWriteLocation(const Identifier &name); 0105 0106 void mark() const; 0107 static inline bool checkEnumerable(unsigned int attr, PropertyMode mode) 0108 { 0109 return (!(attr & DontEnum) || mode == PropertyMap::IncludeDontEnumProperties); 0110 } 0111 void getPropertyNames(PropertyNameArray &, PropertyMode mode = ExcludeDontEnumProperties) const; 0112 0113 void save(SavedProperties &) const; 0114 void restore(const SavedProperties &p); 0115 0116 bool isEmpty() const; 0117 0118 bool hasGetterSetterProperties() const 0119 { 0120 return m_getterSetterFlag; 0121 } 0122 void setHasGetterSetterProperties(bool f) 0123 { 0124 m_getterSetterFlag = f; 0125 } 0126 0127 void setExtensible(bool extensible) 0128 { 0129 m_extensible = extensible; 0130 } 0131 bool isExtensible() const 0132 { 0133 return m_extensible; 0134 } 0135 0136 // This /computes/ whether the table has getters or setters, while the above is 0137 // used to cache the result. In other words, one usually does 0138 // setHasGetterSetterProperties(containsGettersOrSetters()) whenever 0139 // there is a reason to believe that the result has changed 0140 bool containsGettersOrSetters() const; 0141 private: 0142 static bool keysMatch(const UString::Rep *, const UString::Rep *); 0143 void expand(); 0144 void rehash(); 0145 void rehash(int newTableSize); 0146 void createTable(); 0147 0148 void insert(UString::Rep *, JSValue *value, int attributes, int index); 0149 0150 void checkConsistency(); 0151 0152 typedef PropertyMapHashTableEntry Entry; 0153 typedef PropertyMapHashTable Table; 0154 0155 UString::Rep *m_singleEntryKey; 0156 union { 0157 JSValue *singleEntryValue; 0158 Table *table; 0159 } m_u; 0160 0161 short m_singleEntryAttributes; 0162 0163 bool m_getterSetterFlag : 1; 0164 bool m_usingTable : 1; 0165 bool m_extensible : 1; 0166 0167 // We also stick some of the object's 0168 // bitflags here. Kind of ugly, but saves memory... 0169 bool m_objLocalInjected : 1; 0170 }; 0171 0172 inline PropertyMap::PropertyMap() : 0173 m_singleEntryKey(nullptr), 0174 m_getterSetterFlag(false), 0175 m_usingTable(false), 0176 m_extensible(true), 0177 m_objLocalInjected(false) 0178 {} 0179 } // namespace 0180 0181 #endif // _KJS_PROPERTY_MAP_H_