1 /* 2 * Copyright (c) 2024 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_COLLECTION_ITERATOR_STUB_BUILDER_H 17 #define ECMASCRIPT_COMPILER_BUILTINS_COLLECTION_ITERATOR_STUB_BUILDER_H 18 #include "ecmascript/compiler/builtins/linked_hashtable_stub_builder.h" 19 #include "ecmascript/compiler/builtins/builtins_stubs.h" 20 #include "ecmascript/js_map.h" 21 #include "ecmascript/js_map_iterator.h" 22 #include "ecmascript/js_set.h" 23 #include "ecmascript/js_set_iterator.h" 24 #include "ecmascript/linked_hash_table.h" 25 26 namespace panda::ecmascript::kungfu { 27 template <typename IteratorType> 28 class BuiltinsCollectionIteratorStubBuilder : public BuiltinsStubBuilder { 29 public: BuiltinsCollectionIteratorStubBuilder(StubBuilder * parent,GateRef glue,GateRef thisValue,GateRef numArgs,GateRef globalEnv)30 explicit BuiltinsCollectionIteratorStubBuilder(StubBuilder *parent, GateRef glue, GateRef thisValue, 31 GateRef numArgs, GateRef globalEnv) 32 : BuiltinsStubBuilder(parent, globalEnv), glue_(glue), thisValue_(thisValue), numArgs_(numArgs) {} 33 ~BuiltinsCollectionIteratorStubBuilder() override = default; 34 NO_MOVE_SEMANTIC(BuiltinsCollectionIteratorStubBuilder); 35 NO_COPY_SEMANTIC(BuiltinsCollectionIteratorStubBuilder); GenerateCircuit()36 void GenerateCircuit() override {} 37 38 void Next(Variable *result, Label *exit); 39 40 private: 41 GateRef CreateIterValueForEntry(GateRef key, GateRef value); 42 // check target obj 43 void CheckCollectionIteratorObj(Label *updateIter, Label *throwException); 44 void UpdateIter(Label *iterUpdated); 45 GetIteratedLinkedObjOffset()46 GateRef GetIteratedLinkedObjOffset() 47 { 48 int32_t linkedObjOffset = 0; 49 if constexpr (std::is_same_v<IteratorType, JSMapIterator>) { 50 linkedObjOffset = JSMapIterator::ITERATED_MAP_OFFSET; 51 } else { 52 linkedObjOffset = JSSetIterator::ITERATED_SET_OFFSET; 53 } 54 return IntPtr(linkedObjOffset); 55 } 56 GetIteratedLinkedObj()57 GateRef GetIteratedLinkedObj() 58 { 59 GateRef iteratedLinkedObjOffset = GetIteratedLinkedObjOffset(); 60 return Load(VariableType::JS_ANY(), glue_, thisValue_, iteratedLinkedObjOffset); 61 } 62 SetIteratedLinkedObj(GateRef newLinkedObj)63 void SetIteratedLinkedObj(GateRef newLinkedObj) 64 { 65 GateRef iteratedLinkedObjOffset = GetIteratedLinkedObjOffset(); 66 Store(VariableType::JS_ANY(), glue_, thisValue_, iteratedLinkedObjOffset, newLinkedObj); 67 } 68 GetNextIndexOffset()69 GateRef GetNextIndexOffset() 70 { 71 return IntPtr(IteratorType::NEXT_INDEX_OFFSET); 72 } 73 GetNextIndex()74 GateRef GetNextIndex() 75 { 76 GateRef nextIndexOffset = GetNextIndexOffset(); 77 return LoadPrimitive(VariableType::INT32(), thisValue_, nextIndexOffset); 78 } 79 SetNextIndex(GateRef newNextIndex)80 void SetNextIndex(GateRef newNextIndex) 81 { 82 GateRef nextIndexOffset = GetNextIndexOffset(); 83 Store(VariableType::INT32(), glue_, thisValue_, nextIndexOffset, newNextIndex); 84 } 85 GetIterationKind()86 GateRef GetIterationKind() 87 { 88 GateRef bitFieldOffset = IntPtr(IteratorType::BIT_FIELD_OFFSET); 89 GateRef bitField = LoadPrimitive(VariableType::INT32(), thisValue_, bitFieldOffset); 90 // decode 91 GateRef mask = Int32((1LLU << IteratorType::ITERATION_KIND_BITS) - 1); 92 return Int32And(bitField, mask); 93 } 94 GetNextTable(GateRef iteratedLinkedObj)95 GateRef GetNextTable(GateRef iteratedLinkedObj) 96 { 97 if constexpr (std::is_same_v<IteratorType, JSMapIterator>) { 98 LinkedHashTableStubBuilder<LinkedHashMap, LinkedHashMapObject> linkedHashTableStubBuilder(this, glue_, GetCurrentGlobalEnv()); 99 return linkedHashTableStubBuilder.GetNextTable(iteratedLinkedObj); 100 } else { 101 LinkedHashTableStubBuilder<LinkedHashSet, LinkedHashSetObject> linkedHashTableStubBuilder(this, glue_, GetCurrentGlobalEnv()); 102 return linkedHashTableStubBuilder.GetNextTable(iteratedLinkedObj); 103 } 104 } 105 106 GateRef glue_; 107 GateRef thisValue_; 108 GateRef numArgs_; 109 }; 110 } // namespace panda::ecmascript::kungfu 111 #endif // ECMASCRIPT_COMPILER_BUILTINS_COLLECTION_ITERATOR_STUB_BUILDER_H