Use constexpr instead of const in symbol definitions that are obviously constexpr.
[WebKit-https.git] / Source / JavaScriptCore / runtime / PropertyNameArray.h
1 /*
2  *  Copyright (C) 2006-2019 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 propertyNameMode, PrivateSymbolMode privateSymbolMode)
51         : m_data(PropertyNameArrayData::create())
52         , m_vm(vm)
53         , m_propertyNameMode(propertyNameMode)
54         , m_privateSymbolMode(privateSymbolMode)
55     {
56     }
57
58     VM& vm() { return m_vm; }
59
60     void add(uint32_t index)
61     {
62         add(Identifier::from(m_vm, index));
63     }
64
65     void add(const Identifier&);
66     void add(UniquedStringImpl*);
67     void addUnchecked(UniquedStringImpl*);
68
69     Identifier& operator[](unsigned i) { return m_data->propertyNameVector()[i]; }
70     const Identifier& operator[](unsigned i) const { return m_data->propertyNameVector()[i]; }
71
72     PropertyNameArrayData* data() { return m_data.get(); }
73     RefPtr<PropertyNameArrayData> releaseData() { return WTFMove(m_data); }
74
75     // FIXME: Remove these functions.
76     bool canAddKnownUniqueForStructure() const { return m_data->propertyNameVector().isEmpty(); }
77     typedef PropertyNameArrayData::PropertyNameVector::const_iterator const_iterator;
78     size_t size() const { return m_data->propertyNameVector().size(); }
79     const_iterator begin() const { return m_data->propertyNameVector().begin(); }
80     const_iterator end() const { return m_data->propertyNameVector().end(); }
81
82     bool includeSymbolProperties() const;
83     bool includeStringProperties() const;
84
85     PropertyNameMode propertyNameMode() const { return m_propertyNameMode; }
86     PrivateSymbolMode privateSymbolMode() const { return m_privateSymbolMode; }
87
88 private:
89     void addUncheckedInternal(UniquedStringImpl*);
90     bool isUidMatchedToTypeMode(UniquedStringImpl* identifier);
91
92     RefPtr<PropertyNameArrayData> m_data;
93     HashSet<UniquedStringImpl*> m_set;
94     VM& m_vm;
95     PropertyNameMode m_propertyNameMode;
96     PrivateSymbolMode m_privateSymbolMode;
97 };
98
99 ALWAYS_INLINE void PropertyNameArray::add(const Identifier& identifier)
100 {
101     add(identifier.impl());
102 }
103
104 ALWAYS_INLINE void PropertyNameArray::addUncheckedInternal(UniquedStringImpl* identifier)
105 {
106     m_data->propertyNameVector().append(Identifier::fromUid(m_vm, identifier));
107 }
108
109 ALWAYS_INLINE void PropertyNameArray::addUnchecked(UniquedStringImpl* identifier)
110 {
111     if (!isUidMatchedToTypeMode(identifier))
112         return;
113     addUncheckedInternal(identifier);
114 }
115
116 ALWAYS_INLINE void PropertyNameArray::add(UniquedStringImpl* identifier)
117 {
118     static constexpr unsigned setThreshold = 20;
119
120     ASSERT(identifier);
121
122     if (!isUidMatchedToTypeMode(identifier))
123         return;
124
125     if (size() < setThreshold) {
126         if (m_data->propertyNameVector().contains(identifier))
127             return;
128     } else {
129         if (m_set.isEmpty()) {
130             for (Identifier& name : m_data->propertyNameVector())
131                 m_set.add(name.impl());
132         }
133         if (!m_set.add(identifier).isNewEntry)
134             return;
135     }
136
137     addUncheckedInternal(identifier);
138 }
139
140 ALWAYS_INLINE bool PropertyNameArray::isUidMatchedToTypeMode(UniquedStringImpl* identifier)
141 {
142     if (identifier->isSymbol()) {
143         if (!includeSymbolProperties())
144             return false;
145         if (UNLIKELY(m_privateSymbolMode == PrivateSymbolMode::Include))
146             return true;
147         return !static_cast<SymbolImpl*>(identifier)->isPrivate();
148     }
149     return includeStringProperties();
150 }
151
152 ALWAYS_INLINE bool PropertyNameArray::includeSymbolProperties() const
153 {
154     return static_cast<std::underlying_type<PropertyNameMode>::type>(m_propertyNameMode) & static_cast<std::underlying_type<PropertyNameMode>::type>(PropertyNameMode::Symbols);
155 }
156
157 ALWAYS_INLINE bool PropertyNameArray::includeStringProperties() const
158 {
159     return static_cast<std::underlying_type<PropertyNameMode>::type>(m_propertyNameMode) & static_cast<std::underlying_type<PropertyNameMode>::type>(PropertyNameMode::Strings);
160 }
161
162 } // namespace JSC