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