• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2025 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_JS_API_JS_API_HASHARRAY_ITERATOR_H
17 #define ECMASCRIPT_JS_API_JS_API_HASHARRAY_ITERATOR_H
18 
19 #include "ecmascript/js_api/js_api_hashmap_iterator.h"
20 #include "ecmascript/js_api/js_api_hashset_iterator.h"
21 
22 #include "ecmascript/js_handle.h"
23 #include "ecmascript/js_object.h"
24 #include "ecmascript/js_tagged_value.h"
25 #include "ecmascript/tagged_hash_array.h"
26 
27 namespace panda::ecmascript {
28 class JSAPIHashArrayIterator {
29 public:
30     template <typename T>
GetRBTreeCurrentNode(JSThread * thread,JSHandle<T> iter,JSMutableHandle<TaggedQueue> & queue,JSHandle<TaggedHashArray> & tableArr)31     static JSHandle<JSTaggedValue> GetRBTreeCurrentNode(JSThread *thread, JSHandle<T> iter,
32                                                         JSMutableHandle<TaggedQueue> &queue,
33                                                         JSHandle<TaggedHashArray> &tableArr)
34     {
35         JSTaggedValue rootValue;
36         uint32_t index = iter->GetNextIndex();
37         if (queue->Empty(thread)) {
38             rootValue = tableArr->Get(thread, index);
39             ASSERT(rootValue.IsRBTreeNode());
40         } else {
41             rootValue = queue->Pop(thread);
42         }
43         JSHandle<RBTreeNode> root = JSHandle<RBTreeNode>(thread, rootValue);
44         if (!root->GetLeft(thread).IsHole()) {
45             JSHandle<JSTaggedValue> left(thread, root->GetLeft(thread));
46             queue.Update(JSTaggedValue(TaggedQueue::Push(thread, queue, left)));
47         }
48         if (!root->GetRight(thread).IsHole()) {
49             JSHandle<JSTaggedValue> right(thread, root->GetRight(thread));
50             queue.Update(JSTaggedValue(TaggedQueue::Push(thread, queue, right)));
51         }
52         // iter == RBTree.end(), move index to next position
53         if (queue->Empty(thread)) {
54             iter->SetNextIndex(++index);
55         }
56         iter->SetTaggedQueue(thread, queue.GetTaggedValue());
57         return JSHandle<JSTaggedValue>::Cast(root);
58     }
59 
60     template <typename T>
GetCurrentNode(JSThread * thread,JSHandle<T> iter,JSMutableHandle<TaggedQueue> & queue,JSHandle<TaggedHashArray> & tableArr)61     static JSHandle<JSTaggedValue> GetCurrentNode(JSThread *thread, JSHandle<T> iter,
62                                                   JSMutableHandle<TaggedQueue> &queue,
63                                                   JSHandle<TaggedHashArray> &tableArr)
64     {
65         ASSERT((std::is_same_v<T, JSAPIHashMapIterator>) || (std::is_same_v<T, JSAPIHashSetIterator>));
66         uint32_t index = iter->GetNextIndex();
67         // judge type of tableArr[index](Hole, LinkList, RBTree)
68         JSHandle<JSTaggedValue> root(thread, tableArr->Get(thread, index));
69         if (root->IsHole()) {
70             JSHandle<JSTaggedValue> rootValue = JSHandle<JSTaggedValue>(thread, tableArr->Get(thread, index));
71             return rootValue;
72         }
73         // RBTree
74         if (root->IsRBTreeNode()) {
75             return GetRBTreeCurrentNode<T>(thread, iter, queue, tableArr);
76         }
77         // LinkList
78         JSHandle<JSTaggedValue> currentNodeValue(thread, iter->GetCurrentNodeResult(thread));
79         if (!currentNodeValue->IsLinkedNode()) {
80             currentNodeValue = root;
81         }
82         JSHandle<LinkedNode> currentNode = JSHandle<LinkedNode>::Cast(currentNodeValue);
83         JSTaggedValue next = currentNode->GetNext(thread);
84         // iter == linklist.end(), move index to next position
85         if (next.IsHole()) {
86             iter->SetNextIndex(++index);
87         }
88         iter->SetCurrentNodeResult(thread, next);
89         return currentNodeValue;
90     }
91 };
92 }  // namespace panda::ecmascript
93 #endif  // ECMASCRIPT_JS_API_JS_API_HASHARRAY_ITERATOR_H