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#ifndef ECMA_CONTAINER_COMMON_H
16#define ECMA_CONTAINER_COMMON_H
17#include "ecmascript/containers/containers_private.h"
18#include "ecmascript/ecma_string-inl.h"
19#include "ecmascript/global_env.h"
20#include "ecmascript/js_api/js_api_arraylist.h"
21#include "ecmascript/js_api/js_api_arraylist_iterator.h"
22#include "ecmascript/js_api/js_api_deque.h"
23#include "ecmascript/js_api/js_api_deque_iterator.h"
24#include "ecmascript/js_api/js_api_hashmap.h"
25#include "ecmascript/js_api/js_api_hashmap_iterator.h"
26#include "ecmascript/js_api/js_api_hashset.h"
27#include "ecmascript/js_api/js_api_hashset_iterator.h"
28#include "ecmascript/js_api/js_api_lightweightmap.h"
29#include "ecmascript/js_api/js_api_lightweightmap_iterator.h"
30#include "ecmascript/js_api/js_api_lightweightset.h"
31#include "ecmascript/js_api/js_api_lightweightset_iterator.h"
32#include "ecmascript/js_api/js_api_linked_list.h"
33#include "ecmascript/js_api/js_api_linked_list_iterator.h"
34#include "ecmascript/js_api/js_api_list.h"
35#include "ecmascript/js_api/js_api_list_iterator.h"
36#include "ecmascript/js_api/js_api_plain_array.h"
37#include "ecmascript/js_api/js_api_plain_array_iterator.h"
38#include "ecmascript/js_api/js_api_queue.h"
39#include "ecmascript/js_api/js_api_queue_iterator.h"
40#include "ecmascript/js_api/js_api_stack.h"
41#include "ecmascript/js_api/js_api_tree_map.h"
42#include "ecmascript/js_date_time_format.h"
43#include "ecmascript/js_tagged_value.h"
44#include "ecmascript/object_factory.h"
45#include "ecmascript/tagged_tree.h"
46#include "ecmascript/tests/test_common.h"
47
48namespace panda::test {
49
50using namespace panda;
51using namespace panda::ecmascript;
52using ecmascript::base::BuiltinsBase;
53
54constexpr uint32_t g_defaultSize = 8;
55
56class EcmaContainerCommon {
57public:
58    static JSObject *JSObjectTestCreate(JSThread *thread)
59    {
60        [[maybe_unused]] ecmascript::EcmaHandleScope scope(thread);
61        EcmaVM *ecmaVM = thread->GetEcmaVM();
62        auto globalEnv = ecmaVM->GetGlobalEnv();
63        JSHandle<JSTaggedValue> jsFunc = globalEnv->GetObjectFunction();
64        JSHandle<JSObject> newObj =
65            ecmaVM->GetFactory()->NewJSObjectByConstructor(JSHandle<JSFunction>(jsFunc), jsFunc);
66        return *newObj;
67    }
68
69    static JSAPIArrayList *CreateArrayList(JSThread *thread)
70    {
71        ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
72        auto result = TestCommon::CreateContainerTaggedValue(thread, containers::ContainerTag::ArrayList);
73        JSHandle<JSTaggedValue> constructor(thread, result);
74        JSHandle<JSAPIArrayList> arrayList(
75            factory->NewJSObjectByConstructor(JSHandle<JSFunction>(constructor), constructor));
76        JSHandle<TaggedArray> taggedArray = factory->NewTaggedArray(JSAPIArrayList::DEFAULT_CAPACITY_LENGTH);
77        arrayList->SetElements(thread, taggedArray);
78        return *arrayList;
79    }
80
81    static JSAPIPlainArray *CreatePlainArray(JSThread *thread)
82    {
83        ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
84        auto result = TestCommon::CreateContainerTaggedValue(thread, containers::ContainerTag::PlainArray);
85        JSHandle<JSTaggedValue> constructor(thread, result);
86        JSHandle<JSAPIPlainArray> plainArray(
87            factory->NewJSObjectByConstructor(JSHandle<JSFunction>(constructor), constructor));
88        JSHandle<JSTaggedValue> keyArray = JSHandle<JSTaggedValue>(factory->NewTaggedArray(g_defaultSize));
89        JSHandle<JSTaggedValue> valueArray = JSHandle<JSTaggedValue>(factory->NewTaggedArray(g_defaultSize));
90        plainArray->SetKeys(thread, keyArray);
91        plainArray->SetValues(thread, valueArray);
92        return *plainArray;
93    }
94
95    static JSAPIDeque *CreateJSApiDeque(JSThread *thread)
96    {
97        ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
98        auto result = TestCommon::CreateContainerTaggedValue(thread, containers::ContainerTag::Deque);
99        JSHandle<JSTaggedValue> constructor(thread, result);
100        JSHandle<JSAPIDeque> deque(factory->NewJSObjectByConstructor(JSHandle<JSFunction>(constructor), constructor));
101        JSHandle<TaggedArray> newElements = factory->NewTaggedArray(JSAPIDeque::DEFAULT_CAPACITY_LENGTH);
102        deque->SetElements(thread, newElements);
103        return *deque;
104    }
105
106    static JSAPIHashMap *CreateHashMap(JSThread *thread)
107    {
108        ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
109        auto result = TestCommon::CreateContainerTaggedValue(thread, containers::ContainerTag::HashMap);
110        JSHandle<JSTaggedValue> constructor(thread, result);
111        JSHandle<JSAPIHashMap> map(factory->NewJSObjectByConstructor(JSHandle<JSFunction>(constructor), constructor));
112        JSTaggedValue hashMapArray = TaggedHashArray::Create(thread);
113        map->SetTable(thread, hashMapArray);
114        map->SetSize(0);
115        return *map;
116    }
117
118    static JSAPIHashSet *CreateHashSet(JSThread *thread)
119    {
120        ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
121        auto result = TestCommon::CreateContainerTaggedValue(thread, containers::ContainerTag::HashSet);
122        JSHandle<JSTaggedValue> constructor(thread, result);
123        JSHandle<JSAPIHashSet> set(factory->NewJSObjectByConstructor(JSHandle<JSFunction>(constructor), constructor));
124        JSTaggedValue hashSetArray = TaggedHashArray::Create(thread);
125        set->SetTable(thread, hashSetArray);
126        set->SetSize(0);
127        return *set;
128    }
129
130    static JSAPILightWeightMap *CreateLightWeightMap(JSThread *thread)
131    {
132        ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
133        auto result = TestCommon::CreateContainerTaggedValue(thread, containers::ContainerTag::LightWeightMap);
134        JSHandle<JSTaggedValue> constructor(thread, result);
135        JSHandle<JSAPILightWeightMap> lightWeightMap = JSHandle<JSAPILightWeightMap>::Cast(
136            factory->NewJSObjectByConstructor(JSHandle<JSFunction>(constructor), constructor));
137        JSHandle<JSTaggedValue> hashArray = JSHandle<JSTaggedValue>(factory->NewTaggedArray(g_defaultSize));
138        JSHandle<JSTaggedValue> keyArray = JSHandle<JSTaggedValue>(factory->NewTaggedArray(g_defaultSize));
139        JSHandle<JSTaggedValue> valueArray = JSHandle<JSTaggedValue>(factory->NewTaggedArray(g_defaultSize));
140        lightWeightMap->SetHashes(thread, hashArray);
141        lightWeightMap->SetKeys(thread, keyArray);
142        lightWeightMap->SetValues(thread, valueArray);
143        lightWeightMap->SetLength(0);
144        return *lightWeightMap;
145    }
146
147    static JSAPILightWeightSet *CreateLightWeightSet(JSThread *thread)
148    {
149        ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
150        auto result = TestCommon::CreateContainerTaggedValue(thread, containers::ContainerTag::LightWeightSet);
151        JSHandle<JSTaggedValue> constructor(thread, result);
152        JSHandle<JSAPILightWeightSet> lightweightSet = JSHandle<JSAPILightWeightSet>::Cast(
153            factory->NewJSObjectByConstructor(JSHandle<JSFunction>(constructor), constructor));
154        JSHandle<JSTaggedValue> hashArray = JSHandle<JSTaggedValue>(factory->NewTaggedArray(g_defaultSize));
155        JSHandle<JSTaggedValue> valueArray = JSHandle<JSTaggedValue>(factory->NewTaggedArray(g_defaultSize));
156        lightweightSet->SetHashes(thread, hashArray);
157        lightweightSet->SetValues(thread, valueArray);
158        lightweightSet->SetLength(0);  // 0 means the value
159        return *lightweightSet;
160    }
161
162    static JSAPILinkedList *CreateLinkedList(JSThread *thread)
163    {
164        ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
165        auto result = TestCommon::CreateContainerTaggedValue(thread, containers::ContainerTag::LinkedList);
166
167        JSHandle<JSTaggedValue> contianer(thread, result);
168        JSHandle<JSAPILinkedList> linkedList = JSHandle<JSAPILinkedList>::Cast(
169            factory->NewJSObjectByConstructor(JSHandle<JSFunction>(contianer), contianer));
170        JSTaggedValue doubleList = TaggedDoubleList::Create(thread);
171        linkedList->SetDoubleList(thread, doubleList);
172        return *linkedList;
173    }
174
175    static JSAPIList *CreateList(JSThread *thread)
176    {
177        ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
178        auto result = TestCommon::CreateContainerTaggedValue(thread, containers::ContainerTag::List);
179        JSHandle<JSTaggedValue> constructor(thread, result);
180        JSHandle<JSAPIList> list(factory->NewJSObjectByConstructor(JSHandle<JSFunction>(constructor), constructor));
181        JSTaggedValue singleList = TaggedSingleList::Create(thread);
182        list->SetSingleList(thread, singleList);
183        return *list;
184    }
185
186    static JSHandle<JSAPIQueue> CreateQueue(JSThread *thread, int capacaty)
187    {
188        ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
189        auto result = TestCommon::CreateContainerTaggedValue(thread, containers::ContainerTag::Queue);
190        JSHandle<JSTaggedValue> constructor(thread, result);
191        JSHandle<JSAPIQueue> jsQueue(factory->NewJSObjectByConstructor(JSHandle<JSFunction>(constructor), constructor));
192        JSHandle<TaggedArray> newElements = factory->NewTaggedArray(capacaty);
193        jsQueue->SetElements(thread, newElements);
194        jsQueue->SetLength(thread, JSTaggedValue(0));
195        jsQueue->SetFront(0);
196        jsQueue->SetTail(0);
197        return jsQueue;
198    }
199
200    static JSHandle<JSAPIStack> CreateJSApiStack(JSThread *thread)
201    {
202        ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
203        auto result = TestCommon::CreateContainerTaggedValue(thread, containers::ContainerTag::Stack);
204
205        JSHandle<JSTaggedValue> constructor(thread, result);
206        JSHandle<JSAPIStack> jsStack(factory->NewJSObjectByConstructor(JSHandle<JSFunction>(constructor), constructor));
207        jsStack->SetTop(-1);
208        return jsStack;
209    }
210
211    static JSHandle<JSAPITreeMap> CreateTreeMap(JSThread *thread)
212    {
213        ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
214        auto result = TestCommon::CreateContainerTaggedValue(thread, containers::ContainerTag::TreeMap);
215
216        JSHandle<JSTaggedValue> constructor(thread, result);
217        JSHandle<JSAPITreeMap> jsTreeMap(
218            factory->NewJSObjectByConstructor(JSHandle<JSFunction>(constructor), constructor));
219        JSTaggedValue internal = TaggedTreeMap::Create(thread);
220        jsTreeMap->SetTreeMap(thread, internal);
221        return jsTreeMap;
222    }
223};
224};
225#endif
226