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 26namespace panda::ecmascript { 27class SymbolTable : public TaggedHashTable<SymbolTable> { 28public: 29 using HashTable = TaggedHashTable<SymbolTable>; 30 static SymbolTable *Cast(TaggedObject *object) 31 { 32 return reinterpret_cast<SymbolTable *>(object); 33 } 34 inline static int GetKeyIndex(int entry) 35 { 36 return HashTable::TABLE_HEADER_SIZE + entry * GetEntrySize() + ENTRY_KEY_INDEX; 37 } 38 inline static int GetValueIndex(int entry) 39 { 40 return HashTable::TABLE_HEADER_SIZE + entry * GetEntrySize() + ENTRY_VALUE_INDEX; 41 } 42 inline static int GetEntryIndex(int entry) 43 { 44 return HashTable::TABLE_HEADER_SIZE + entry * GetEntrySize(); 45 } 46 inline static int GetEntrySize() 47 { 48 return ENTRY_SIZE; 49 } 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 } 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 LOG_ECMA(FATAL) << "this branch is unreachable"; 70 UNREACHABLE(); 71 } 72 73 static const int DEFAULT_ELEMENTS_NUMBER = 64; 74 static JSHandle<SymbolTable> Create(JSThread *thread, int numberOfElements = DEFAULT_ELEMENTS_NUMBER) 75 { 76 return HashTable::Create(thread, numberOfElements); 77 } 78 79 inline bool ContainsKey(const JSTaggedValue &key) 80 { 81 int entry = FindEntry(key); 82 return entry != -1; 83 } 84 85 inline JSTaggedValue GetSymbol(const JSTaggedValue &key) 86 { 87 int entry = FindEntry(key); 88 ASSERT(entry != -1); 89 return GetValue(entry); 90 } 91 92 inline JSTaggedValue FindSymbol(const JSTaggedValue &value) 93 { 94 JSSymbol *symbol = JSSymbol::Cast(value.GetTaggedObject()); 95 JSTaggedValue des = symbol->GetDescription(); 96 if (!des.IsUndefined()) { 97 if (ContainsKey(des)) { 98 return des; 99 } 100 } 101 return JSTaggedValue::Undefined(); 102 } 103 static int ComputeCompactSize([[maybe_unused]] const JSHandle<SymbolTable> &table, int computeHashTableSize, 104 [[maybe_unused]] int tableSize, [[maybe_unused]] int addedElements) 105 { 106 return computeHashTableSize; 107 } 108 static constexpr int ENTRY_KEY_INDEX = 0; 109 static constexpr int ENTRY_VALUE_INDEX = 1; 110 static constexpr int ENTRY_SIZE = 2; 111}; 112} // namespace panda::ecmascript 113#endif // ECMASCRIPT_SYMBOL_TABLE_H