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