Changeset 262613 in webkit for trunk/Source/JavaScriptCore/parser/VariableEnvironment.h
- Timestamp:
- Jun 5, 2020, 4:25:43 AM (5 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/Source/JavaScriptCore/parser/VariableEnvironment.h
r255659 r262613 28 28 #include "Identifier.h" 29 29 #include <wtf/HashMap.h> 30 #include <wtf/HashSet.h> 31 #include <wtf/IteratorRange.h> 30 32 31 33 namespace JSC { … … 43 45 ALWAYS_INLINE bool isParameter() const { return m_bits & IsParameter; } 44 46 ALWAYS_INLINE bool isSloppyModeHoistingCandidate() const { return m_bits & IsSloppyModeHoistingCandidate; } 47 ALWAYS_INLINE bool isPrivateName() const { return m_bits & IsPrivateName; } 45 48 46 49 ALWAYS_INLINE void setIsCaptured() { m_bits |= IsCaptured; } … … 54 57 ALWAYS_INLINE void setIsParameter() { m_bits |= IsParameter; } 55 58 ALWAYS_INLINE void setIsSloppyModeHoistingCandidate() { m_bits |= IsSloppyModeHoistingCandidate; } 59 ALWAYS_INLINE void setIsPrivateName() { m_bits |= IsPrivateName; } 56 60 57 61 ALWAYS_INLINE void clearIsVar() { m_bits &= ~IsVar; } … … 75 79 IsFunction = 1 << 7, 76 80 IsParameter = 1 << 8, 77 IsSloppyModeHoistingCandidate = 1 << 9 81 IsSloppyModeHoistingCandidate = 1 << 9, 82 IsPrivateName = 1 << 10, 78 83 }; 79 84 uint16_t m_bits { 0 }; … … 84 89 }; 85 90 91 struct PrivateNameEntry { 92 public: 93 PrivateNameEntry(uint16_t traits = 0) { m_bits = traits; } 94 95 ALWAYS_INLINE bool isUsed() const { return m_bits & IsUsed; } 96 ALWAYS_INLINE bool isDeclared() const { return m_bits & IsDeclared; } 97 98 ALWAYS_INLINE void setIsUsed() { m_bits |= IsUsed; } 99 ALWAYS_INLINE void setIsDeclared() { m_bits |= IsDeclared; } 100 101 uint16_t bits() const { return m_bits; } 102 103 bool operator==(const PrivateNameEntry& other) const 104 { 105 return m_bits == other.m_bits; 106 } 107 108 enum Traits : uint16_t { 109 IsUsed = 1 << 0, 110 IsDeclared = 1 << 1, 111 }; 112 113 private: 114 uint16_t m_bits { 0 }; 115 }; 116 117 struct PrivateNameEntryHashTraits : HashTraits<PrivateNameEntry> { 118 static const bool needsDestruction = false; 119 }; 120 86 121 class VariableEnvironment { 87 122 private: 88 123 typedef HashMap<PackedRefPtr<UniquedStringImpl>, VariableEnvironmentEntry, IdentifierRepHash, HashTraits<RefPtr<UniquedStringImpl>>, VariableEnvironmentEntryHashTraits> Map; 124 typedef HashMap<PackedRefPtr<UniquedStringImpl>, PrivateNameEntry, IdentifierRepHash, HashTraits<RefPtr<UniquedStringImpl>>, PrivateNameEntryHashTraits> PrivateNames; 89 125 public: 90 VariableEnvironment() = default; 91 VariableEnvironment(VariableEnvironment&& other) = default; 92 VariableEnvironment(const VariableEnvironment&) = default; 93 VariableEnvironment& operator=(const VariableEnvironment&) = default; 94 VariableEnvironment& operator=(VariableEnvironment&&) = default; 126 VariableEnvironment() { } 127 VariableEnvironment(VariableEnvironment&& other) 128 : m_map(WTFMove(other.m_map)) 129 , m_isEverythingCaptured(other.m_isEverythingCaptured) 130 , m_rareData(WTFMove(other.m_rareData)) 131 { 132 } 133 VariableEnvironment(const VariableEnvironment& other) 134 : m_map(other.m_map) 135 , m_isEverythingCaptured(other.m_isEverythingCaptured) 136 , m_rareData(other.m_rareData ? WTF::makeUnique<VariableEnvironment::RareData>(*other.m_rareData) : nullptr) 137 { 138 } 139 VariableEnvironment& operator=(const VariableEnvironment& other); 95 140 96 141 ALWAYS_INLINE Map::iterator begin() { return m_map.begin(); } … … 100 145 ALWAYS_INLINE Map::AddResult add(const RefPtr<UniquedStringImpl>& identifier) { return m_map.add(identifier, VariableEnvironmentEntry()); } 101 146 ALWAYS_INLINE Map::AddResult add(const Identifier& identifier) { return add(identifier.impl()); } 102 ALWAYS_INLINE unsigned size() const { return m_map.size(); } 147 ALWAYS_INLINE unsigned size() const { return m_map.size() + privateNamesSize(); } 148 ALWAYS_INLINE unsigned mapSize() const { return m_map.size(); } 103 149 ALWAYS_INLINE bool contains(const RefPtr<UniquedStringImpl>& identifier) const { return m_map.contains(identifier); } 104 150 ALWAYS_INLINE bool remove(const RefPtr<UniquedStringImpl>& identifier) { return m_map.remove(identifier); } … … 117 163 bool isEmpty() const { return !m_map.size(); } 118 164 165 using PrivateNamesRange = WTF::IteratorRange<PrivateNames::iterator>; 166 167 ALWAYS_INLINE Map::AddResult declarePrivateName(const Identifier& identifier) { return declarePrivateName(identifier.impl()); } 168 ALWAYS_INLINE void usePrivateName(const Identifier& identifier) { usePrivateName(identifier.impl()); } 169 170 Map::AddResult declarePrivateName(const RefPtr<UniquedStringImpl>& identifier) 171 { 172 auto& meta = getOrAddPrivateName(identifier.get()); 173 meta.setIsDeclared(); 174 auto entry = VariableEnvironmentEntry(); 175 entry.setIsPrivateName(); 176 entry.setIsConst(); 177 entry.setIsCaptured(); 178 return m_map.add(identifier, entry); 179 } 180 void usePrivateName(const RefPtr<UniquedStringImpl>& identifier) 181 { 182 auto& meta = getOrAddPrivateName(identifier.get()); 183 meta.setIsUsed(); 184 if (meta.isDeclared()) 185 find(identifier)->value.setIsCaptured(); 186 } 187 188 ALWAYS_INLINE PrivateNamesRange privateNames() const 189 { 190 // Use of the IteratorRange must be guarded to prevent ASSERT failures in checkValidity(). 191 ASSERT(privateNamesSize() > 0); 192 return makeIteratorRange(m_rareData->m_privateNames.begin(), m_rareData->m_privateNames.end()); 193 } 194 195 ALWAYS_INLINE unsigned privateNamesSize() const 196 { 197 if (!m_rareData) 198 return 0; 199 return m_rareData->m_privateNames.size(); 200 } 201 202 ALWAYS_INLINE bool hasPrivateName(const Identifier& identifier) 203 { 204 if (!m_rareData) 205 return false; 206 return m_rareData->m_privateNames.contains(identifier.impl()); 207 } 208 209 ALWAYS_INLINE void copyPrivateNamesTo(VariableEnvironment& other) const 210 { 211 if (!m_rareData) 212 return; 213 if (!other.m_rareData) 214 other.m_rareData = WTF::makeUnique<VariableEnvironment::RareData>(); 215 if (privateNamesSize() > 0) { 216 for (auto entry : privateNames()) { 217 if (!(entry.value.isUsed() && entry.value.isDeclared())) 218 other.m_rareData->m_privateNames.add(entry.key, entry.value); 219 } 220 } 221 } 222 223 ALWAYS_INLINE void copyUndeclaredPrivateNamesTo(VariableEnvironment& outer) const { 224 // Used by the Parser to transfer recorded uses of PrivateNames from an 225 // inner PrivateNameEnvironment into an outer one, in case a PNE is used 226 // earlier in the source code than it is defined. 227 if (privateNamesSize() > 0) { 228 for (auto entry : privateNames()) { 229 if (entry.value.isUsed() && !entry.value.isDeclared()) 230 outer.getOrAddPrivateName(entry.key.get()).setIsUsed(); 231 } 232 } 233 } 234 235 struct RareData { 236 WTF_MAKE_STRUCT_FAST_ALLOCATED; 237 238 RareData() { } 239 RareData(RareData&& other) 240 : m_privateNames(WTFMove(other.m_privateNames)) 241 { 242 } 243 RareData(const RareData&) = default; 244 RareData& operator=(const RareData&) = default; 245 PrivateNames m_privateNames; 246 }; 247 119 248 private: 120 249 friend class CachedVariableEnvironment; … … 122 251 Map m_map; 123 252 bool m_isEverythingCaptured { false }; 253 254 PrivateNameEntry& getOrAddPrivateName(UniquedStringImpl* impl) 255 { 256 if (!m_rareData) 257 m_rareData = WTF::makeUnique<VariableEnvironment::RareData>(); 258 259 return m_rareData->m_privateNames.add(impl, PrivateNameEntry()).iterator->value; 260 } 261 262 std::unique_ptr<VariableEnvironment::RareData> m_rareData; 124 263 }; 125 264
Note:
See TracChangeset
for help on using the changeset viewer.