1 /* 2 * Copyright (c) 2022 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_COMPILER_BUILTINS_LINKED_HASHTABLE_STUB_BUILDER_H 17 #define ECMASCRIPT_COMPILER_BUILTINS_LINKED_HASHTABLE_STUB_BUILDER_H 18 #include "ecmascript/compiler/stub_builder-inl.h" 19 20 namespace panda::ecmascript::kungfu { 21 22 template<typename LinkedHashTableType, typename LinkedHashTableObject> 23 class LinkedHashTableStubBuilder : public BuiltinsStubBuilder { 24 public: LinkedHashTableStubBuilder(BuiltinsStubBuilder * parent,GateRef glue)25 explicit LinkedHashTableStubBuilder(BuiltinsStubBuilder *parent, GateRef glue) 26 : BuiltinsStubBuilder(parent), glue_(glue) {} 27 ~LinkedHashTableStubBuilder() override = default; 28 NO_MOVE_SEMANTIC(LinkedHashTableStubBuilder); 29 NO_COPY_SEMANTIC(LinkedHashTableStubBuilder); GenerateCircuit()30 void GenerateCircuit() override {} 31 32 GateRef Create(GateRef numberOfElements); 33 GateRef Clear(GateRef linkedTable); 34 GateRef ForEach(GateRef thisValue, GateRef linkedTable, GateRef numArgs); 35 GateRef Insert(GateRef linkedTable, GateRef key, GateRef value); 36 GateRef Delete(GateRef linkedTable, GateRef key); 37 GateRef Has(GateRef linkedTable, GateRef key); 38 39 private: IsKey(GateRef key)40 GateRef IsKey(GateRef key) 41 { 42 return TaggedIsNotHole(key); 43 } 44 HashToBucket(GateRef linkedTable,GateRef hash)45 GateRef HashToBucket(GateRef linkedTable, GateRef hash) 46 { 47 GateRef cap = GetCapacity(linkedTable); 48 return Int32And(hash, Int32Sub(cap, Int32(1))); 49 } 50 BucketToIndex(GateRef bucket)51 GateRef BucketToIndex(GateRef bucket) 52 { 53 return Int32Add(bucket, Int32(LinkedHashTableType::ELEMENTS_START_INDEX)); 54 } 55 56 GateRef GetHash(GateRef key); 57 GateRef HashObjectIsMatch(GateRef key, GateRef other); 58 GateRef FindElement(GateRef linkedTable, GateRef key); GetKey(GateRef linkedTable,GateRef entry)59 GateRef GetKey(GateRef linkedTable, GateRef entry) 60 { 61 GateRef index = EntryToIndex(linkedTable, entry); 62 return GetElement(linkedTable, index); 63 } 64 SetKey(GateRef linkedTable,GateRef entry,GateRef key)65 void SetKey(GateRef linkedTable, GateRef entry, GateRef key) 66 { 67 GateRef index = EntryToIndex(linkedTable, entry); 68 SetElement(linkedTable, index, key); 69 } 70 GetValue(GateRef linkedTable,GateRef entry)71 GateRef GetValue(GateRef linkedTable, GateRef entry) 72 { 73 GateRef index = EntryToIndex(linkedTable, entry); 74 GateRef valueIndex = Int32(LinkedHashTableObject::ENTRY_VALUE_INDEX); 75 return GetElement(linkedTable, Int32Add(index, valueIndex)); 76 } 77 SetValue(GateRef linkedTable,GateRef entry,GateRef value)78 void SetValue(GateRef linkedTable, GateRef entry, GateRef value) 79 { 80 GateRef index = EntryToIndex(linkedTable, entry); 81 GateRef valueIndex = Int32(LinkedHashTableObject::ENTRY_VALUE_INDEX); 82 SetElement(linkedTable, Int32Add(index, valueIndex), value); 83 } 84 EntryToIndex(GateRef linkedTable,GateRef entry)85 GateRef EntryToIndex(GateRef linkedTable, GateRef entry) 86 { 87 int32_t startIndex = LinkedHashTableType::ELEMENTS_START_INDEX; 88 int32_t entrySize = LinkedHashTableObject::ENTRY_SIZE; 89 GateRef sumEntrySize = Int32Mul(entry, Int32Add(Int32(entrySize), Int32(1))); 90 return Int32Add(Int32(startIndex), Int32Add(GetCapacity(linkedTable), sumEntrySize)); 91 } 92 GetElement(GateRef linkedTable,GateRef index)93 GateRef GetElement(GateRef linkedTable, GateRef index) 94 { 95 return GetValueFromTaggedArray(linkedTable, index); 96 } 97 SetElement(GateRef linkedTable,GateRef index,GateRef value)98 void SetElement(GateRef linkedTable, GateRef index, GateRef value) 99 { 100 SetValueToTaggedArray(VariableType::JS_ANY(), glue_, linkedTable, index, value); 101 } 102 GetDeletedNum(GateRef linkedTable,GateRef entry)103 GateRef GetDeletedNum(GateRef linkedTable, GateRef entry) 104 { 105 return TaggedGetInt(GetNextEntry(linkedTable, entry)); 106 } 107 SetDeletedNum(GateRef linkedTable,GateRef entry,GateRef num)108 void SetDeletedNum(GateRef linkedTable, GateRef entry, GateRef num) 109 { 110 SetNextEntry(linkedTable, entry, IntToTaggedInt(num)); 111 } 112 GetNextEntry(GateRef linkedTable,GateRef entry)113 GateRef GetNextEntry(GateRef linkedTable, GateRef entry) 114 { 115 GateRef entryIndex = EntryToIndex(linkedTable, entry); 116 return GetElement(linkedTable, Int32Add(entryIndex, Int32(LinkedHashTableObject::ENTRY_SIZE))); 117 } 118 SetNextEntry(GateRef linkedTable,GateRef entry,GateRef nextEntry)119 void SetNextEntry(GateRef linkedTable, GateRef entry, GateRef nextEntry) 120 { 121 GateRef entryIndex = EntryToIndex(linkedTable, entry); 122 SetElement(linkedTable, Int32Add(entryIndex, Int32(LinkedHashTableObject::ENTRY_SIZE)), nextEntry); 123 } 124 GetCapacity(GateRef linkedTable)125 GateRef GetCapacity(GateRef linkedTable) 126 { 127 GateRef capacityIndex = Int32(LinkedHashTableType::CAPACITY_INDEX); 128 GateRef capacity = GetValueFromTaggedArray(linkedTable, capacityIndex); 129 return TaggedGetInt(capacity); 130 } 131 SetCapacity(GateRef linkedTable,GateRef numberOfElements)132 void SetCapacity(GateRef linkedTable, GateRef numberOfElements) 133 { 134 GateRef capacityIndex = Int32(LinkedHashTableType::CAPACITY_INDEX); 135 SetValueToTaggedArray(VariableType::JS_NOT_POINTER(), glue_, linkedTable, capacityIndex, 136 IntToTaggedInt(numberOfElements)); 137 } 138 GetNumberOfElements(GateRef linkedTable)139 GateRef GetNumberOfElements(GateRef linkedTable) 140 { 141 int32_t elementsIndex = LinkedHashTableType::NUMBER_OF_ELEMENTS_INDEX; 142 GateRef tmpNumberOfElements = GetValueFromTaggedArray(linkedTable, Int32(elementsIndex)); 143 return TaggedGetInt(tmpNumberOfElements); 144 } 145 SetNumberOfElements(GateRef linkedTable,GateRef num)146 void SetNumberOfElements(GateRef linkedTable, GateRef num) 147 { 148 int32_t elementsIndex = LinkedHashTableType::NUMBER_OF_ELEMENTS_INDEX; 149 SetValueToTaggedArray(VariableType::JS_NOT_POINTER(), glue_, linkedTable, Int32(elementsIndex), 150 IntToTaggedInt(num)); 151 } 152 GetNumberOfDeletedElements(GateRef linkedTable)153 GateRef GetNumberOfDeletedElements(GateRef linkedTable) 154 { 155 GateRef deletedIndex = Int32(LinkedHashTableType::NUMBER_OF_DELETED_ELEMENTS_INDEX); 156 GateRef tmpNumberOfDeletedElements = GetValueFromTaggedArray(linkedTable, deletedIndex); 157 return TaggedGetInt(tmpNumberOfDeletedElements); 158 } 159 SetNumberOfDeletedElements(GateRef linkedTable,GateRef num)160 void SetNumberOfDeletedElements(GateRef linkedTable, GateRef num) 161 { 162 GateRef deletedIndex = Int32(LinkedHashTableType::NUMBER_OF_DELETED_ELEMENTS_INDEX); 163 SetValueToTaggedArray(VariableType::JS_NOT_POINTER(), glue_, linkedTable, deletedIndex, IntToTaggedInt(num)); 164 } 165 GetNextTable(GateRef linkedTable)166 GateRef GetNextTable(GateRef linkedTable) 167 { 168 GateRef nextTableIndex = Int32(LinkedHashTableType::NEXT_TABLE_INDEX); 169 return GetValueFromTaggedArray(linkedTable, nextTableIndex); 170 } 171 SetNextTable(GateRef linkedTable,GateRef nexTable)172 void SetNextTable(GateRef linkedTable, GateRef nexTable) 173 { 174 GateRef nextTableIndex = Int32(LinkedHashTableType::NEXT_TABLE_INDEX); 175 SetValueToTaggedArray(VariableType::JS_POINTER(), glue_, linkedTable, nextTableIndex, nexTable); 176 } 177 CalNewTaggedArrayLength(GateRef numberOfElements)178 GateRef CalNewTaggedArrayLength(GateRef numberOfElements) 179 { 180 GateRef startIndex = Int32(LinkedHashTableType::ELEMENTS_START_INDEX); 181 GateRef entrySize = Int32(LinkedHashTableObject::ENTRY_SIZE); 182 GateRef nEntrySize = Int32Mul(numberOfElements, Int32Add(entrySize, Int32(1))); 183 GateRef length = Int32Add(startIndex, Int32Add(numberOfElements, nEntrySize)); 184 return length; 185 } 186 InsertNewEntry(GateRef linkedTable,GateRef bucket,GateRef entry)187 void InsertNewEntry(GateRef linkedTable, GateRef bucket, GateRef entry) 188 { 189 GateRef bucketIndex = BucketToIndex(bucket); 190 GateRef previousEntry = GetElement(linkedTable, bucketIndex); 191 SetNextEntry(linkedTable, entry, previousEntry); 192 SetElement(linkedTable, bucketIndex, IntToTaggedInt(entry)); 193 } 194 195 GateRef GetDeletedElementsAt(GateRef linkedTable, GateRef entry); 196 GateRef GrowCapacity(GateRef linkedTable, GateRef numberOfAddedElements); 197 GateRef HasSufficientCapacity(GateRef linkedTable, GateRef numOfAddElements); 198 void Rehash(GateRef linkedTable, GateRef newTable); 199 GateRef ComputeCapacity(GateRef atLeastSpaceFor); 200 void RemoveEntry(GateRef linkedTable, GateRef entry); 201 202 GateRef glue_; 203 }; 204 } // namespace panda::ecmascript::kungfu 205 #endif // ECMASCRIPT_COMPILER_BUILTINS_LINKED_HASHTABLE_STUB_BUILDER_H 206