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