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