• 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_CONTAINERS_STUB_BUILDER_H
17 #define ECMASCRIPT_COMPILER_BUILTINS_CONTAINERS_STUB_BUILDER_H
18 #include "ecmascript/compiler/builtins/containers_arraylist_stub_builder.h"
19 #include "ecmascript/compiler/builtins/containers_deque_stub_builder.h"
20 #include "ecmascript/compiler/builtins/containers_hashmap_stub_builder.h"
21 #include "ecmascript/compiler/builtins/containers_hashset_stub_builder.h"
22 #include "ecmascript/compiler/builtins/containers_lightweightmap_stub_builder.h"
23 #include "ecmascript/compiler/builtins/containers_lightweightset_stub_builder.h"
24 #include "ecmascript/compiler/builtins/containers_linkedlist_stub_builder.h"
25 #include "ecmascript/compiler/builtins/containers_list_stub_builder.h"
26 #include "ecmascript/compiler/builtins/containers_plainarray_stub_builder.h"
27 #include "ecmascript/compiler/builtins/containers_queue_stub_builder.h"
28 #include "ecmascript/compiler/builtins/containers_stack_stub_builder.h"
29 #include "ecmascript/compiler/builtins/containers_vector_stub_builder.h"
30 #include "ecmascript/compiler/builtins/builtins_stubs.h"
31 #include "ecmascript/js_api/js_api_vector.h"
32 
33 namespace panda::ecmascript::kungfu {
34 // enumerate container functions that use function call
35 enum class ContainersType : uint8_t {
36     VECTOR_FOREACH = 0,
37     VECTOR_REPLACEALLELEMENTS,
38     STACK_FOREACH,
39     PLAINARRAY_FOREACH,
40     QUEUE_FOREACH,
41     DEQUE_FOREACH,
42     LIGHTWEIGHTMAP_FOREACH,
43     LIGHTWEIGHTSET_FOREACH,
44     HASHMAP_FOREACH,
45     HASHSET_FOREACH,
46     LINKEDLIST_FOREACH,
47     LIST_FOREACH,
48     ARRAYLIST_FOREACH,
49     ARRAYLIST_REPLACEALLELEMENTS,
50 };
51 
52 class ContainersStubBuilder : public BuiltinsStubBuilder {
53 public:
ContainersStubBuilder(StubBuilder * parent)54     explicit ContainersStubBuilder(StubBuilder *parent)
55         : BuiltinsStubBuilder(parent) {}
56     ~ContainersStubBuilder() override = default;
57     NO_MOVE_SEMANTIC(ContainersStubBuilder);
58     NO_COPY_SEMANTIC(ContainersStubBuilder);
GenerateCircuit()59     void GenerateCircuit() override {}
60 
61     void ContainersCommonFuncCall(GateRef glue, GateRef thisValue, GateRef numArgs,
62         Variable* result, Label *exit, Label *slowPath, ContainersType type);
63 
64     void QueueCommonFuncCall(GateRef glue, GateRef thisValue, GateRef numArgs,
65         Variable* result, Label *exit, Label *slowPath, ContainersType type);
66 
67     void DequeCommonFuncCall(GateRef glue, GateRef thisValue, GateRef numArgs,
68         Variable* result, Label *exit, Label *slowPath, ContainersType type);
69 
70     void ContainersLightWeightCall(GateRef glue, GateRef thisValue, GateRef numArgs,
71         Variable* result, Label *exit, Label *slowPath, ContainersType type);
72 
73     void ContainersHashCall(GateRef glue, GateRef thisValue, GateRef numArgs,
74         Variable* result, Label *exit, Label *slowPath, ContainersType type);
75 
76     void ContainersLinkedListCall(GateRef glue, GateRef thisValue, GateRef numArgs,
77         Variable* result, Label *exit, Label *slowPath, ContainersType type);
78 
IsContainer(GateRef obj,ContainersType type)79     GateRef IsContainer(GateRef obj, ContainersType type)
80     {
81         switch (type) {
82             case ContainersType::VECTOR_FOREACH:
83             case ContainersType::VECTOR_REPLACEALLELEMENTS:
84                 return IsJSAPIVector(obj);
85             case ContainersType::STACK_FOREACH:
86                 return IsJSAPIStack(obj);
87             case ContainersType::PLAINARRAY_FOREACH:
88                 return IsJSAPIPlainArray(obj);
89             case ContainersType::QUEUE_FOREACH:
90                 return IsJSAPIQueue(obj);
91             case ContainersType::DEQUE_FOREACH:
92                 return IsJSAPIDeque(obj);
93             case ContainersType::LIGHTWEIGHTMAP_FOREACH:
94                 return IsJSAPILightWeightMap(obj);
95             case ContainersType::LIGHTWEIGHTSET_FOREACH:
96                 return IsJSAPILightWeightSet(obj);
97             case ContainersType::HASHMAP_FOREACH:
98                 return IsJSAPIHashMap(obj);
99             case ContainersType::HASHSET_FOREACH:
100                 return IsJSAPIHashSet(obj);
101             case ContainersType::LINKEDLIST_FOREACH:
102                 return IsJSAPILinkedList(obj);
103             case ContainersType::LIST_FOREACH:
104                 return IsJSAPIList(obj);
105             case ContainersType::ARRAYLIST_FOREACH:
106             case ContainersType::ARRAYLIST_REPLACEALLELEMENTS:
107                 return IsJSAPIArrayList(obj);
108             default:
109                 LOG_ECMA(FATAL) << "this branch is unreachable";
110                 UNREACHABLE();
111         }
112         return False();
113     }
114 
IsReplaceAllElements(ContainersType type)115     bool IsReplaceAllElements(ContainersType type)
116     {
117         switch (type) {
118             case ContainersType::STACK_FOREACH:
119             case ContainersType::VECTOR_FOREACH:
120             case ContainersType::PLAINARRAY_FOREACH:
121             case ContainersType::QUEUE_FOREACH:
122             case ContainersType::DEQUE_FOREACH:
123             case ContainersType::ARRAYLIST_FOREACH:
124                 return false;
125             case ContainersType::VECTOR_REPLACEALLELEMENTS:
126             case ContainersType::ARRAYLIST_REPLACEALLELEMENTS:
127                 return true;
128             default:
129                 LOG_ECMA(FATAL) << "this branch is unreachable";
130                 UNREACHABLE();
131         }
132         return false;
133     }
134 
IsPlainArray(ContainersType type)135     bool IsPlainArray(ContainersType type)
136     {
137         switch (type) {
138             case ContainersType::STACK_FOREACH:
139             case ContainersType::VECTOR_FOREACH:
140             case ContainersType::VECTOR_REPLACEALLELEMENTS:
141             case ContainersType::QUEUE_FOREACH:
142             case ContainersType::DEQUE_FOREACH:
143             case ContainersType::ARRAYLIST_FOREACH:
144             case ContainersType::ARRAYLIST_REPLACEALLELEMENTS:
145                 return false;
146             case ContainersType::PLAINARRAY_FOREACH:
147                 return true;
148             default:
149                 LOG_ECMA(FATAL) << "this branch is unreachable";
150                 UNREACHABLE();
151         }
152         return false;
153     }
154 
IsArrayListReplaceAllelements(ContainersType type)155     bool IsArrayListReplaceAllelements(ContainersType type)
156     {
157         switch (type) {
158             case ContainersType::STACK_FOREACH:
159             case ContainersType::VECTOR_FOREACH:
160             case ContainersType::VECTOR_REPLACEALLELEMENTS:
161             case ContainersType::QUEUE_FOREACH:
162             case ContainersType::DEQUE_FOREACH:
163             case ContainersType::ARRAYLIST_FOREACH:
164             case ContainersType::PLAINARRAY_FOREACH:
165                 return false;
166             case ContainersType::ARRAYLIST_REPLACEALLELEMENTS:
167                 return true;
168             default:
169                 LOG_ECMA(FATAL) << "this branch is unreachable";
170                 UNREACHABLE();
171         }
172         return false;
173     }
174 
ContainerSet(GateRef glue,GateRef obj,GateRef index,GateRef value,ContainersType type)175     void ContainerSet(GateRef glue, GateRef obj, GateRef index, GateRef value, ContainersType type)
176     {
177         switch (type) {
178             case ContainersType::VECTOR_REPLACEALLELEMENTS: {
179                 ContainersVectorStubBuilder vectorBuilder(this);
180                 vectorBuilder.Set(glue, obj, index, value);
181                 break;
182             }
183             case ContainersType::ARRAYLIST_REPLACEALLELEMENTS: {
184                 ContainersArrayListStubBuilder arrayListBuilder(this);
185                 arrayListBuilder.Set(glue, obj, index, value);
186                 break;
187             }
188             default:
189                 LOG_ECMA(FATAL) << "this branch is unreachable";
190                 UNREACHABLE();
191         }
192     }
193 
ContainerGetSize(GateRef obj,ContainersType type)194     GateRef ContainerGetSize(GateRef obj, ContainersType type)
195     {
196         switch (type) {
197             case ContainersType::VECTOR_FOREACH:
198             case ContainersType::VECTOR_REPLACEALLELEMENTS: {
199                 ContainersVectorStubBuilder vectorBuilder(this);
200                 return vectorBuilder.GetSize(obj);
201             }
202             case ContainersType::STACK_FOREACH: {
203                 ContainersStackStubBuilder stackBuilder(this);
204                 return stackBuilder.GetSize(obj);
205             }
206             case ContainersType::PLAINARRAY_FOREACH: {
207                 ContainersPlainArrayStubBuilder plainArrayBuilder(this);
208                 return plainArrayBuilder.GetSize(obj);
209             }
210             case ContainersType::QUEUE_FOREACH: {
211                 ContainersQueueStubBuilder queueBuilder(this);
212                 return queueBuilder.GetArrayLength(obj);
213             }
214             case ContainersType::DEQUE_FOREACH: {
215                 ContainersDequeStubBuilder dequeBuilder(this);
216                 return dequeBuilder.GetSize(obj);
217             }
218             case ContainersType::LIGHTWEIGHTMAP_FOREACH: {
219                 ContainersLightWeightMapStubBuilder lightWeightMapBuilder(this);
220                 return lightWeightMapBuilder.GetSize(obj);
221             }
222             case ContainersType::LIGHTWEIGHTSET_FOREACH: {
223                 ContainersLightWeightSetStubBuilder lightWeightSetBuilder(this);
224                 return lightWeightSetBuilder.GetSize(obj);
225             }
226             case ContainersType::HASHMAP_FOREACH: {
227                 ContainersHashMapStubBuilder hashMapBuilder(this);
228                 return hashMapBuilder.GetTableLength(obj);
229             }
230             case ContainersType::HASHSET_FOREACH: {
231                 ContainersHashSetStubBuilder hashSetBuilder(this);
232                 return hashSetBuilder.GetTableLength(obj);
233             }
234             case ContainersType::LINKEDLIST_FOREACH: {
235                 ContainersLinkedListStubBuilder linkedListBuilder(this);
236                 return linkedListBuilder.GetTableLength(obj);
237             }
238             case ContainersType::LIST_FOREACH: {
239                 ContainersListStubBuilder listBuilder(this);
240                 return listBuilder.GetTableLength(obj);
241             }
242             case ContainersType::ARRAYLIST_REPLACEALLELEMENTS:
243             case ContainersType::ARRAYLIST_FOREACH: {
244                 ContainersArrayListStubBuilder arrayListBuilder(this);
245                 return arrayListBuilder.GetSize(obj);
246             }
247             default:
248                 LOG_ECMA(FATAL) << "this branch is unreachable";
249                 UNREACHABLE();
250         }
251         return False();
252     }
253 
ContainerGetValue(GateRef obj,GateRef index,ContainersType type)254     GateRef ContainerGetValue(GateRef obj, GateRef index, ContainersType type)
255     {
256         switch (type) {
257             case ContainersType::VECTOR_FOREACH:
258             case ContainersType::VECTOR_REPLACEALLELEMENTS: {
259                 ContainersVectorStubBuilder vectorBuilder(this);
260                 return vectorBuilder.Get(obj, index);
261             }
262             case ContainersType::STACK_FOREACH: {
263                 ContainersStackStubBuilder stackBuilder(this);
264                 return stackBuilder.Get(obj, index);
265             }
266             case ContainersType::PLAINARRAY_FOREACH: {
267                 ContainersPlainArrayStubBuilder plainArrayBuilder(this);
268                 return plainArrayBuilder.Get(obj, index);
269             }
270             case ContainersType::QUEUE_FOREACH: {
271                 ContainersQueueStubBuilder queueBuilder(this);
272                 return queueBuilder.Get(obj, index);
273             }
274             case ContainersType::DEQUE_FOREACH: {
275                 ContainersDequeStubBuilder dequeBuilder(this);
276                 return dequeBuilder.Get(obj, index);
277             }
278             case ContainersType::LIGHTWEIGHTMAP_FOREACH: {
279                 ContainersLightWeightMapStubBuilder lightWeightMapBuilder(this);
280                 return lightWeightMapBuilder.GetValue(obj, index);
281             }
282             case ContainersType::LIGHTWEIGHTSET_FOREACH: {
283                 ContainersLightWeightSetStubBuilder lightWeightSetBuilder(this);
284                 return lightWeightSetBuilder.GetValue(obj, index);
285             }
286             case ContainersType::ARRAYLIST_REPLACEALLELEMENTS:
287             case ContainersType::ARRAYLIST_FOREACH: {
288                 ContainersArrayListStubBuilder arrayListBuilder(this);
289                 return arrayListBuilder.Get(obj, index);
290             }
291             default:
292                 LOG_ECMA(FATAL) << "this branch is unreachable";
293                 UNREACHABLE();
294         }
295         return False();
296     }
297 
ContainerGetKey(GateRef obj,GateRef index,ContainersType type)298     GateRef ContainerGetKey(GateRef obj, GateRef index, ContainersType type)
299     {
300         switch (type) {
301             case ContainersType::LIGHTWEIGHTMAP_FOREACH: {
302                 ContainersLightWeightMapStubBuilder lightWeightMapBuilder(this);
303                 return lightWeightMapBuilder.GetKey(obj, index);
304             }
305             case ContainersType::LIGHTWEIGHTSET_FOREACH: {
306                 ContainersLightWeightSetStubBuilder lightWeightSetBuilder(this);
307                 return lightWeightSetBuilder.GetKey(obj, index);
308             }
309             default:
310                 LOG_ECMA(FATAL) << "this branch is unreachable";
311                 UNREACHABLE();
312         }
313         return False();
314     }
315 
ContainerGetNode(GateRef obj,GateRef index,ContainersType type)316     GateRef ContainerGetNode(GateRef obj, GateRef index, ContainersType type)
317     {
318         switch (type) {
319             case ContainersType::HASHMAP_FOREACH: {
320                 ContainersHashMapStubBuilder hashMapBuilder(this);
321                 return hashMapBuilder.GetNode(obj, index);
322             }
323             case ContainersType::HASHSET_FOREACH: {
324                 ContainersHashSetStubBuilder hashSetBuilder(this);
325                 return hashSetBuilder.GetNode(obj, index);
326             }
327             case ContainersType::LINKEDLIST_FOREACH: {
328                 ContainersLinkedListStubBuilder linkedListBuilder(this);
329                 return linkedListBuilder.GetNode(obj, index);
330             }
331             case ContainersType::LIST_FOREACH: {
332                 ContainersListStubBuilder listBuilder(this);
333                 return listBuilder.GetNode(obj, index);
334             }
335             default:
336                 LOG_ECMA(FATAL) << "this branch is unreachable";
337                 UNREACHABLE();
338         }
339         return False();
340     }
341 
PlainArrayGetKey(GateRef obj,GateRef index)342     GateRef PlainArrayGetKey(GateRef obj, GateRef index)
343     {
344         ContainersPlainArrayStubBuilder plainArrayBuilder(this);
345         return plainArrayBuilder.GetKey(obj, index);
346     }
347 
QueueGetNextPosition(GateRef obj,GateRef index)348     GateRef QueueGetNextPosition(GateRef obj, GateRef index)
349     {
350         ContainersQueueStubBuilder queueBuilder(this);
351         return queueBuilder.GetNextPosition(obj, index);
352     }
353 
QueueGetCurrentFront(GateRef obj)354     GateRef QueueGetCurrentFront(GateRef obj)
355     {
356         ContainersQueueStubBuilder queueBuilder(this);
357         return queueBuilder.GetCurrentFront(obj);
358     }
359 };
360 }  // namespace panda::ecmascript::kungfu
361 #endif  // ECMASCRIPT_COMPILER_BUILTINS_CONTAINERS_STUB_BUILDER_H