Remove excessive headers from JavaScriptCore
[WebKit-https.git] / Source / JavaScriptCore / runtime / PropertyNameArray.h
1 /*
2  *  Copyright (C) 2006, 2008, 2012 Apple Inc. All rights reserved.
3  *
4  *  This library is free software; you can redistribute it and/or
5  *  modify it under the terms of the GNU Library General Public
6  *  License as published by the Free Software Foundation; either
7  *  version 2 of the License, or (at your option) any later version.
8  *
9  *  This library is distributed in the hope that it will be useful,
10  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
11  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
12  *  Library General Public License for more details.
13  *
14  *  You should have received a copy of the GNU Library General Public License
15  *  along with this library; see the file COPYING.LIB.  If not, write to
16  *  the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
17  *  Boston, MA 02110-1301, USA.
18  *
19  */
20
21 #pragma once
22
23 #include "CallFrame.h"
24 #include "Identifier.h"
25 #include <wtf/HashSet.h>
26 #include <wtf/Vector.h>
27
28 namespace JSC {
29
30 // FIXME: Rename to PropertyNameArray.
31 class PropertyNameArrayData : public RefCounted<PropertyNameArrayData> {
32 public:
33     typedef Vector<Identifier, 20> PropertyNameVector;
34
35     static Ref<PropertyNameArrayData> create() { return adoptRef(*new PropertyNameArrayData); }
36
37     PropertyNameVector& propertyNameVector() { return m_propertyNameVector; }
38
39 private:
40     PropertyNameArrayData()
41     {
42     }
43
44     PropertyNameVector m_propertyNameVector;
45 };
46
47 // FIXME: Rename to PropertyNameArrayBuilder.
48 class PropertyNameArray {
49 public:
50     PropertyNameArray(VM* vm, PropertyNameMode mode)
51         : m_data(PropertyNameArrayData::create())
52         , m_vm(vm)
53         , m_mode(mode)
54     {
55     }
56
57     PropertyNameArray(ExecState* exec, PropertyNameMode mode)
58         : PropertyNameArray(&exec->vm(), mode)
59     {
60     }
61
62     VM* vm() { return m_vm; }
63
64     void add(uint32_t index)
65     {
66         add(Identifier::from(m_vm, index));
67     }
68
69     void add(const Identifier&);
70     void add(UniquedStringImpl*);
71     void addUnchecked(UniquedStringImpl*);
72
73     Identifier& operator[](unsigned i) { return m_data->propertyNameVector()[i]; }
74     const Identifier& operator[](unsigned i) const { return m_data->propertyNameVector()[i]; }
75
76     PropertyNameArrayData* data() { return m_data.get(); }
77     RefPtr<PropertyNameArrayData> releaseData() { return WTFMove(m_data); }
78
79     // FIXME: Remove these functions.
80     bool canAddKnownUniqueForStructure() const { return m_data->propertyNameVector().isEmpty(); }
81     typedef PropertyNameArrayData::PropertyNameVector::const_iterator const_iterator;
82     size_t size() const { return m_data->propertyNameVector().size(); }
83     const_iterator begin() const { return m_data->propertyNameVector().begin(); }
84     const_iterator end() const { return m_data->propertyNameVector().end(); }
85
86     PropertyNameMode mode() const { return m_mode; }
87     bool includeSymbolProperties() const;
88     bool includeStringProperties() const;
89
90 private:
91     bool isUidMatchedToTypeMode(UniquedStringImpl* identifier);
92
93     RefPtr<PropertyNameArrayData> m_data;
94     HashSet<UniquedStringImpl*> m_set;
95     VM* m_vm;
96     PropertyNameMode m_mode;
97 };
98
99 ALWAYS_INLINE void PropertyNameArray::add(const Identifier& identifier)
100 {
101     add(identifier.impl());
102 }
103
104 ALWAYS_INLINE void PropertyNameArray::addUnchecked(UniquedStringImpl* identifier)
105 {
106     if (!isUidMatchedToTypeMode(identifier))
107         return;
108     m_data->propertyNameVector().append(Identifier::fromUid(m_vm, identifier));
109 }
110
111 ALWAYS_INLINE void PropertyNameArray::add(UniquedStringImpl* identifier)
112 {
113     static const unsigned setThreshold = 20;
114
115     ASSERT(identifier);
116
117     if (!isUidMatchedToTypeMode(identifier))
118         return;
119
120     if (size() < setThreshold) {
121         if (m_data->propertyNameVector().contains(identifier))
122             return;
123     } else {
124         if (m_set.isEmpty()) {
125             for (Identifier& name : m_data->propertyNameVector())
126                 m_set.add(name.impl());
127         }
128         if (!m_set.add(identifier).isNewEntry)
129             return;
130     }
131
132     addUnchecked(identifier);
133 }
134
135 ALWAYS_INLINE bool PropertyNameArray::isUidMatchedToTypeMode(UniquedStringImpl* identifier)
136 {
137     if (identifier->isSymbol())
138         return includeSymbolProperties();
139     return includeStringProperties();
140 }
141
142 ALWAYS_INLINE bool PropertyNameArray::includeSymbolProperties() const
143 {
144     return static_cast<std::underlying_type<PropertyNameMode>::type>(m_mode) & static_cast<std::underlying_type<PropertyNameMode>::type>(PropertyNameMode::Symbols);
145 }
146
147 ALWAYS_INLINE bool PropertyNameArray::includeStringProperties() const
148 {
149     return static_cast<std::underlying_type<PropertyNameMode>::type>(m_mode) & static_cast<std::underlying_type<PropertyNameMode>::type>(PropertyNameMode::Strings);
150 }
151
152 } // namespace JSC