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_