• 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 
ContainerSet(GateRef glue,GateRef obj,GateRef index,GateRef value,ContainersType type)155     void ContainerSet(GateRef glue, GateRef obj, GateRef index, GateRef value, ContainersType type)
156     {
157         switch (type) {
158             case ContainersType::VECTOR_REPLACEALLELEMENTS: {
159                 ContainersVectorStubBuilder vectorBuilder(this);
160                 vectorBuilder.Set(glue, obj, index, value);
161                 break;
162             }
163             case ContainersType::ARRAYLIST_REPLACEALLELEMENTS: {
164                 ContainersArrayListStubBuilder arrayListBuilder(this);
165                 arrayListBuilder.Set(glue, obj, index, value);
166                 break;
167             }
168             default:
169                 LOG_ECMA(FATAL) << "this branch is unreachable";
170                 UNREACHABLE();
171         }
172     }
173 
ContainerGetSize(GateRef obj,ContainersType type)174     GateRef ContainerGetSize(GateRef obj, ContainersType type)
175     {
176         switch (type) {
177             case ContainersType::VECTOR_FOREACH:
178             case ContainersType::VECTOR_REPLACEALLELEMENTS: {
179                 ContainersVectorStubBuilder vectorBuilder(this);
180                 return vectorBuilder.GetSize(obj);
181             }
182             case ContainersType::STACK_FOREACH: {
183                 ContainersStackStubBuilder stackBuilder(this);
184                 return stackBuilder.GetSize(obj);
185             }
186             case ContainersType::PLAINARRAY_FOREACH: {
187                 ContainersPlainArrayStubBuilder plainArrayBuilder(this);
188                 return plainArrayBuilder.GetSize(obj);
189             }
190             case ContainersType::QUEUE_FOREACH: {
191                 ContainersQueueStubBuilder queueBuilder(this);
192                 return queueBuilder.GetArrayLength(obj);
193             }
194             case ContainersType::DEQUE_FOREACH: {
195                 ContainersDequeStubBuilder dequeBuilder(this);
196                 return dequeBuilder.GetSize(obj);
197             }
198             case ContainersType::LIGHTWEIGHTMAP_FOREACH: {
199                 ContainersLightWeightMapStubBuilder lightWeightMapBuilder(this);
200                 return lightWeightMapBuilder.GetSize(obj);
201             }
202             case ContainersType::LIGHTWEIGHTSET_FOREACH: {
203                 ContainersLightWeightSetStubBuilder lightWeightSetBuilder(this);
204                 return lightWeightSetBuilder.GetSize(obj);
205             }
206             case ContainersType::HASHMAP_FOREACH: {
207                 ContainersHashMapStubBuilder hashMapBuilder(this);
208                 return hashMapBuilder.GetTableLength(obj);
209             }
210             case ContainersType::HASHSET_FOREACH: {
211                 ContainersHashSetStubBuilder hashSetBuilder(this);
212                 return hashSetBuilder.GetTableLength(obj);
213             }
214             case ContainersType::LINKEDLIST_FOREACH: {
215                 ContainersLinkedListStubBuilder linkedListBuilder(this);
216                 return linkedListBuilder.GetTableLength(obj);
217             }
218             case ContainersType::LIST_FOREACH: {
219                 ContainersListStubBuilder listBuilder(this);
220                 return listBuilder.GetTableLength(obj);
221             }
222             case ContainersType::ARRAYLIST_REPLACEALLELEMENTS:
223             case ContainersType::ARRAYLIST_FOREACH: {
224                 ContainersArrayListStubBuilder arrayListBuilder(this);
225                 return arrayListBuilder.GetSize(obj);
226             }
227             default:
228                 LOG_ECMA(FATAL) << "this branch is unreachable";
229                 UNREACHABLE();
230         }
231         return False();
232     }
233 
ContainerGetValue(GateRef obj,GateRef index,ContainersType type)234     GateRef ContainerGetValue(GateRef obj, GateRef index, ContainersType type)
235     {
236         switch (type) {
237             case ContainersType::VECTOR_FOREACH:
238             case ContainersType::VECTOR_REPLACEALLELEMENTS: {
239                 ContainersVectorStubBuilder vectorBuilder(this);
240                 return vectorBuilder.Get(obj, index);
241             }
242             case ContainersType::STACK_FOREACH: {
243                 ContainersStackStubBuilder stackBuilder(this);
244                 return stackBuilder.Get(obj, index);
245             }
246             case ContainersType::PLAINARRAY_FOREACH: {
247                 ContainersPlainArrayStubBuilder plainArrayBuilder(this);
248                 return plainArrayBuilder.Get(obj, index);
249             }
250             case ContainersType::QUEUE_FOREACH: {
251                 ContainersQueueStubBuilder queueBuilder(this);
252                 return queueBuilder.Get(obj, index);
253             }
254             case ContainersType::DEQUE_FOREACH: {
255                 ContainersDequeStubBuilder dequeBuilder(this);
256                 return dequeBuilder.Get(obj, index);
257             }
258             case ContainersType::LIGHTWEIGHTMAP_FOREACH: {
259                 ContainersLightWeightMapStubBuilder lightWeightMapBuilder(this);
260                 return lightWeightMapBuilder.GetValue(obj, index);
261             }
262             case ContainersType::LIGHTWEIGHTSET_FOREACH: {
263                 ContainersLightWeightSetStubBuilder lightWeightSetBuilder(this);
264                 return lightWeightSetBuilder.GetValue(obj, index);
265             }
266             case ContainersType::ARRAYLIST_REPLACEALLELEMENTS:
267             case ContainersType::ARRAYLIST_FOREACH: {
268                 ContainersArrayListStubBuilder arrayListBuilder(this);
269                 return arrayListBuilder.Get(obj, index);
270             }
271             default:
272                 LOG_ECMA(FATAL) << "this branch is unreachable";
273                 UNREACHABLE();
274         }
275         return False();
276     }
277 
ContainerGetKey(GateRef obj,GateRef index,ContainersType type)278     GateRef ContainerGetKey(GateRef obj, GateRef index, ContainersType type)
279     {
280         switch (type) {
281             case ContainersType::LIGHTWEIGHTMAP_FOREACH: {
282                 ContainersLightWeightMapStubBuilder lightWeightMapBuilder(this);
283                 return lightWeightMapBuilder.GetKey(obj, index);
284             }
285             case ContainersType::LIGHTWEIGHTSET_FOREACH: {
286                 ContainersLightWeightSetStubBuilder lightWeightSetBuilder(this);
287                 return lightWeightSetBuilder.GetKey(obj, index);
288             }
289             default:
290                 LOG_ECMA(FATAL) << "this branch is unreachable";
291                 UNREACHABLE();
292         }
293         return False();
294     }
295 
ContainerGetNode(GateRef obj,GateRef index,ContainersType type)296     GateRef ContainerGetNode(GateRef obj, GateRef index, ContainersType type)
297     {
298         switch (type) {
299             case ContainersType::HASHMAP_FOREACH: {
300                 ContainersHashMapStubBuilder hashMapBuilder(this);
301                 return hashMapBuilder.GetNode(obj, index);
302             }
303             case ContainersType::HASHSET_FOREACH: {
304                 ContainersHashSetStubBuilder hashSetBuilder(this);
305                 return hashSetBuilder.GetNode(obj, index);
306             }
307             case ContainersType::LINKEDLIST_FOREACH: {
308                 ContainersLinkedListStubBuilder linkedListBuilder(this);
309                 return linkedListBuilder.GetNode(obj, index);
310             }
311             case ContainersType::LIST_FOREACH: {
312                 ContainersListStubBuilder listBuilder(this);
313                 return listBuilder.GetNode(obj, index);
314             }
315             default:
316                 LOG_ECMA(FATAL) << "this branch is unreachable";
317                 UNREACHABLE();
318         }
319         return False();
320     }
321 
PlainArrayGetKey(GateRef obj,GateRef index)322     GateRef PlainArrayGetKey(GateRef obj, GateRef index)
323     {
324         ContainersPlainArrayStubBuilder plainArrayBuilder(this);
325         return plainArrayBuilder.GetKey(obj, index);
326     }
327 
QueueGetNextPosition(GateRef obj,GateRef index)328     GateRef QueueGetNextPosition(GateRef obj, GateRef index)
329     {
330         ContainersQueueStubBuilder queueBuilder(this);
331         return queueBuilder.GetNextPosition(obj, index);
332     }
333 
QueueGetCurrentFront(GateRef obj)334     GateRef QueueGetCurrentFront(GateRef obj)
335     {
336         ContainersQueueStubBuilder queueBuilder(this);
337         return queueBuilder.GetCurrentFront(obj);
338     }
339 };
340 }  // namespace panda::ecmascript::kungfu
341 #endif  // ECMASCRIPT_COMPILER_BUILTINS_CONTAINERS_STUB_BUILDER_H