/* * Copyright (c) 2025 Huawei Device Co., Ltd. * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #ifndef ECMASCRIPT_JS_API_JS_API_HASHARRAY_ITERATOR_H #define ECMASCRIPT_JS_API_JS_API_HASHARRAY_ITERATOR_H #include "ecmascript/js_api/js_api_hashmap_iterator.h" #include "ecmascript/js_api/js_api_hashset_iterator.h" #include "ecmascript/js_handle.h" #include "ecmascript/js_object.h" #include "ecmascript/js_tagged_value.h" #include "ecmascript/tagged_hash_array.h" namespace panda::ecmascript { class JSAPIHashArrayIterator { public: template static JSHandle GetRBTreeCurrentNode(JSThread *thread, JSHandle iter, JSMutableHandle &queue, JSHandle &tableArr) { JSTaggedValue rootValue; uint32_t index = iter->GetNextIndex(); if (queue->Empty(thread)) { rootValue = tableArr->Get(thread, index); ASSERT(rootValue.IsRBTreeNode()); } else { rootValue = queue->Pop(thread); } JSHandle root = JSHandle(thread, rootValue); if (!root->GetLeft(thread).IsHole()) { JSHandle left(thread, root->GetLeft(thread)); queue.Update(JSTaggedValue(TaggedQueue::Push(thread, queue, left))); } if (!root->GetRight(thread).IsHole()) { JSHandle right(thread, root->GetRight(thread)); queue.Update(JSTaggedValue(TaggedQueue::Push(thread, queue, right))); } // iter == RBTree.end(), move index to next position if (queue->Empty(thread)) { iter->SetNextIndex(++index); } iter->SetTaggedQueue(thread, queue.GetTaggedValue()); return JSHandle::Cast(root); } template static JSHandle GetCurrentNode(JSThread *thread, JSHandle iter, JSMutableHandle &queue, JSHandle &tableArr) { ASSERT((std::is_same_v) || (std::is_same_v)); uint32_t index = iter->GetNextIndex(); // judge type of tableArr[index](Hole, LinkList, RBTree) JSHandle root(thread, tableArr->Get(thread, index)); if (root->IsHole()) { JSHandle rootValue = JSHandle(thread, tableArr->Get(thread, index)); return rootValue; } // RBTree if (root->IsRBTreeNode()) { return GetRBTreeCurrentNode(thread, iter, queue, tableArr); } // LinkList JSHandle currentNodeValue(thread, iter->GetCurrentNodeResult(thread)); if (!currentNodeValue->IsLinkedNode()) { currentNodeValue = root; } JSHandle currentNode = JSHandle::Cast(currentNodeValue); JSTaggedValue next = currentNode->GetNext(thread); // iter == linklist.end(), move index to next position if (next.IsHole()) { iter->SetNextIndex(++index); } iter->SetCurrentNodeResult(thread, next); return currentNodeValue; } }; } // namespace panda::ecmascript #endif // ECMASCRIPT_JS_API_JS_API_HASHARRAY_ITERATOR_H