• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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