1 /* 2 * Copyright (c) 2021 Huawei Device Co., Ltd. 3 * Licensed under the Apache License, Version 2.0 (the "License"); 4 * you may not use this file except in compliance with the License. 5 * You may obtain a copy of the License at 6 * 7 * http://www.apache.org/licenses/LICENSE-2.0 8 * 9 * Unless required by applicable law or agreed to in writing, software 10 * distributed under the License is distributed on an "AS IS" BASIS, 11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 * See the License for the specific language governing permissions and 13 * limitations under the License. 14 */ 15 16 #ifndef ECMASCRIPT_SYMBOL_TABLE_H 17 #define ECMASCRIPT_SYMBOL_TABLE_H 18 19 #include "ecmascript/ecma_string.h" 20 #include "ecmascript/ecma_vm.h" 21 #include "ecmascript/js_symbol.h" 22 #include "ecmascript/js_thread.h" 23 #include "ecmascript/object_factory.h" 24 #include "ecmascript/tagged_hash_table.h" 25 26 namespace panda::ecmascript { 27 class SymbolTable : public TaggedHashTable<SymbolTable> { 28 public: 29 using HashTable = TaggedHashTable<SymbolTable>; Cast(TaggedObject * object)30 static SymbolTable *Cast(TaggedObject *object) 31 { 32 return reinterpret_cast<SymbolTable *>(object); 33 } GetKeyIndex(int entry)34 inline static int GetKeyIndex(int entry) 35 { 36 return HashTable::TABLE_HEADER_SIZE + entry * GetEntrySize() + ENTRY_KEY_INDEX; 37 } GetValueIndex(int entry)38 inline static int GetValueIndex(int entry) 39 { 40 return HashTable::TABLE_HEADER_SIZE + entry * GetEntrySize() + ENTRY_VALUE_INDEX; 41 } GetEntryIndex(int entry)42 inline static int GetEntryIndex(int entry) 43 { 44 return HashTable::TABLE_HEADER_SIZE + entry * GetEntrySize(); 45 } GetEntrySize()46 inline static int GetEntrySize() 47 { 48 return ENTRY_SIZE; 49 } IsMatch(const JSTaggedValue & name,const JSTaggedValue & other)50 static inline bool IsMatch(const JSTaggedValue &name, const JSTaggedValue &other) 51 { 52 if (name.IsHole() || name.IsUndefined()) { 53 return false; 54 } 55 56 auto *nameString = static_cast<EcmaString *>(name.GetTaggedObject()); 57 auto *otherString = static_cast<EcmaString *>(other.GetTaggedObject()); 58 return EcmaStringAccessor::StringsAreEqual(nameString, otherString); 59 } Hash(const JSTaggedValue & obj)60 static inline uint32_t Hash(const JSTaggedValue &obj) 61 { 62 if (obj.IsHeapObject()) { 63 if (obj.IsString()) { 64 auto *nameString = static_cast<EcmaString *>(obj.GetTaggedObject()); 65 return EcmaStringAccessor(nameString).GetHashcode(); 66 } 67 return JSSymbol::ComputeHash(); 68 } 69 UNREACHABLE(); 70 } 71 72 static const int DEFAULT_ELEMENTS_NUMBER = 64; 73 static JSHandle<SymbolTable> Create(JSThread *thread, int numberOfElements = DEFAULT_ELEMENTS_NUMBER) 74 { 75 return HashTable::Create(thread, numberOfElements); 76 } 77 ContainsKey(const JSTaggedValue & key)78 inline bool ContainsKey(const JSTaggedValue &key) 79 { 80 int entry = FindEntry(key); 81 return entry != -1; 82 } 83 GetSymbol(const JSTaggedValue & key)84 inline JSTaggedValue GetSymbol(const JSTaggedValue &key) 85 { 86 int entry = FindEntry(key); 87 ASSERT(entry != -1); 88 return GetValue(entry); 89 } 90 FindSymbol(const JSTaggedValue & value)91 inline JSTaggedValue FindSymbol(const JSTaggedValue &value) 92 { 93 JSSymbol *symbol = JSSymbol::Cast(value.GetTaggedObject()); 94 JSTaggedValue des = symbol->GetDescription(); 95 if (!des.IsUndefined()) { 96 if (ContainsKey(des)) { 97 return des; 98 } 99 } 100 return JSTaggedValue::Undefined(); 101 } ComputeCompactSize(const JSHandle<SymbolTable> & table,int computeHashTableSize,int tableSize,int addedElements)102 static int ComputeCompactSize([[maybe_unused]] const JSHandle<SymbolTable> &table, int computeHashTableSize, 103 [[maybe_unused]] int tableSize, [[maybe_unused]] int addedElements) 104 { 105 return computeHashTableSize; 106 } 107 static constexpr int ENTRY_KEY_INDEX = 0; 108 static constexpr int ENTRY_VALUE_INDEX = 1; 109 static constexpr int ENTRY_SIZE = 2; 110 }; 111 } // namespace panda::ecmascript 112 #endif // ECMASCRIPT_SYMBOL_TABLE_H