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 #include "ecmascript/containers/containers_private.h"
17 
18 #include "containers_arraylist.h"
19 #include "containers_bitvector.h"
20 #include "containers_deque.h"
21 #include "containers_hashmap.h"
22 #include "containers_hashset.h"
23 #include "containers_lightweightmap.h"
24 #include "containers_lightweightset.h"
25 #include "containers_linked_list.h"
26 #include "containers_list.h"
27 #include "containers_plainarray.h"
28 #include "containers_queue.h"
29 #include "containers_stack.h"
30 #include "containers_treemap.h"
31 #include "containers_treeset.h"
32 #include "containers_vector.h"
33 #include "ecmascript/js_api/js_api_arraylist_iterator.h"
34 #include "ecmascript/js_api/js_api_bitvector_iterator.h"
35 #include "ecmascript/js_api/js_api_deque_iterator.h"
36 #include "ecmascript/js_api/js_api_hashmap_iterator.h"
37 #include "ecmascript/js_api/js_api_hashset_iterator.h"
38 #include "ecmascript/js_api/js_api_hashset.h"
39 #include "ecmascript/js_api/js_api_lightweightmap_iterator.h"
40 #include "ecmascript/js_api/js_api_lightweightmap.h"
41 #include "ecmascript/js_api/js_api_lightweightset_iterator.h"
42 #include "ecmascript/js_api/js_api_lightweightset.h"
43 #include "ecmascript/js_api/js_api_linked_list_iterator.h"
44 #include "ecmascript/js_api/js_api_list_iterator.h"
45 #include "ecmascript/js_api/js_api_plain_array_iterator.h"
46 #include "ecmascript/js_api/js_api_queue_iterator.h"
47 #include "ecmascript/js_api/js_api_stack_iterator.h"
48 #include "ecmascript/js_api/js_api_tree_map_iterator.h"
49 #include "ecmascript/js_api/js_api_tree_map.h"
50 #include "ecmascript/js_api/js_api_tree_set_iterator.h"
51 #include "ecmascript/js_api/js_api_tree_set.h"
52 #include "ecmascript/js_api/js_api_vector_iterator.h"
53 #include "ecmascript/object_fast_operator-inl.h"
54 
55 namespace panda::ecmascript::containers {
Load(EcmaRuntimeCallInfo *msg)56 JSTaggedValue ContainersPrivate::Load(EcmaRuntimeCallInfo *msg)
57 {
58     ASSERT(msg != nullptr);
59     JSThread *thread = msg->GetThread();
60     [[maybe_unused]] EcmaHandleScope handleScope(thread);
61     JSHandle<JSTaggedValue> argv = GetCallArg(msg, 0);
62     JSHandle<JSObject> thisValue(GetThis(msg));
63 
64     uint32_t tag = 0;
65     if (!JSTaggedValue::ToElementIndex(argv.GetTaggedValue(), &tag) || tag >= ContainerTag::END) {
66         THROW_TYPE_ERROR_AND_RETURN(thread, "Incorrect input parameters", JSTaggedValue::Exception());
67     }
68 
69     // Lazy set an undefinedIteratorResult to global constants
70     auto globalConst = const_cast<GlobalEnvConstants *>(thread->GlobalConstants());
71     JSHandle<JSTaggedValue> undefinedHandle = globalConst->GetHandledUndefined();
72     JSHandle<JSObject> undefinedIteratorResult = JSIterator::CreateIterResultObject(thread, undefinedHandle, true);
73     globalConst->SetConstant(ConstantIndex::UNDEFINED_INTERATOR_RESULT_INDEX, undefinedIteratorResult.GetTaggedValue());
74 
75     JSTaggedValue res = JSTaggedValue::Undefined();
76     switch (tag) {
77         case ContainerTag::ArrayList: {
78             res = InitializeContainer(thread, thisValue, InitializeArrayList, "ArrayListConstructor");
79             break;
80         }
81         case ContainerTag::Deque: {
82             res = InitializeContainer(thread, thisValue, InitializeDeque, "DequeConstructor");
83             break;
84         }
85         case ContainerTag::LightWeightMap: {
86             res = InitializeContainer(thread, thisValue, InitializeLightWeightMap, "LightWeightMapConstructor");
87             break;
88         }
89         case ContainerTag::LightWeightSet: {
90             res = InitializeContainer(thread, thisValue, InitializeLightWeightSet, "LightWeightSetConstructor");
91             break;
92         }
93         case ContainerTag::PlainArray: {
94             res = InitializeContainer(thread, thisValue, InitializePlainArray, "PlainArrayConstructor");
95             break;
96         }
97         case ContainerTag::Queue: {
98             res = InitializeContainer(thread, thisValue, InitializeQueue, "QueueConstructor");
99             break;
100         }
101         case ContainerTag::Stack: {
102             res = InitializeContainer(thread, thisValue, InitializeStack, "StackConstructor");
103             break;
104         }
105         case ContainerTag::TreeMap: {
106             res = InitializeContainer(thread, thisValue, InitializeTreeMap, "TreeMapConstructor");
107             break;
108         }
109         case ContainerTag::TreeSet: {
110             res = InitializeContainer(thread, thisValue, InitializeTreeSet, "TreeSetConstructor");
111             break;
112         }
113         case ContainerTag::Vector: {
114             res = InitializeContainer(thread, thisValue, InitializeVector, "VectorConstructor");
115             break;
116         }
117         case ContainerTag::BitVector: {
118             res = InitializeContainer(thread, thisValue, InitializeBitVector, "BitVectorConstructor");
119             break;
120         }
121         case ContainerTag::List: {
122             res = InitializeContainer(thread, thisValue, InitializeList, "ListConstructor");
123             break;
124         }
125         case ContainerTag::LinkedList: {
126             res = InitializeContainer(thread, thisValue, InitializeLinkedList, "LinkedListConstructor");
127             break;
128         }
129         case ContainerTag::HashMap: {
130             res = InitializeContainer(thread, thisValue, InitializeHashMap, "HashMapConstructor");
131             break;
132         }
133         case ContainerTag::HashSet: {
134             res = InitializeContainer(thread, thisValue, InitializeHashSet, "HashSetConstructor");
135             break;
136         }
137         case ContainerTag::END:
138             break;
139         default:
140             LOG_ECMA(FATAL) << "this branch is unreachable";
141             UNREACHABLE();
142     }
143 
144     return res;
145 }
146 
InitializeContainer(JSThread *thread, const JSHandle<JSObject> &obj, InitializeFunction func, const char *name)147 JSTaggedValue ContainersPrivate::InitializeContainer(JSThread *thread, const JSHandle<JSObject> &obj,
148                                                      InitializeFunction func, const char *name)
149 {
150     ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
151     JSHandle<JSTaggedValue> key(factory->NewFromASCII(name));
152     JSTaggedValue value = ObjectFastOperator::GetPropertyByName<ObjectFastOperator::Status::UseOwn>
153         (thread, obj.GetTaggedValue(), key.GetTaggedValue());
154     if (!value.IsUndefined()) {
155         return value;
156     }
157     JSHandle<JSTaggedValue> map = func(thread);
158     SetFrozenConstructor(thread, obj, name, map);
159     return map.GetTaggedValue();
160 }
161 
NewContainerConstructor(JSThread *thread, const JSHandle<JSObject> &prototype, EcmaEntrypoint ctorFunc, const char *name, int length)162 JSHandle<JSFunction> ContainersPrivate::NewContainerConstructor(JSThread *thread, const JSHandle<JSObject> &prototype,
163                                                                 EcmaEntrypoint ctorFunc, const char *name, int length)
164 {
165     JSHandle<GlobalEnv> env = thread->GetEcmaVM()->GetGlobalEnv();
166     ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
167     JSHandle<JSFunction> ctor =
168         factory->NewJSFunction(env, reinterpret_cast<void *>(ctorFunc), FunctionKind::BUILTIN_CONSTRUCTOR);
169 
170     const GlobalEnvConstants *globalConst = thread->GlobalConstants();
171     JSFunction::SetFunctionLength(thread, ctor, JSTaggedValue(length));
172     JSHandle<JSTaggedValue> nameString(factory->NewFromASCII(name));
173     JSFunction::SetFunctionName(thread, JSHandle<JSFunctionBase>(ctor), nameString,
174                                 globalConst->GetHandledUndefined());
175     JSHandle<JSTaggedValue> constructorKey = globalConst->GetHandledConstructorString();
176     PropertyDescriptor descriptor1(thread, JSHandle<JSTaggedValue>::Cast(ctor), true, false, true);
177     JSObject::DefineOwnProperty(thread, prototype, constructorKey, descriptor1);
178 
179     /* set "prototype" in constructor */
180     JSFunction::SetFunctionPrototypeOrInstanceHClass(thread, ctor, prototype.GetTaggedValue());
181 
182     return ctor;
183 }
184 
SetFrozenFunction(JSThread *thread, const JSHandle<JSObject> &obj, const char *key, EcmaEntrypoint func, int length, kungfu::BuiltinsStubCSigns::ID builtinId)185 void ContainersPrivate::SetFrozenFunction(JSThread *thread, const JSHandle<JSObject> &obj, const char *key,
186                                           EcmaEntrypoint func, int length, kungfu::BuiltinsStubCSigns::ID builtinId)
187 {
188     ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
189     JSHandle<JSTaggedValue> keyString(factory->NewFromASCII(key));
190     JSHandle<JSFunction> function = NewFunction(thread, keyString, func, length, builtinId);
191     PropertyDescriptor descriptor(thread, JSHandle<JSTaggedValue>(function), false, false, false);
192     JSObject::DefineOwnProperty(thread, obj, keyString, descriptor);
193 }
194 
SetFrozenConstructor(JSThread *thread, const JSHandle<JSObject> &obj, const char *keyChar, JSHandle<JSTaggedValue> &value)195 void ContainersPrivate::SetFrozenConstructor(JSThread *thread, const JSHandle<JSObject> &obj, const char *keyChar,
196                                              JSHandle<JSTaggedValue> &value)
197 {
198     JSObject::PreventExtensions(thread, JSHandle<JSObject>::Cast(value));
199     ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
200     JSHandle<JSTaggedValue> key(factory->NewFromASCII(keyChar));
201     PropertyDescriptor descriptor(thread, value, false, false, false);
202     JSObject::DefineOwnProperty(thread, obj, key, descriptor);
203 }
204 
NewFunction(JSThread *thread, const JSHandle<JSTaggedValue> &key, EcmaEntrypoint func, int length, kungfu::BuiltinsStubCSigns::ID builtinId)205 JSHandle<JSFunction> ContainersPrivate::NewFunction(JSThread *thread, const JSHandle<JSTaggedValue> &key,
206                                                     EcmaEntrypoint func, int length,
207                                                     kungfu::BuiltinsStubCSigns::ID builtinId)
208 {
209     ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
210     JSHandle<JSFunction> function =
211         factory->NewJSFunction(thread->GetEcmaVM()->GetGlobalEnv(), reinterpret_cast<void *>(func),
212                                FunctionKind::NORMAL_FUNCTION, builtinId);
213     JSFunction::SetFunctionLength(thread, function, JSTaggedValue(length));
214     JSHandle<JSFunctionBase> baseFunction(function);
215     JSFunction::SetFunctionName(thread, baseFunction, key, thread->GlobalConstants()->GetHandledUndefined());
216     return function;
217 }
218 
CreateGetter(JSThread *thread, EcmaEntrypoint func, const char *name, int length)219 JSHandle<JSTaggedValue> ContainersPrivate::CreateGetter(JSThread *thread, EcmaEntrypoint func, const char *name,
220                                                         int length)
221 {
222     JSHandle<GlobalEnv> env = thread->GetEcmaVM()->GetGlobalEnv();
223     ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
224     JSHandle<JSFunction> function = factory->NewJSFunction(env, reinterpret_cast<void *>(func));
225     JSFunction::SetFunctionLength(thread, function, JSTaggedValue(length));
226     JSHandle<JSTaggedValue> funcName(factory->NewFromASCII(name));
227     JSHandle<JSTaggedValue> prefix = thread->GlobalConstants()->GetHandledGetString();
228     JSFunction::SetFunctionName(thread, JSHandle<JSFunctionBase>(function), funcName, prefix);
229     return JSHandle<JSTaggedValue>(function);
230 }
231 
SetGetter(JSThread *thread, const JSHandle<JSObject> &obj, const JSHandle<JSTaggedValue> &key, const JSHandle<JSTaggedValue> &getter)232 void ContainersPrivate::SetGetter(JSThread *thread, const JSHandle<JSObject> &obj, const JSHandle<JSTaggedValue> &key,
233                                   const JSHandle<JSTaggedValue> &getter)
234 {
235     ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
236     JSHandle<AccessorData> accessor = factory->NewAccessorData();
237     accessor->SetGetter(thread, getter);
238     PropertyAttributes attr = PropertyAttributes::DefaultAccessor(false, false, false);
239     JSObject::AddAccessor(thread, JSHandle<JSTaggedValue>::Cast(obj), key, accessor, attr);
240 }
241 
SetFunctionAtSymbol(JSThread *thread, const JSHandle<GlobalEnv> &env, const JSHandle<JSObject> &obj, const JSHandle<JSTaggedValue> &symbol, const char *name, EcmaEntrypoint func, int length)242 void ContainersPrivate::SetFunctionAtSymbol(JSThread *thread, const JSHandle<GlobalEnv> &env,
243                                             const JSHandle<JSObject> &obj, const JSHandle<JSTaggedValue> &symbol,
244                                             const char *name, EcmaEntrypoint func, int length)
245 {
246     ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
247     JSHandle<JSFunction> function = factory->NewJSFunction(env, reinterpret_cast<void *>(func));
248     JSFunction::SetFunctionLength(thread, function, JSTaggedValue(length));
249     JSHandle<JSTaggedValue> nameString(factory->NewFromASCII(name));
250     JSHandle<JSFunctionBase> baseFunction(function);
251     JSFunction::SetFunctionName(thread, baseFunction, nameString, thread->GlobalConstants()->GetHandledUndefined());
252     PropertyDescriptor descriptor(thread, JSHandle<JSTaggedValue>::Cast(function), false, false, false);
253     JSObject::DefineOwnProperty(thread, obj, symbol, descriptor);
254 }
255 
SetStringTagSymbol(JSThread *thread, const JSHandle<GlobalEnv> &env, const JSHandle<JSObject> &obj, const char *key)256 void ContainersPrivate::SetStringTagSymbol(JSThread *thread, const JSHandle<GlobalEnv> &env,
257                                            const JSHandle<JSObject> &obj, const char *key)
258 {
259     ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
260     JSHandle<JSTaggedValue> tag(factory->NewFromASCII(key));
261     JSHandle<JSTaggedValue> symbol = env->GetToStringTagSymbol();
262     PropertyDescriptor desc(thread, tag, false, false, false);
263     JSObject::DefineOwnProperty(thread, obj, symbol, desc);
264 }
265 
InitializeArrayList(JSThread *thread)266 JSHandle<JSTaggedValue> ContainersPrivate::InitializeArrayList(JSThread *thread)
267 {
268     auto globalConst = const_cast<GlobalEnvConstants *>(thread->GlobalConstants());
269     ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
270     // ArrayList.prototype
271     JSHandle<JSObject> prototype = factory->NewEmptyJSObject();
272     JSHandle<JSTaggedValue> arrayListFuncPrototypeValue(prototype);
273     // ArrayList.prototype_or_hclass
274     JSHandle<JSHClass> arrayListInstanceClass =
275         factory->NewEcmaHClass(JSAPIArrayList::SIZE, JSType::JS_API_ARRAY_LIST, arrayListFuncPrototypeValue);
276     // ArrayList() = new Function()
277     JSHandle<JSTaggedValue> arrayListFunction(NewContainerConstructor(
278         thread, prototype, ContainersArrayList::ArrayListConstructor, "ArrayList", FuncLength::ZERO));
279     JSFunction::SetFunctionPrototypeOrInstanceHClass(thread,
280         JSHandle<JSFunction>::Cast(arrayListFunction), arrayListInstanceClass.GetTaggedValue());
281 
282     // "constructor" property on the prototype
283     JSHandle<JSTaggedValue> constructorKey = globalConst->GetHandledConstructorString();
284     JSObject::SetProperty(thread, JSHandle<JSTaggedValue>(prototype), constructorKey, arrayListFunction);
285     RETURN_HANDLE_IF_ABRUPT_COMPLETION(JSTaggedValue, thread);
286 
287     // ArrayList.prototype
288     SetFrozenFunction(thread, prototype, "add", ContainersArrayList::Add, FuncLength::ONE);
289     SetFrozenFunction(thread, prototype, "insert", ContainersArrayList::Insert, FuncLength::TWO);
290     SetFrozenFunction(thread, prototype, "clear", ContainersArrayList::Clear, FuncLength::ZERO);
291     SetFrozenFunction(thread, prototype, "clone", ContainersArrayList::Clone, FuncLength::ZERO);
292     SetFrozenFunction(thread, prototype, "has", ContainersArrayList::Has, FuncLength::ONE);
293     SetFrozenFunction(thread, prototype, "getCapacity", ContainersArrayList::GetCapacity, FuncLength::ZERO);
294     SetFrozenFunction(thread, prototype, "increaseCapacityTo",
295                       ContainersArrayList::IncreaseCapacityTo, FuncLength::ONE);
296     SetFrozenFunction(thread, prototype, "trimToCurrentLength",
297                       ContainersArrayList::TrimToCurrentLength, FuncLength::ZERO);
298     SetFrozenFunction(thread, prototype, "getIndexOf", ContainersArrayList::GetIndexOf, FuncLength::ONE);
299     SetFrozenFunction(thread, prototype, "isEmpty", ContainersArrayList::IsEmpty, FuncLength::ZERO);
300     SetFrozenFunction(thread, prototype, "getLastIndexOf", ContainersArrayList::GetLastIndexOf, FuncLength::ONE);
301     SetFrozenFunction(thread, prototype, "removeByIndex", ContainersArrayList::RemoveByIndex, FuncLength::ONE);
302     SetFrozenFunction(thread, prototype, "remove", ContainersArrayList::Remove, FuncLength::ONE);
303     SetFrozenFunction(thread, prototype, "removeByRange", ContainersArrayList::RemoveByRange, FuncLength::TWO);
304     SetFrozenFunction(thread, prototype, "replaceAllElements", ContainersArrayList::ReplaceAllElements,
305         FuncLength::TWO, BUILTINS_STUB_ID(ArrayListReplaceAllElements));
306     SetFrozenFunction(thread, prototype, "sort", ContainersArrayList::Sort, FuncLength::ONE);
307     SetFrozenFunction(thread, prototype, "subArrayList", ContainersArrayList::SubArrayList, FuncLength::TWO);
308     SetFrozenFunction(thread, prototype, "convertToArray", ContainersArrayList::ConvertToArray, FuncLength::ZERO);
309     SetFrozenFunction(thread, prototype, "forEach", ContainersArrayList::ForEach, FuncLength::TWO,
310         BUILTINS_STUB_ID(ArrayListForEach));
311 
312     JSHandle<GlobalEnv> env = thread->GetEcmaVM()->GetGlobalEnv();
313     SetStringTagSymbol(thread, env, prototype, "ArrayList");
314 
315     JSHandle<JSTaggedValue> lengthGetter = CreateGetter(thread, ContainersArrayList::GetSize, "length",
316                                                         FuncLength::ZERO);
317     JSHandle<JSTaggedValue> lengthKey(thread, globalConst->GetLengthString());
318     SetGetter(thread, prototype, lengthKey, lengthGetter);
319 
320     SetFunctionAtSymbol(thread, env, prototype, env->GetIteratorSymbol(), "[Symbol.iterator]",
321                         ContainersArrayList::GetIteratorObj, FuncLength::ONE);
322     ContainersPrivate::InitializeArrayListIterator(thread, env, globalConst);
323     globalConst->SetConstant(ConstantIndex::ARRAYLIST_FUNCTION_INDEX, arrayListFunction.GetTaggedValue());
324     return arrayListFunction;
325 }
326 
InitializeArrayListIterator(JSThread *thread, const JSHandle<GlobalEnv> &env, GlobalEnvConstants *globalConst)327 void ContainersPrivate::InitializeArrayListIterator(JSThread *thread, const JSHandle<GlobalEnv> &env,
328                                                     GlobalEnvConstants *globalConst)
329 {
330     ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
331     // Iterator.hclass
332     JSHandle<JSHClass> iteratorFuncHClass =
333         factory->NewEcmaHClass(JSObject::SIZE, JSType::JS_ITERATOR, env->GetIteratorPrototype());
334     // ArrayListIterator.prototype
335     JSHandle<JSObject> arrayListIteratorPrototype(factory->NewJSObject(iteratorFuncHClass));
336     // Iterator.prototype.next()
337     SetFrozenFunction(thread, arrayListIteratorPrototype, "next", JSAPIArrayListIterator::Next, FuncLength::ONE);
338     SetStringTagSymbol(thread, env, arrayListIteratorPrototype, "ArrayList Iterator");
339     globalConst->SetConstant(ConstantIndex::ARRAYLIST_ITERATOR_PROTOTYPE_INDEX,
340                              arrayListIteratorPrototype.GetTaggedValue());
341 }
342 
InitializeLightWeightMap(JSThread *thread)343 JSHandle<JSTaggedValue> ContainersPrivate::InitializeLightWeightMap(JSThread *thread)
344 {
345     const GlobalEnvConstants *globalConst = thread->GlobalConstants();
346     ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
347     JSHandle<JSObject> funcPrototype = factory->NewEmptyJSObject();
348     JSHandle<JSTaggedValue> mapFuncPrototypeValue(funcPrototype);
349     JSHandle<JSHClass> lightWeightMapInstanceClass =
350         factory->NewEcmaHClass(JSAPILightWeightMap::SIZE, JSType::JS_API_LIGHT_WEIGHT_MAP, mapFuncPrototypeValue);
351     JSHandle<JSTaggedValue> lightWeightMapFunction(NewContainerConstructor(
352         thread, funcPrototype, ContainersLightWeightMap::LightWeightMapConstructor, "LightWeightMap",
353         FuncLength::ZERO));
354     JSFunction::SetFunctionPrototypeOrInstanceHClass(thread,
355         JSHandle<JSFunction>::Cast(lightWeightMapFunction), lightWeightMapInstanceClass.GetTaggedValue());
356 
357     // "constructor" property on the prototype
358     JSHandle<JSTaggedValue> constructorKey = globalConst->GetHandledConstructorString();
359     JSObject::SetProperty(thread, JSHandle<JSTaggedValue>(funcPrototype), constructorKey, lightWeightMapFunction);
360     RETURN_HANDLE_IF_ABRUPT_COMPLETION(JSTaggedValue, thread);
361 
362     // LightWeightMap.prototype.add()
363     SetFrozenFunction(thread, funcPrototype, "hasAll", ContainersLightWeightMap::HasAll, FuncLength::ONE);
364     SetFrozenFunction(thread, funcPrototype, "hasKey", ContainersLightWeightMap::HasKey, FuncLength::ONE);
365     SetFrozenFunction(thread, funcPrototype, "hasValue", ContainersLightWeightMap::HasValue, FuncLength::ONE);
366     SetFrozenFunction(thread, funcPrototype, "increaseCapacityTo", ContainersLightWeightMap::IncreaseCapacityTo,
367                       FuncLength::ONE);
368     SetFrozenFunction(thread, funcPrototype, "entries", ContainersLightWeightMap::Entries, FuncLength::ONE);
369     SetFrozenFunction(thread, funcPrototype, "get", ContainersLightWeightMap::Get, FuncLength::ONE);
370     SetFrozenFunction(thread, funcPrototype, "getIndexOfKey", ContainersLightWeightMap::GetIndexOfKey, FuncLength::ONE);
371     SetFrozenFunction(thread, funcPrototype, "getIndexOfValue", ContainersLightWeightMap::GetIndexOfValue,
372                       FuncLength::ONE);
373     SetFrozenFunction(thread, funcPrototype, "isEmpty", ContainersLightWeightMap::IsEmpty, FuncLength::ONE);
374     SetFrozenFunction(thread, funcPrototype, "getKeyAt", ContainersLightWeightMap::GetKeyAt, FuncLength::ONE);
375     SetFrozenFunction(thread, funcPrototype, "keys", ContainersLightWeightMap::Keys, FuncLength::ONE);
376     SetFrozenFunction(thread, funcPrototype, "setAll", ContainersLightWeightMap::SetAll, FuncLength::ONE);
377     SetFrozenFunction(thread, funcPrototype, "set", ContainersLightWeightMap::Set, FuncLength::ONE);
378     SetFrozenFunction(thread, funcPrototype, "remove", ContainersLightWeightMap::Remove, FuncLength::ONE);
379     SetFrozenFunction(thread, funcPrototype, "removeAt", ContainersLightWeightMap::RemoveAt, FuncLength::ONE);
380     SetFrozenFunction(thread, funcPrototype, "clear", ContainersLightWeightMap::Clear, FuncLength::ONE);
381     SetFrozenFunction(thread, funcPrototype, "setValueAt", ContainersLightWeightMap::SetValueAt, FuncLength::ONE);
382     SetFrozenFunction(thread, funcPrototype, "forEach", ContainersLightWeightMap::ForEach, FuncLength::ONE,
383                       BUILTINS_STUB_ID(LightWeightMapForEach));
384     SetFrozenFunction(thread, funcPrototype, "toString", ContainersLightWeightMap::ToString, FuncLength::ONE);
385     SetFrozenFunction(thread, funcPrototype, "getValueAt", ContainersLightWeightMap::GetValueAt, FuncLength::ONE);
386     SetFrozenFunction(thread, funcPrototype, "values", ContainersLightWeightMap::Values, FuncLength::ONE);
387 
388     JSHandle<JSTaggedValue> lengthGetter = CreateGetter(thread, ContainersLightWeightMap::Length, "length",
389                                                         FuncLength::ZERO);
390     JSHandle<JSTaggedValue> lengthKey(factory->NewFromASCII("length"));
391     SetGetter(thread, funcPrototype, lengthKey, lengthGetter);
392 
393     JSHandle<GlobalEnv> env = thread->GetEcmaVM()->GetGlobalEnv();
394     SetFunctionAtSymbol(thread, env, funcPrototype, env->GetIteratorSymbol(), "[Symbol.iterator]",
395                         ContainersLightWeightMap::Entries, FuncLength::ONE);
396 
397     ContainersPrivate::InitializeLightWeightMapIterator(thread);
398     return lightWeightMapFunction;
399 }
400 
InitializeLightWeightMapIterator(JSThread *thread)401 void ContainersPrivate::InitializeLightWeightMapIterator(JSThread *thread)
402 {
403     JSHandle<GlobalEnv> env = thread->GetEcmaVM()->GetGlobalEnv();
404     ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
405     JSHandle<JSHClass> iteratorClass = factory->NewEcmaHClass(JSObject::SIZE, JSType::JS_ITERATOR,
406                                                               env->GetIteratorPrototype());
407     JSHandle<JSObject> lightWeightMapIteratorPrototype(factory->NewJSObject(iteratorClass));
408     SetFrozenFunction(thread, lightWeightMapIteratorPrototype, "next", JSAPILightWeightMapIterator::Next,
409                       FuncLength::ONE);
410     SetStringTagSymbol(thread, env, lightWeightMapIteratorPrototype, "LightWeightMap Iterator");
411     auto globalConst = const_cast<GlobalEnvConstants *>(thread->GlobalConstants());
412     globalConst->SetConstant(ConstantIndex::LIGHTWEIGHTMAP_ITERATOR_PROTOTYPE_INDEX,
413                              lightWeightMapIteratorPrototype.GetTaggedValue());
414 }
415 
InitializeLightWeightSet(JSThread *thread)416 JSHandle<JSTaggedValue> ContainersPrivate::InitializeLightWeightSet(JSThread *thread)
417 {
418     const GlobalEnvConstants *globalConst = thread->GlobalConstants();
419     ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
420     // LightWeightSet.prototype
421     JSHandle<JSObject> funcPrototype = factory->NewEmptyJSObject();
422     JSHandle<JSTaggedValue> funcPrototypeValue(funcPrototype);
423     // LightWeightSet.prototype_or_hclass
424     JSHandle<JSHClass> lightweightSetInstanceClass =
425         factory->NewEcmaHClass(JSAPILightWeightSet::SIZE, JSType::JS_API_LIGHT_WEIGHT_SET, funcPrototypeValue);
426     JSHandle<JSTaggedValue> lightweightSetFunction(
427         NewContainerConstructor(thread, funcPrototype, ContainersLightWeightSet::LightWeightSetConstructor,
428                                 "LightWeightSet", FuncLength::ZERO));
429     JSFunction::SetFunctionPrototypeOrInstanceHClass(thread,
430         JSHandle<JSFunction>::Cast(lightweightSetFunction), lightweightSetInstanceClass.GetTaggedValue());
431     // "constructor" property on the prototype
432     JSHandle<JSTaggedValue> constructorKey = globalConst->GetHandledConstructorString();
433     JSObject::SetProperty(thread, JSHandle<JSTaggedValue>(funcPrototype), constructorKey, lightweightSetFunction);
434     RETURN_HANDLE_IF_ABRUPT_COMPLETION(JSTaggedValue, thread);
435     SetFrozenFunction(thread, funcPrototype, "add", ContainersLightWeightSet::Add, FuncLength::ONE);
436     SetFrozenFunction(thread, funcPrototype, "addAll", ContainersLightWeightSet::AddAll, FuncLength::ONE);
437     SetFrozenFunction(thread, funcPrototype, "isEmpty", ContainersLightWeightSet::IsEmpty, FuncLength::ONE);
438     SetFrozenFunction(thread, funcPrototype, "getValueAt", ContainersLightWeightSet::GetValueAt, FuncLength::ONE);
439     SetFrozenFunction(thread, funcPrototype, "hasAll", ContainersLightWeightSet::HasAll, FuncLength::ONE);
440     SetFrozenFunction(thread, funcPrototype, "has", ContainersLightWeightSet::Has, FuncLength::ONE);
441     SetFrozenFunction(thread, funcPrototype, "equal", ContainersLightWeightSet::Equal, FuncLength::ONE);
442     SetFrozenFunction(thread, funcPrototype, "increaseCapacityTo",
443                       ContainersLightWeightSet::IncreaseCapacityTo, FuncLength::ONE);
444     SetFrozenFunction(thread, funcPrototype, "forEach", ContainersLightWeightSet::ForEach, FuncLength::ONE,
445                       BUILTINS_STUB_ID(LightWeightSetForEach));
446     SetFrozenFunction(thread, funcPrototype, "getIndexOf", ContainersLightWeightSet::GetIndexOf, FuncLength::ONE);
447     SetFrozenFunction(thread, funcPrototype, "remove", ContainersLightWeightSet::Remove, FuncLength::ZERO);
448     SetFrozenFunction(thread, funcPrototype, "removeAt", ContainersLightWeightSet::RemoveAt, FuncLength::ZERO);
449     SetFrozenFunction(thread, funcPrototype, "clear", ContainersLightWeightSet::Clear, FuncLength::ONE);
450     SetFrozenFunction(thread, funcPrototype, "toString", ContainersLightWeightSet::ToString, FuncLength::ZERO);
451     SetFrozenFunction(thread, funcPrototype, "toArray", ContainersLightWeightSet::ToArray, FuncLength::ONE);
452     SetFrozenFunction(thread, funcPrototype, "values", ContainersLightWeightSet::Values, FuncLength::ONE);
453     SetFrozenFunction(thread, funcPrototype, "entries", ContainersLightWeightSet::Entries, FuncLength::ZERO);
454     JSHandle<JSTaggedValue> lengthGetter =
455         CreateGetter(thread, ContainersLightWeightSet::GetSize, "length", FuncLength::ZERO);
456 
457     JSHandle<JSTaggedValue> lengthKey(factory->NewFromASCII("length"));
458     SetGetter(thread, funcPrototype, lengthKey, lengthGetter);
459     JSHandle<GlobalEnv> env = thread->GetEcmaVM()->GetGlobalEnv();
460     SetFunctionAtSymbol(thread, env, funcPrototype, env->GetIteratorSymbol(), "[Symbol.iterator]",
461                         ContainersLightWeightSet::GetIteratorObj, FuncLength::ONE);
462 
463     InitializeLightWeightSetIterator(thread);
464     return lightweightSetFunction;
465 }
466 
InitializeLightWeightSetIterator(JSThread *thread)467 void ContainersPrivate::InitializeLightWeightSetIterator(JSThread *thread)
468 {
469     JSHandle<GlobalEnv> env = thread->GetEcmaVM()->GetGlobalEnv();
470     ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
471     auto globalConst = const_cast<GlobalEnvConstants *>(thread->GlobalConstants());
472     JSHandle<JSHClass> iteratorClass =
473         JSHandle<JSHClass>(thread, globalConst->GetHandledJSAPIIteratorFuncHClass().GetObject<JSHClass>());
474     JSHandle<JSObject> lightWeightSetIteratorPrototype(factory->NewJSObject(iteratorClass));
475     SetFrozenFunction(
476         thread, lightWeightSetIteratorPrototype, "next", JSAPILightWeightSetIterator::Next, FuncLength::ONE);
477     SetStringTagSymbol(thread, env, lightWeightSetIteratorPrototype, "LightWeightSet Iterator");
478     globalConst->SetConstant(ConstantIndex::LIGHTWEIGHTSET_ITERATOR_PROTOTYPE_INDEX,
479                              lightWeightSetIteratorPrototype.GetTaggedValue());
480 }
481 
InitializeTreeMap(JSThread *thread)482 JSHandle<JSTaggedValue> ContainersPrivate::InitializeTreeMap(JSThread *thread)
483 {
484     const GlobalEnvConstants *globalConst = thread->GlobalConstants();
485     ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
486     // TreeMap.prototype
487     JSHandle<JSObject> mapFuncPrototype = factory->NewEmptyJSObject();
488     JSHandle<JSTaggedValue> mapFuncPrototypeValue(mapFuncPrototype);
489     // TreeMap.prototype_or_hclass
490     JSHandle<JSHClass> mapInstanceClass =
491         factory->NewEcmaHClass(JSAPITreeMap::SIZE, JSType::JS_API_TREE_MAP, mapFuncPrototypeValue);
492     // TreeMap() = new Function()
493     JSHandle<JSTaggedValue> mapFunction(NewContainerConstructor(
494         thread, mapFuncPrototype, ContainersTreeMap::TreeMapConstructor, "TreeMap", FuncLength::ZERO));
495     JSFunction::SetFunctionPrototypeOrInstanceHClass(thread,
496         JSHandle<JSFunction>::Cast(mapFunction), mapInstanceClass.GetTaggedValue());
497 
498     // "constructor" property on the prototype
499     JSHandle<JSTaggedValue> constructorKey = globalConst->GetHandledConstructorString();
500     JSObject::SetProperty(thread, JSHandle<JSTaggedValue>(mapFuncPrototype), constructorKey, mapFunction);
501     RETURN_HANDLE_IF_ABRUPT_COMPLETION(JSTaggedValue, thread);
502     // TreeMap.prototype
503     SetFrozenFunction(thread, mapFuncPrototype, "set", ContainersTreeMap::Set, FuncLength::TWO);
504     SetFrozenFunction(thread, mapFuncPrototype, "get", ContainersTreeMap::Get, FuncLength::ONE);
505     SetFrozenFunction(thread, mapFuncPrototype, "remove", ContainersTreeMap::Remove, FuncLength::ONE);
506     SetFrozenFunction(thread, mapFuncPrototype, "hasKey", ContainersTreeMap::HasKey, FuncLength::ONE);
507     SetFrozenFunction(thread, mapFuncPrototype, "hasValue", ContainersTreeMap::HasValue, FuncLength::ONE);
508     SetFrozenFunction(thread, mapFuncPrototype, "getFirstKey", ContainersTreeMap::GetFirstKey, FuncLength::ZERO);
509     SetFrozenFunction(thread, mapFuncPrototype, "getLastKey", ContainersTreeMap::GetLastKey, FuncLength::ZERO);
510     SetFrozenFunction(thread, mapFuncPrototype, "setAll", ContainersTreeMap::SetAll, FuncLength::ONE);
511     SetFrozenFunction(thread, mapFuncPrototype, "clear", ContainersTreeMap::Clear, FuncLength::ZERO);
512     SetFrozenFunction(thread, mapFuncPrototype, "getLowerKey", ContainersTreeMap::GetLowerKey, FuncLength::ONE);
513     SetFrozenFunction(thread, mapFuncPrototype, "getHigherKey", ContainersTreeMap::GetHigherKey, FuncLength::ONE);
514     SetFrozenFunction(thread, mapFuncPrototype, "keys", ContainersTreeMap::Keys, FuncLength::ZERO);
515     SetFrozenFunction(thread, mapFuncPrototype, "values", ContainersTreeMap::Values, FuncLength::ZERO);
516     SetFrozenFunction(thread, mapFuncPrototype, "replace", ContainersTreeMap::Replace, FuncLength::TWO);
517     SetFrozenFunction(thread, mapFuncPrototype, "forEach", ContainersTreeMap::ForEach, FuncLength::ONE);
518     SetFrozenFunction(thread, mapFuncPrototype, "entries", ContainersTreeMap::Entries, FuncLength::ZERO);
519     SetFrozenFunction(thread, mapFuncPrototype, "isEmpty", ContainersTreeMap::IsEmpty, FuncLength::ZERO);
520 
521     // @@ToStringTag
522     JSHandle<GlobalEnv> env = thread->GetEcmaVM()->GetGlobalEnv();
523     SetStringTagSymbol(thread, env, mapFuncPrototype, "TreeMap");
524     // %TreeMapPrototype% [ @@iterator ]
525     JSHandle<JSTaggedValue> iteratorSymbol = env->GetIteratorSymbol();
526     JSHandle<JSTaggedValue> entries = globalConst->GetHandledEntriesString();
527     JSHandle<JSTaggedValue> entriesFunc =
528         JSObject::GetMethod(thread, JSHandle<JSTaggedValue>::Cast(mapFuncPrototype), entries);
529     RETURN_HANDLE_IF_ABRUPT_COMPLETION(JSTaggedValue, thread);
530     PropertyDescriptor descriptor(thread, entriesFunc, false, false, false);
531     JSObject::DefineOwnProperty(thread, mapFuncPrototype, iteratorSymbol, descriptor);
532     // length
533     JSHandle<JSTaggedValue> lengthGetter =
534         CreateGetter(thread, ContainersTreeMap::GetLength, "length", FuncLength::ZERO);
535     JSHandle<JSTaggedValue> lengthKey(thread, globalConst->GetLengthString());
536     SetGetter(thread, mapFuncPrototype, lengthKey, lengthGetter);
537 
538     InitializeTreeMapIterator(thread);
539     return mapFunction;
540 }
541 
InitializeTreeMapIterator(JSThread *thread)542 void ContainersPrivate::InitializeTreeMapIterator(JSThread *thread)
543 {
544     JSHandle<GlobalEnv> env = thread->GetEcmaVM()->GetGlobalEnv();
545     ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
546     // Iterator.hclass
547     JSHandle<JSHClass> iteratorClass =
548         factory->NewEcmaHClass(JSObject::SIZE, JSType::JS_ITERATOR, env->GetIteratorPrototype());
549 
550     // TreeMapIterator.prototype
551     JSHandle<JSObject> mapIteratorPrototype(factory->NewJSObject(iteratorClass));
552     // TreeIterator.prototype.next()
553     SetFrozenFunction(thread, mapIteratorPrototype, "next", JSAPITreeMapIterator::Next, FuncLength::ZERO);
554     SetStringTagSymbol(thread, env, mapIteratorPrototype, "TreeMap Iterator");
555     auto globalConst = const_cast<GlobalEnvConstants *>(thread->GlobalConstants());
556     globalConst->SetConstant(ConstantIndex::TREEMAP_ITERATOR_PROTOTYPE_INDEX, mapIteratorPrototype.GetTaggedValue());
557 }
558 
InitializeTreeSet(JSThread *thread)559 JSHandle<JSTaggedValue> ContainersPrivate::InitializeTreeSet(JSThread *thread)
560 {
561     const GlobalEnvConstants *globalConst = thread->GlobalConstants();
562     ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
563     // TreeSet.prototype
564     JSHandle<JSObject> setFuncPrototype = factory->NewEmptyJSObject();
565     JSHandle<JSTaggedValue> setFuncPrototypeValue(setFuncPrototype);
566     // TreeSet.prototype_or_hclass
567     JSHandle<JSHClass> setInstanceClass =
568         factory->NewEcmaHClass(JSAPITreeSet::SIZE, JSType::JS_API_TREE_SET, setFuncPrototypeValue);
569     // TreeSet() = new Function()
570     JSHandle<JSTaggedValue> setFunction(NewContainerConstructor(
571         thread, setFuncPrototype, ContainersTreeSet::TreeSetConstructor, "TreeSet", FuncLength::ZERO));
572     JSFunction::SetFunctionPrototypeOrInstanceHClass(thread,
573         JSHandle<JSFunction>::Cast(setFunction), setInstanceClass.GetTaggedValue());
574 
575     // "constructor" property on the prototype
576     JSHandle<JSTaggedValue> constructorKey = globalConst->GetHandledConstructorString();
577     JSObject::SetProperty(thread, JSHandle<JSTaggedValue>(setFuncPrototype), constructorKey, setFunction);
578     RETURN_HANDLE_IF_ABRUPT_COMPLETION(JSTaggedValue, thread);
579     // TreeSet.prototype
580     SetFrozenFunction(thread, setFuncPrototype, "add", ContainersTreeSet::Add, FuncLength::TWO);
581     SetFrozenFunction(thread, setFuncPrototype, "remove", ContainersTreeSet::Remove, FuncLength::ONE);
582     SetFrozenFunction(thread, setFuncPrototype, "has", ContainersTreeSet::Has, FuncLength::ONE);
583     SetFrozenFunction(thread, setFuncPrototype, "getFirstValue", ContainersTreeSet::GetFirstValue, FuncLength::ZERO);
584     SetFrozenFunction(thread, setFuncPrototype, "getLastValue", ContainersTreeSet::GetLastValue, FuncLength::ZERO);
585     SetFrozenFunction(thread, setFuncPrototype, "clear", ContainersTreeSet::Clear, FuncLength::ZERO);
586     SetFrozenFunction(thread, setFuncPrototype, "getLowerValue", ContainersTreeSet::GetLowerValue, FuncLength::ONE);
587     SetFrozenFunction(thread, setFuncPrototype, "getHigherValue", ContainersTreeSet::GetHigherValue, FuncLength::ONE);
588     SetFrozenFunction(thread, setFuncPrototype, "popFirst", ContainersTreeSet::PopFirst, FuncLength::ZERO);
589     SetFrozenFunction(thread, setFuncPrototype, "popLast", ContainersTreeSet::PopLast, FuncLength::ZERO);
590     SetFrozenFunction(thread, setFuncPrototype, "isEmpty", ContainersTreeSet::IsEmpty, FuncLength::TWO);
591     SetFrozenFunction(thread, setFuncPrototype, "values", ContainersTreeSet::Values, FuncLength::ZERO);
592     SetFrozenFunction(thread, setFuncPrototype, "forEach", ContainersTreeSet::ForEach, FuncLength::ONE);
593     SetFrozenFunction(thread, setFuncPrototype, "entries", ContainersTreeSet::Entries, FuncLength::ZERO);
594 
595     // @@ToStringTag
596     JSHandle<GlobalEnv> env = thread->GetEcmaVM()->GetGlobalEnv();
597     SetStringTagSymbol(thread, env, setFuncPrototype, "TreeSet");
598     // %TreeSetPrototype% [ @@iterator ]
599     JSHandle<JSTaggedValue> iteratorSymbol = env->GetIteratorSymbol();
600     JSHandle<JSTaggedValue> values(thread, globalConst->GetValuesString());
601     JSHandle<JSTaggedValue> valuesFunc =
602         JSObject::GetMethod(thread, JSHandle<JSTaggedValue>::Cast(setFuncPrototype), values);
603     RETURN_HANDLE_IF_ABRUPT_COMPLETION(JSTaggedValue, thread);
604     PropertyDescriptor descriptor(thread, valuesFunc, false, false, false);
605     JSObject::DefineOwnProperty(thread, setFuncPrototype, iteratorSymbol, descriptor);
606     // length
607     JSHandle<JSTaggedValue> lengthGetter =
608         CreateGetter(thread, ContainersTreeSet::GetLength, "length", FuncLength::ZERO);
609     JSHandle<JSTaggedValue> lengthKey(thread, globalConst->GetLengthString());
610     SetGetter(thread, setFuncPrototype, lengthKey, lengthGetter);
611 
612     InitializeTreeSetIterator(thread);
613     return setFunction;
614 }
615 
InitializeTreeSetIterator(JSThread *thread)616 void ContainersPrivate::InitializeTreeSetIterator(JSThread *thread)
617 {
618     JSHandle<GlobalEnv> env = thread->GetEcmaVM()->GetGlobalEnv();
619     ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
620     // Iterator.hclass
621     JSHandle<JSHClass> iteratorClass =
622         factory->NewEcmaHClass(JSObject::SIZE, JSType::JS_ITERATOR, env->GetIteratorPrototype());
623 
624     // TreeSetIterator.prototype
625     JSHandle<JSObject> setIteratorPrototype(factory->NewJSObject(iteratorClass));
626     // TreeSetIterator.prototype.next()
627     SetFrozenFunction(thread, setIteratorPrototype, "next", JSAPITreeSetIterator::Next, FuncLength::ZERO);
628     SetStringTagSymbol(thread, env, setIteratorPrototype, "TreeSet Iterator");
629     auto globalConst = const_cast<GlobalEnvConstants *>(thread->GlobalConstants());
630     globalConst->SetConstant(ConstantIndex::TREESET_ITERATOR_PROTOTYPE_INDEX, setIteratorPrototype.GetTaggedValue());
631 }
632 
InitializePlainArray(JSThread *thread)633 JSHandle<JSTaggedValue> ContainersPrivate::InitializePlainArray(JSThread *thread)
634 {
635     auto globalConst = const_cast<GlobalEnvConstants *>(thread->GlobalConstants());
636     ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
637     // PlainArray.prototype
638     JSHandle<JSObject> plainArrayFuncPrototype = factory->NewEmptyJSObject();
639     JSHandle<JSTaggedValue> plainArrayFuncPrototypeValue(plainArrayFuncPrototype);
640     // PlainArray.prototype_or_hclass
641     JSHandle<JSHClass> plainArrayInstanceClass =
642         factory->NewEcmaHClass(JSAPIPlainArray::SIZE, JSType::JS_API_PLAIN_ARRAY, plainArrayFuncPrototypeValue);
643     JSHandle<JSTaggedValue> plainArrayFunction(
644         NewContainerConstructor(thread, plainArrayFuncPrototype, ContainersPlainArray::PlainArrayConstructor,
645                                 "PlainArray", FuncLength::ZERO));
646     JSFunction::SetFunctionPrototypeOrInstanceHClass(thread,
647         JSHandle<JSFunction>::Cast(plainArrayFunction), plainArrayInstanceClass.GetTaggedValue());
648 
649     // "constructor" property on the prototype
650     JSHandle<JSTaggedValue> constructorKey = globalConst->GetHandledConstructorString();
651     JSObject::SetProperty(thread, JSHandle<JSTaggedValue>(plainArrayFuncPrototype), constructorKey,
652                           plainArrayFunction);
653     RETURN_HANDLE_IF_ABRUPT_COMPLETION(JSTaggedValue, thread);
654     // PlainArray.prototype.add()
655     SetFrozenFunction(thread, plainArrayFuncPrototype, "add", ContainersPlainArray::Add, FuncLength::ONE);
656     SetFrozenFunction(thread, plainArrayFuncPrototype, "clear", ContainersPlainArray::Clear, FuncLength::ONE);
657     SetFrozenFunction(thread, plainArrayFuncPrototype, "clone", ContainersPlainArray::Clone, FuncLength::ONE);
658     SetFrozenFunction(thread, plainArrayFuncPrototype, "has", ContainersPlainArray::Has, FuncLength::ONE);
659     SetFrozenFunction(thread, plainArrayFuncPrototype, "get", ContainersPlainArray::Get, FuncLength::ONE);
660     SetFrozenFunction(thread, plainArrayFuncPrototype, "forEach", ContainersPlainArray::ForEach, FuncLength::ONE,
661                       BUILTINS_STUB_ID(PlainArrayForEach));
662     SetFrozenFunction(thread, plainArrayFuncPrototype, "toString", ContainersPlainArray::ToString,
663                       FuncLength::ZERO);
664     SetFrozenFunction(thread, plainArrayFuncPrototype, "getIndexOfKey", ContainersPlainArray::GetIndexOfKey,
665                       FuncLength::ZERO);
666     SetFrozenFunction(thread, plainArrayFuncPrototype, "getIndexOfValue", ContainersPlainArray::GetIndexOfValue,
667                       FuncLength::ZERO);
668     SetFrozenFunction(thread, plainArrayFuncPrototype, "isEmpty", ContainersPlainArray::IsEmpty, FuncLength::ZERO);
669     SetFrozenFunction(thread, plainArrayFuncPrototype, "getKeyAt",
670                       ContainersPlainArray::GetKeyAt, FuncLength::ZERO);
671     SetFrozenFunction(thread, plainArrayFuncPrototype, "remove", ContainersPlainArray::Remove, FuncLength::ZERO);
672     SetFrozenFunction(thread, plainArrayFuncPrototype, "removeAt", ContainersPlainArray::RemoveAt,
673                       FuncLength::ZERO);
674     SetFrozenFunction(thread, plainArrayFuncPrototype, "removeRangeFrom", ContainersPlainArray::RemoveRangeFrom,
675                       FuncLength::ZERO);
676     SetFrozenFunction(thread, plainArrayFuncPrototype, "setValueAt", ContainersPlainArray::SetValueAt,
677                       FuncLength::ZERO);
678     SetFrozenFunction(thread, plainArrayFuncPrototype, "getValueAt", ContainersPlainArray::GetValueAt,
679                       FuncLength::ZERO);
680 
681     JSHandle<JSTaggedValue> lengthGetter = CreateGetter(thread, ContainersPlainArray::GetSize, "length",
682                                                         FuncLength::ZERO);
683     JSHandle<JSTaggedValue> lengthKey = globalConst->GetHandledLengthString();
684     SetGetter(thread, plainArrayFuncPrototype, lengthKey, lengthGetter);
685 
686     JSHandle<GlobalEnv> env = thread->GetEcmaVM()->GetGlobalEnv();
687     SetFunctionAtSymbol(thread, env, plainArrayFuncPrototype, env->GetIteratorSymbol(), "[Symbol.iterator]",
688                         ContainersPlainArray::GetIteratorObj, FuncLength::ONE);
689     InitializePlainArrayIterator(thread);
690     globalConst->SetConstant(ConstantIndex::PLAIN_ARRAY_FUNCTION_INDEX, plainArrayFunction.GetTaggedValue());
691     return plainArrayFunction;
692 }
693 
InitializePlainArrayIterator(JSThread *thread)694 void ContainersPrivate::InitializePlainArrayIterator(JSThread *thread)
695 {
696     JSHandle<GlobalEnv> env = thread->GetEcmaVM()->GetGlobalEnv();
697     ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
698     auto globalConst = const_cast<GlobalEnvConstants *>(thread->GlobalConstants());
699     JSHandle<JSHClass> iteratorClass =
700         JSHandle<JSHClass>(thread, globalConst->GetHandledJSAPIIteratorFuncHClass().GetObject<JSHClass>());
701     JSHandle<JSObject> plainarrayIteratorPrototype(factory->NewJSObject(iteratorClass));
702     SetFrozenFunction(thread, plainarrayIteratorPrototype, "next", JSAPIPlainArrayIterator::Next, FuncLength::ONE);
703     SetStringTagSymbol(thread, env, plainarrayIteratorPrototype, "PlainArray Iterator");
704     globalConst->SetConstant(ConstantIndex::PLAIN_ARRAY_ITERATOR_PROTOTYPE_INDEX,
705                              plainarrayIteratorPrototype.GetTaggedValue());
706 }
707 
InitializeStack(JSThread *thread)708 JSHandle<JSTaggedValue> ContainersPrivate::InitializeStack(JSThread *thread)
709 {
710     auto globalConst = const_cast<GlobalEnvConstants *>(thread->GlobalConstants());
711     ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
712     // Stack.prototype
713     JSHandle<JSObject> stackFuncPrototype = factory->NewEmptyJSObject();
714     JSHandle<JSTaggedValue> stackFuncPrototypeValue(stackFuncPrototype);
715     // Stack.prototype_or_hclass
716     JSHandle<JSHClass> stackInstanceClass =
717         factory->NewEcmaHClass(JSAPIStack::SIZE, JSType::JS_API_STACK, stackFuncPrototypeValue);
718     // Stack() = new Function()
719     JSHandle<JSTaggedValue> stackFunction(NewContainerConstructor(
720         thread, stackFuncPrototype, ContainersStack::StackConstructor, "Stack", FuncLength::ZERO));
721     JSFunction::SetFunctionPrototypeOrInstanceHClass(thread,
722         JSHandle<JSFunction>::Cast(stackFunction), stackInstanceClass.GetTaggedValue());
723 
724     // "constructor" property on the prototype
725     JSHandle<JSTaggedValue> constructorKey = globalConst->GetHandledConstructorString();
726     JSObject::SetProperty(thread, JSHandle<JSTaggedValue>(stackFuncPrototype), constructorKey, stackFunction);
727     RETURN_HANDLE_IF_ABRUPT_COMPLETION(JSTaggedValue, thread);
728     // Stack.prototype.push()
729     SetFrozenFunction(thread, stackFuncPrototype, "push", ContainersStack::Push, FuncLength::ONE);
730     // Stack.prototype.empty()
731     SetFrozenFunction(thread, stackFuncPrototype, "isEmpty", ContainersStack::IsEmpty, FuncLength::ONE);
732     // Stack.prototype.peek()
733     SetFrozenFunction(thread, stackFuncPrototype, "peek", ContainersStack::Peek, FuncLength::ONE);
734     // Stack.prototype.pop()
735     SetFrozenFunction(thread, stackFuncPrototype, "pop", ContainersStack::Pop, FuncLength::ONE);
736     // Stack.prototype.search()
737     SetFrozenFunction(thread, stackFuncPrototype, "locate", ContainersStack::Locate, FuncLength::ONE);
738     // Stack.prototype.forEach()
739     SetFrozenFunction(thread, stackFuncPrototype, "forEach", ContainersStack::ForEach, FuncLength::ONE,
740                       BUILTINS_STUB_ID(StackForEach));
741     JSHandle<GlobalEnv> env = thread->GetEcmaVM()->GetGlobalEnv();
742     SetStringTagSymbol(thread, env, stackFuncPrototype, "Stack");
743 
744     JSHandle<JSTaggedValue> lengthGetter = CreateGetter(thread, ContainersStack::GetLength, "length", FuncLength::ZERO);
745     JSHandle<JSTaggedValue> lengthKey = globalConst->GetHandledLengthString();
746     SetGetter(thread, stackFuncPrototype, lengthKey, lengthGetter);
747 
748     SetFunctionAtSymbol(thread, env, stackFuncPrototype, env->GetIteratorSymbol(), "[Symbol.iterator]",
749                         ContainersStack::Iterator, FuncLength::ONE);
750 
751     ContainersPrivate::InitializeStackIterator(thread, globalConst);
752     return stackFunction;
753 }
754 
InitializeStackIterator(JSThread *thread, GlobalEnvConstants *globalConst)755 void ContainersPrivate::InitializeStackIterator(JSThread *thread, GlobalEnvConstants *globalConst)
756 {
757     ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
758     JSHandle<JSHClass> iteratorFuncHClass = JSHandle<JSHClass>(thread, globalConst->
759                         GetHandledJSAPIIteratorFuncHClass().GetObject<JSHClass>());
760     // StackIterator.prototype
761     JSHandle<JSObject> stackIteratorPrototype(factory->NewJSObject(iteratorFuncHClass));
762     // Iterator.prototype.next()
763     SetFrozenFunction(thread, stackIteratorPrototype, "next", JSAPIStackIterator::Next, FuncLength::ONE);
764     globalConst->SetConstant(ConstantIndex::STACK_ITERATOR_PROTOTYPE_INDEX, stackIteratorPrototype.GetTaggedValue());
765 }
766 
InitializeVector(JSThread *thread)767 JSHandle<JSTaggedValue> ContainersPrivate::InitializeVector(JSThread *thread)
768 {
769     auto globalConst = const_cast<GlobalEnvConstants *>(thread->GlobalConstants());
770     ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
771     // Vector.prototype
772     JSHandle<JSObject> prototype = factory->NewEmptyJSObject();
773     JSHandle<JSTaggedValue> vectorFuncPrototypeValue(prototype);
774     // Vector.prototype_or_hclass
775     JSHandle<JSHClass> vectorInstanceClass =
776         factory->NewEcmaHClass(JSAPIVector::SIZE, JSType::JS_API_VECTOR, vectorFuncPrototypeValue);
777     // Vector() = new Function()
778     JSHandle<JSTaggedValue> vectorFunction(NewContainerConstructor(
779         thread, prototype, ContainersVector::VectorConstructor, "Vector", FuncLength::ZERO));
780     JSFunction::SetFunctionPrototypeOrInstanceHClass(thread,
781         JSHandle<JSFunction>::Cast(vectorFunction), vectorInstanceClass.GetTaggedValue());
782 
783     // "constructor" property on the prototype
784     JSHandle<JSTaggedValue> constructorKey = globalConst->GetHandledConstructorString();
785     JSObject::SetProperty(thread, JSHandle<JSTaggedValue>(prototype), constructorKey, vectorFunction);
786     RETURN_HANDLE_IF_ABRUPT_COMPLETION(JSTaggedValue, thread);
787     // Vector.prototype
788     SetFrozenFunction(thread, prototype, "add", ContainersVector::Add, FuncLength::ONE);
789     SetFrozenFunction(thread, prototype, "insert", ContainersVector::Insert, FuncLength::TWO);
790     SetFrozenFunction(thread, prototype, "setLength", ContainersVector::SetLength, FuncLength::ONE);
791     SetFrozenFunction(thread, prototype, "getCapacity", ContainersVector::GetCapacity, FuncLength::ZERO);
792     SetFrozenFunction(thread, prototype, "increaseCapacityTo", ContainersVector::IncreaseCapacityTo, FuncLength::ONE);
793     SetFrozenFunction(thread, prototype, "get", ContainersVector::Get, FuncLength::ONE);
794     SetFrozenFunction(thread, prototype, "getIndexOf", ContainersVector::GetIndexOf, FuncLength::ONE);
795     SetFrozenFunction(thread, prototype, "getIndexFrom", ContainersVector::GetIndexFrom, FuncLength::TWO);
796     SetFrozenFunction(thread, prototype, "isEmpty", ContainersVector::IsEmpty, FuncLength::ZERO);
797     SetFrozenFunction(thread, prototype, "getLastElement", ContainersVector::GetLastElement, FuncLength::ZERO);
798     SetFrozenFunction(thread, prototype, "getLastIndexOf", ContainersVector::GetLastIndexOf, FuncLength::ONE);
799     SetFrozenFunction(thread, prototype, "getLastIndexFrom", ContainersVector::GetLastIndexFrom, FuncLength::TWO);
800     SetFrozenFunction(thread, prototype, "remove", ContainersVector::Remove, FuncLength::ONE);
801     SetFrozenFunction(thread, prototype, "removeByIndex", ContainersVector::RemoveByIndex, FuncLength::ONE);
802     SetFrozenFunction(thread, prototype, "removeByRange", ContainersVector::RemoveByRange, FuncLength::TWO);
803     SetFrozenFunction(thread, prototype, "set", ContainersVector::Set, FuncLength::TWO);
804     SetFrozenFunction(thread, prototype, "subVector", ContainersVector::SubVector, FuncLength::TWO);
805     SetFrozenFunction(thread, prototype, "toString", ContainersVector::ToString, FuncLength::ZERO);
806     SetFrozenFunction(thread, prototype, "forEach", ContainersVector::ForEach, FuncLength::TWO,
807                       BUILTINS_STUB_ID(VectorForEach));
808     SetFrozenFunction(thread, prototype, "replaceAllElements", ContainersVector::ReplaceAllElements, FuncLength::TWO,
809                       BUILTINS_STUB_ID(VectorReplaceAllElements));
810     SetFrozenFunction(thread, prototype, "has", ContainersVector::Has, FuncLength::ONE);
811     SetFrozenFunction(thread, prototype, "sort", ContainersVector::Sort, FuncLength::ZERO);
812     SetFrozenFunction(thread, prototype, "clear", ContainersVector::Clear, FuncLength::ZERO);
813     SetFrozenFunction(thread, prototype, "clone", ContainersVector::Clone, FuncLength::ZERO);
814     SetFrozenFunction(thread, prototype, "copyToArray", ContainersVector::CopyToArray, FuncLength::ONE);
815     SetFrozenFunction(thread, prototype, "convertToArray", ContainersVector::ConvertToArray, FuncLength::ZERO);
816     SetFrozenFunction(thread, prototype, "getFirstElement", ContainersVector::GetFirstElement, FuncLength::ZERO);
817     SetFrozenFunction(thread, prototype, "trimToCurrentLength",
818                       ContainersVector::TrimToCurrentLength, FuncLength::ZERO);
819 
820     JSHandle<GlobalEnv> env = thread->GetEcmaVM()->GetGlobalEnv();
821     SetStringTagSymbol(thread, env, prototype, "Vector");
822 
823     JSHandle<JSTaggedValue> lengthGetter = CreateGetter(thread, ContainersVector::GetSize, "length", FuncLength::ZERO);
824     JSHandle<JSTaggedValue> lengthKey(thread, globalConst->GetLengthString());
825     SetGetter(thread, prototype, lengthKey, lengthGetter);
826 
827     SetFunctionAtSymbol(thread, env, prototype, env->GetIteratorSymbol(), "[Symbol.iterator]",
828                         ContainersVector::GetIteratorObj, FuncLength::ONE);
829 
830     ContainersPrivate::InitializeVectorIterator(thread, env, globalConst);
831     globalConst->SetConstant(ConstantIndex::VECTOR_FUNCTION_INDEX, vectorFunction.GetTaggedValue());
832     return vectorFunction;
833 }
834 
InitializeVectorIterator(JSThread *thread, const JSHandle<GlobalEnv> &env, GlobalEnvConstants *globalConst)835 void ContainersPrivate::InitializeVectorIterator(JSThread *thread, const JSHandle<GlobalEnv> &env,
836                                                  GlobalEnvConstants *globalConst)
837 {
838     ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
839     JSHandle<JSHClass> iteratorFuncHClass = JSHandle<JSHClass>(thread, globalConst->
840                         GetHandledJSAPIIteratorFuncHClass().GetObject<JSHClass>());
841     // VectorIterator.prototype
842     JSHandle<JSObject> vectorIteratorPrototype(factory->NewJSObject(iteratorFuncHClass));
843     // Iterator.prototype.next()
844     SetFrozenFunction(thread, vectorIteratorPrototype, "next", JSAPIVectorIterator::Next, FuncLength::ONE);
845     SetStringTagSymbol(thread, env, vectorIteratorPrototype, "Vector Iterator");
846     globalConst->SetConstant(ConstantIndex::VECTOR_ITERATOR_PROTOTYPE_INDEX, vectorIteratorPrototype.GetTaggedValue());
847 }
848 
InitializeBitVector(JSThread* thread)849 JSHandle<JSTaggedValue> ContainersPrivate::InitializeBitVector(JSThread* thread)
850 {
851     auto globalConst = const_cast<GlobalEnvConstants*>(thread->GlobalConstants());
852     ObjectFactory* factory = thread->GetEcmaVM()->GetFactory();
853     // BitVector.prototype
854     JSHandle<JSObject> prototype = factory->NewEmptyJSObject();
855     JSHandle<JSTaggedValue> bitVectorFuncPrototypeValue(prototype);
856     // BitVector.prototype_or_hclass
857     JSHandle<JSHClass> bitVectorInstanceClass =
858         factory->NewEcmaHClass(JSAPIBitVector::SIZE, JSType::JS_API_BITVECTOR, bitVectorFuncPrototypeValue);
859     // BitVector() = new Function()
860     JSHandle<JSTaggedValue> bitVectorFunction(NewContainerConstructor(
861         thread, prototype, ContainersBitVector::BitVectorConstructor, "BitVector", FuncLength::ONE));
862     JSFunction::SetFunctionPrototypeOrInstanceHClass(
863         thread, JSHandle<JSFunction>::Cast(bitVectorFunction), bitVectorInstanceClass.GetTaggedValue());
864 
865     // "constructor" property on the prototype
866     JSHandle<JSTaggedValue> constructorKey = globalConst->GetHandledConstructorString();
867     JSObject::SetProperty(thread, JSHandle<JSTaggedValue>(prototype), constructorKey, bitVectorFunction);
868     RETURN_HANDLE_IF_ABRUPT_COMPLETION(JSTaggedValue, thread);
869 
870     // BitVector.prototype
871     SetFrozenFunction(thread, prototype, "push", ContainersBitVector::Push, FuncLength::ONE);
872     SetFrozenFunction(thread, prototype, "pop", ContainersBitVector::Pop, FuncLength::ZERO);
873     SetFrozenFunction(thread, prototype, "has", ContainersBitVector::Has, FuncLength::THREE);
874     SetFrozenFunction(thread, prototype, "setBitsByRange", ContainersBitVector::SetBitsByRange, FuncLength::THREE);
875     SetFrozenFunction(thread, prototype, "getBitsByRange", ContainersBitVector::GetBitsByRange, FuncLength::TWO);
876     SetFrozenFunction(thread, prototype, "setAllBits", ContainersBitVector::SetAllBits, FuncLength::ONE);
877     SetFrozenFunction(thread, prototype, "resize", ContainersBitVector::Resize, FuncLength::ONE);
878     SetFrozenFunction(
879         thread, prototype, "getBitCountByRange", ContainersBitVector::GetBitCountByRange, FuncLength::THREE);
880     SetFrozenFunction(thread, prototype, "getIndexOf", ContainersBitVector::GetIndexOf, FuncLength::THREE);
881     SetFrozenFunction(thread, prototype, "getLastIndexOf", ContainersBitVector::GetLastIndexOf, FuncLength::THREE);
882     SetFrozenFunction(thread, prototype, "flipBitByIndex", ContainersBitVector::FlipBitByIndex, FuncLength::ONE);
883     SetFrozenFunction(thread, prototype, "flipBitsByRange", ContainersBitVector::FlipBitsByRange, FuncLength::TWO);
884     SetFrozenFunction(thread, prototype, "values", ContainersBitVector::GetIteratorObj, FuncLength::ZERO);
885 
886     JSHandle<GlobalEnv> env = thread->GetEcmaVM()->GetGlobalEnv();
887     SetStringTagSymbol(thread, env, prototype, "BitVector");
888 
889     JSHandle<JSTaggedValue> lengthGetter =
890         CreateGetter(thread, ContainersBitVector::GetSize, "length", FuncLength::ZERO);
891     JSHandle<JSTaggedValue> lengthKey(thread, globalConst->GetLengthString());
892     SetGetter(thread, prototype, lengthKey, lengthGetter);
893 
894     SetFunctionAtSymbol(thread, env, prototype, env->GetIteratorSymbol(), "[Symbol.iterator]",
895                         ContainersBitVector::GetIteratorObj, FuncLength::ONE);
896     ContainersPrivate::InitializeBitVectorIterator(thread, env, globalConst);
897 
898     globalConst->SetConstant(ConstantIndex::BITVECTOR_FUNCTION_INDEX, bitVectorFunction.GetTaggedValue());
899     return bitVectorFunction;
900 }
901 
InitializeBitVectorIterator( JSThread* thread, const JSHandle<GlobalEnv>& env, GlobalEnvConstants* globalConst)902 void ContainersPrivate::InitializeBitVectorIterator(
903     JSThread* thread, const JSHandle<GlobalEnv>& env, GlobalEnvConstants* globalConst)
904 {
905     ObjectFactory* factory = thread->GetEcmaVM()->GetFactory();
906     JSHandle<JSHClass> iteratorFuncHClass =
907         JSHandle<JSHClass>(thread, globalConst->GetHandledJSAPIIteratorFuncHClass().GetObject<JSHClass>());
908     // BitVectorIterator.prototype
909     JSHandle<JSObject> bitVectorIteratorPrototype(factory->NewJSObject(iteratorFuncHClass));
910     // Iterator.prototype.next()
911     SetFrozenFunction(thread, bitVectorIteratorPrototype, "next", JSAPIBitVectorIterator::Next, FuncLength::ONE);
912     SetStringTagSymbol(thread, env, bitVectorIteratorPrototype, "BitVector Iterator");
913     globalConst->SetConstant(
914         ConstantIndex::BITVECTOR_ITERATOR_PROTOTYPE_INDEX, bitVectorIteratorPrototype.GetTaggedValue());
915 }
916 
InitializeQueue(JSThread *thread)917 JSHandle<JSTaggedValue> ContainersPrivate::InitializeQueue(JSThread *thread)
918 {
919     auto globalConst = const_cast<GlobalEnvConstants *>(thread->GlobalConstants());
920     ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
921     // Queue.prototype
922     JSHandle<JSObject> queueFuncPrototype = factory->NewEmptyJSObject();
923     JSHandle<JSTaggedValue> queueFuncPrototypeValue(queueFuncPrototype);
924     // Queue.prototype_or_hclass
925     JSHandle<JSHClass> queueInstanceClass =
926         factory->NewEcmaHClass(JSAPIQueue::SIZE, JSType::JS_API_QUEUE, queueFuncPrototypeValue);
927     // Queue() = new Function()
928     JSHandle<JSTaggedValue> queueFunction(NewContainerConstructor(
929         thread, queueFuncPrototype, ContainersQueue::QueueConstructor, "Queue", FuncLength::ZERO));
930     JSFunction::SetFunctionPrototypeOrInstanceHClass(thread,
931         JSHandle<JSFunction>::Cast(queueFunction), queueInstanceClass.GetTaggedValue());
932 
933     // "constructor" property on the prototype
934     JSHandle<JSTaggedValue> constructorKey = globalConst->GetHandledConstructorString();
935     JSObject::SetProperty(thread, JSHandle<JSTaggedValue>(queueFuncPrototype), constructorKey, queueFunction);
936     RETURN_HANDLE_IF_ABRUPT_COMPLETION(JSTaggedValue, thread);
937     // Queue.prototype.add()
938     SetFrozenFunction(thread, queueFuncPrototype, "add", ContainersQueue::Add, FuncLength::ONE);
939     SetFrozenFunction(thread, queueFuncPrototype, "getFirst", ContainersQueue::GetFirst, FuncLength::ZERO);
940     SetFrozenFunction(thread, queueFuncPrototype, "pop", ContainersQueue::Pop, FuncLength::ZERO);
941     SetFrozenFunction(thread, queueFuncPrototype, "forEach", ContainersQueue::ForEach, FuncLength::TWO,
942                       BUILTINS_STUB_ID(QueueForEach));
943 
944     JSHandle<GlobalEnv> env = thread->GetEcmaVM()->GetGlobalEnv();
945     SetStringTagSymbol(thread, env, queueFuncPrototype, "Queue");
946 
947     JSHandle<JSTaggedValue> lengthGetter = CreateGetter(thread, ContainersQueue::GetSize, "length", FuncLength::ZERO);
948     JSHandle<JSTaggedValue> lengthKey(thread, globalConst->GetLengthString());
949     SetGetter(thread, queueFuncPrototype, lengthKey, lengthGetter);
950 
951     SetFunctionAtSymbol(thread, env, queueFuncPrototype, env->GetIteratorSymbol(), "[Symbol.iterator]",
952                         ContainersQueue::GetIteratorObj, FuncLength::ONE);
953 
954     ContainersPrivate::InitializeQueueIterator(thread, env, globalConst);
955     return queueFunction;
956 }
957 
InitializeQueueIterator(JSThread *thread, const JSHandle<GlobalEnv> &env, GlobalEnvConstants *globalConst)958 void ContainersPrivate::InitializeQueueIterator(JSThread *thread, const JSHandle<GlobalEnv> &env,
959                                                 GlobalEnvConstants *globalConst)
960 {
961     ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
962     JSHandle<JSHClass> iteratorFuncHClass =
963         factory->NewEcmaHClass(JSObject::SIZE, JSType::JS_ITERATOR, env->GetIteratorPrototype());
964     // QueueIterator.prototype
965     JSHandle<JSObject> queueIteratorPrototype(factory->NewJSObject(iteratorFuncHClass));
966     // Iterator.prototype.next()
967     SetFrozenFunction(thread, queueIteratorPrototype, "next", JSAPIQueueIterator::Next, FuncLength::ONE);
968     SetStringTagSymbol(thread, env, queueIteratorPrototype, "Queue Iterator");
969     globalConst->SetConstant(ConstantIndex::QUEUE_ITERATOR_PROTOTYPE_INDEX, queueIteratorPrototype.GetTaggedValue());
970 }
971 
InitializeDeque(JSThread *thread)972 JSHandle<JSTaggedValue> ContainersPrivate::InitializeDeque(JSThread *thread)
973 {
974     auto globalConst = const_cast<GlobalEnvConstants *>(thread->GlobalConstants());
975     ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
976     // Deque.prototype
977     JSHandle<JSObject> dequeFuncPrototype = factory->NewEmptyJSObject();
978     JSHandle<JSTaggedValue> dequeFuncPrototypeValue(dequeFuncPrototype);
979     // Deque.prototype_or_hclass
980     JSHandle<JSHClass> dequeInstanceClass =
981         factory->NewEcmaHClass(JSAPIDeque::SIZE, JSType::JS_API_DEQUE, dequeFuncPrototypeValue);
982     // Deque() = new Function()
983     JSHandle<JSTaggedValue> dequeFunction(NewContainerConstructor(
984         thread, dequeFuncPrototype, ContainersDeque::DequeConstructor, "Deque", FuncLength::ZERO));
985     JSFunction::SetFunctionPrototypeOrInstanceHClass(thread,
986         JSHandle<JSFunction>::Cast(dequeFunction), dequeInstanceClass.GetTaggedValue());
987 
988     // "constructor" property on the prototype
989     JSHandle<JSTaggedValue> constructorKey = globalConst->GetHandledConstructorString();
990     JSObject::SetProperty(thread, JSHandle<JSTaggedValue>(dequeFuncPrototype), constructorKey, dequeFunction);
991     RETURN_HANDLE_IF_ABRUPT_COMPLETION(JSTaggedValue, thread);
992     SetFrozenFunction(thread, dequeFuncPrototype, "insertFront", ContainersDeque::InsertFront, FuncLength::ONE);
993     SetFrozenFunction(thread, dequeFuncPrototype, "insertEnd", ContainersDeque::InsertEnd, FuncLength::ONE);
994     SetFrozenFunction(thread, dequeFuncPrototype, "getFirst", ContainersDeque::GetFirst, FuncLength::ZERO);
995     SetFrozenFunction(thread, dequeFuncPrototype, "getLast", ContainersDeque::GetLast, FuncLength::ZERO);
996     SetFrozenFunction(thread, dequeFuncPrototype, "has", ContainersDeque::Has, FuncLength::ONE);
997     SetFrozenFunction(thread, dequeFuncPrototype, "popFirst", ContainersDeque::PopFirst, FuncLength::ZERO);
998     SetFrozenFunction(thread, dequeFuncPrototype, "popLast", ContainersDeque::PopLast, FuncLength::ZERO);
999     SetFrozenFunction(thread, dequeFuncPrototype, "forEach", ContainersDeque::ForEach, FuncLength::TWO,
1000                       BUILTINS_STUB_ID(DequeForEach));
1001 
1002     JSHandle<GlobalEnv> env = thread->GetEcmaVM()->GetGlobalEnv();
1003     SetStringTagSymbol(thread, env, dequeFuncPrototype, "Deque");
1004 
1005     JSHandle<JSTaggedValue> lengthGetter = CreateGetter(thread, ContainersDeque::GetSize, "length", FuncLength::ZERO);
1006     JSHandle<JSTaggedValue> lengthKey = globalConst->GetHandledLengthString();
1007     SetGetter(thread, dequeFuncPrototype, lengthKey, lengthGetter);
1008 
1009     SetFunctionAtSymbol(thread, env, dequeFuncPrototype, env->GetIteratorSymbol(), "[Symbol.iterator]",
1010                         ContainersDeque::GetIteratorObj, FuncLength::ONE);
1011 
1012     ContainersPrivate::InitializeDequeIterator(thread, env, globalConst);
1013 
1014     return dequeFunction;
1015 }
1016 
InitializeDequeIterator(JSThread *thread, const JSHandle<GlobalEnv> &env, GlobalEnvConstants *globalConst)1017 void ContainersPrivate::InitializeDequeIterator(JSThread *thread, const JSHandle<GlobalEnv> &env,
1018                                                 GlobalEnvConstants *globalConst)
1019 {
1020     ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
1021     JSHandle<JSHClass> iteratorFuncHClass = JSHandle<JSHClass>(thread, globalConst->
1022                         GetHandledJSAPIIteratorFuncHClass().GetObject<JSHClass>());
1023     JSHandle<JSObject> dequeIteratorPrototype(factory->NewJSObject(iteratorFuncHClass));
1024     SetFrozenFunction(thread, dequeIteratorPrototype, "next", JSAPIDequeIterator::Next, FuncLength::ONE);
1025     SetStringTagSymbol(thread, env, dequeIteratorPrototype, "Deque Iterator");
1026     globalConst->SetConstant(ConstantIndex::DEQUE_ITERATOR_PROTOTYPE_INDEX, dequeIteratorPrototype.GetTaggedValue());
1027 }
1028 
InitializeList(JSThread *thread)1029 JSHandle<JSTaggedValue> ContainersPrivate::InitializeList(JSThread *thread)
1030 {
1031     auto globalConst = const_cast<GlobalEnvConstants *>(thread->GlobalConstants());
1032     ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
1033     JSHandle<JSObject> listFuncPrototype = factory->NewEmptyJSObject();
1034     JSHandle<JSTaggedValue> listFuncPrototypeValue(listFuncPrototype);
1035     JSHandle<JSHClass> listInstanceClass =
1036         factory->NewEcmaHClass(JSAPIList::SIZE, JSType::JS_API_LIST, listFuncPrototypeValue);
1037     JSHandle<JSTaggedValue> listFunction(NewContainerConstructor(
1038         thread, listFuncPrototype, ContainersList::ListConstructor, "List", FuncLength::ZERO));
1039     JSFunction::SetFunctionPrototypeOrInstanceHClass(thread,
1040         JSHandle<JSFunction>::Cast(listFunction), listInstanceClass.GetTaggedValue());
1041 
1042     JSHandle<JSTaggedValue> constructorKey = globalConst->GetHandledConstructorString();
1043     JSObject::SetProperty(thread, JSHandle<JSTaggedValue>(listFuncPrototype), constructorKey, listFunction);
1044     RETURN_HANDLE_IF_ABRUPT_COMPLETION(JSTaggedValue, thread);
1045     SetFrozenFunction(thread, listFuncPrototype, "add", ContainersList::Add, FuncLength::ONE);
1046     SetFrozenFunction(thread, listFuncPrototype, "getFirst", ContainersList::GetFirst, FuncLength::ONE);
1047     SetFrozenFunction(thread, listFuncPrototype, "getLast", ContainersList::GetLast, FuncLength::ONE);
1048     SetFrozenFunction(thread, listFuncPrototype, "insert", ContainersList::Insert, FuncLength::ONE);
1049     SetFrozenFunction(thread, listFuncPrototype, "clear", ContainersList::Clear, FuncLength::ONE);
1050     SetFrozenFunction(thread, listFuncPrototype, "removeByIndex", ContainersList::RemoveByIndex, FuncLength::ONE);
1051     SetFrozenFunction(thread, listFuncPrototype, "remove", ContainersList::Remove, FuncLength::ONE);
1052     SetFrozenFunction(thread, listFuncPrototype, "has", ContainersList::Has, FuncLength::ONE);
1053     SetFrozenFunction(thread, listFuncPrototype, "isEmpty", ContainersList::IsEmpty, FuncLength::ONE);
1054     SetFrozenFunction(thread, listFuncPrototype, "get", ContainersList::Get, FuncLength::ONE);
1055     SetFrozenFunction(thread, listFuncPrototype, "getIndexOf", ContainersList::GetIndexOf, FuncLength::ONE);
1056     SetFrozenFunction(thread, listFuncPrototype, "getLastIndexOf", ContainersList::GetLastIndexOf, FuncLength::ONE);
1057     SetFrozenFunction(thread, listFuncPrototype, "set", ContainersList::Set, FuncLength::ONE);
1058     SetFrozenFunction(thread, listFuncPrototype, "forEach", ContainersList::ForEach, FuncLength::ONE,
1059                       BUILTINS_STUB_ID(ListForEach));
1060     SetFrozenFunction(thread, listFuncPrototype, "replaceAllElements", ContainersList::ReplaceAllElements,
1061                       FuncLength::ONE);
1062     SetFrozenFunction(thread, listFuncPrototype, "equal", ContainersList::Equal, FuncLength::ONE);
1063     SetFrozenFunction(thread, listFuncPrototype, "sort", ContainersList::Sort, FuncLength::ONE);
1064     SetFrozenFunction(thread, listFuncPrototype, "convertToArray", ContainersList::ConvertToArray, FuncLength::ONE);
1065     SetFrozenFunction(thread, listFuncPrototype, "getSubList", ContainersList::GetSubList, FuncLength::ONE);
1066 
1067     JSHandle<JSTaggedValue> lengthGetter = CreateGetter(thread, ContainersList::Length, "length", FuncLength::ZERO);
1068     JSHandle<JSTaggedValue> lengthKey(factory->NewFromASCII("length"));
1069     SetGetter(thread, listFuncPrototype, lengthKey, lengthGetter);
1070 
1071     JSHandle<GlobalEnv> env = thread->GetEcmaVM()->GetGlobalEnv();
1072     SetFunctionAtSymbol(thread, env, listFuncPrototype, env->GetIteratorSymbol(), "[Symbol.iterator]",
1073                         ContainersList::GetIteratorObj, FuncLength::ONE);
1074 
1075     InitializeListIterator(thread, env);
1076     globalConst->SetConstant(ConstantIndex::LIST_FUNCTION_INDEX, listFunction.GetTaggedValue());
1077     return listFunction;
1078 }
1079 
InitializeLinkedList(JSThread *thread)1080 JSHandle<JSTaggedValue> ContainersPrivate::InitializeLinkedList(JSThread *thread)
1081 {
1082     auto globalConst = const_cast<GlobalEnvConstants *>(thread->GlobalConstants());
1083     ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
1084     JSHandle<JSObject> linkedListFuncPrototype = factory->NewEmptyJSObject();
1085     JSHandle<JSTaggedValue> linkedListFuncPrototypeValue(linkedListFuncPrototype);
1086     JSHandle<JSHClass> linkedListInstanceClass =
1087         factory->NewEcmaHClass(JSAPILinkedList::SIZE, JSType::JS_API_LINKED_LIST, linkedListFuncPrototypeValue);
1088     JSHandle<JSTaggedValue> linkedListFunction(NewContainerConstructor(
1089         thread, linkedListFuncPrototype, ContainersLinkedList::LinkedListConstructor, "LinkedList", FuncLength::ZERO));
1090     JSFunction::SetFunctionPrototypeOrInstanceHClass(thread,
1091         JSHandle<JSFunction>::Cast(linkedListFunction), linkedListInstanceClass.GetTaggedValue());
1092 
1093     JSHandle<JSTaggedValue> constructorKey = globalConst->GetHandledConstructorString();
1094     JSObject::SetProperty(thread, JSHandle<JSTaggedValue>(linkedListFuncPrototype), constructorKey, linkedListFunction);
1095     RETURN_HANDLE_IF_ABRUPT_COMPLETION(JSTaggedValue, thread);
1096     SetFrozenFunction(thread, linkedListFuncPrototype, "add", ContainersLinkedList::Add, FuncLength::ONE);
1097     SetFrozenFunction(thread, linkedListFuncPrototype, "insert", ContainersLinkedList::Insert, FuncLength::ONE);
1098     SetFrozenFunction(thread, linkedListFuncPrototype, "clear", ContainersLinkedList::Clear, FuncLength::ONE);
1099     SetFrozenFunction(thread, linkedListFuncPrototype, "clone", ContainersLinkedList::Clone, FuncLength::ONE);
1100     SetFrozenFunction(thread, linkedListFuncPrototype, "removeFirst", ContainersLinkedList::RemoveFirst,
1101                       FuncLength::ONE);
1102     SetFrozenFunction(thread, linkedListFuncPrototype, "removeLast", ContainersLinkedList::RemoveLast, FuncLength::ONE);
1103     SetFrozenFunction(thread, linkedListFuncPrototype, "removeFirstFound", ContainersLinkedList::RemoveFirstFound,
1104                       FuncLength::ONE);
1105     SetFrozenFunction(thread, linkedListFuncPrototype, "removeByIndex", ContainersLinkedList::RemoveByIndex,
1106                       FuncLength::ONE);
1107     SetFrozenFunction(thread, linkedListFuncPrototype, "remove", ContainersLinkedList::Remove, FuncLength::ONE);
1108     SetFrozenFunction(thread, linkedListFuncPrototype, "removeLastFound", ContainersLinkedList::RemoveLastFound,
1109                       FuncLength::ONE);
1110     SetFrozenFunction(thread, linkedListFuncPrototype, "has", ContainersLinkedList::Has, FuncLength::ONE);
1111     SetFrozenFunction(thread, linkedListFuncPrototype, "get", ContainersLinkedList::Get, FuncLength::ONE);
1112     SetFrozenFunction(thread, linkedListFuncPrototype, "addFirst", ContainersLinkedList::AddFirst, FuncLength::ONE);
1113     SetFrozenFunction(thread, linkedListFuncPrototype, "getFirst", ContainersLinkedList::GetFirst, FuncLength::ONE);
1114     SetFrozenFunction(thread, linkedListFuncPrototype, "getLast", ContainersLinkedList::GetLast, FuncLength::ONE);
1115     SetFrozenFunction(thread, linkedListFuncPrototype, "getIndexOf", ContainersLinkedList::GetIndexOf, FuncLength::ONE);
1116     SetFrozenFunction(thread, linkedListFuncPrototype, "getLastIndexOf", ContainersLinkedList::GetLastIndexOf,
1117                       FuncLength::ONE);
1118     SetFrozenFunction(thread, linkedListFuncPrototype, "convertToArray", ContainersLinkedList::ConvertToArray,
1119                       FuncLength::ONE);
1120     SetFrozenFunction(thread, linkedListFuncPrototype, "set", ContainersLinkedList::Set, FuncLength::ONE);
1121     SetFrozenFunction(thread, linkedListFuncPrototype, "forEach", ContainersLinkedList::ForEach, FuncLength::ONE,
1122                       BUILTINS_STUB_ID(LinkedListForEach));
1123 
1124     JSHandle<JSTaggedValue> lengthGetter = CreateGetter(thread, ContainersLinkedList::Length, "length",
1125                                                         FuncLength::ZERO);
1126     JSHandle<JSTaggedValue> lengthKey(factory->NewFromASCII("length"));
1127     SetGetter(thread, linkedListFuncPrototype, lengthKey, lengthGetter);
1128 
1129     JSHandle<GlobalEnv> env = thread->GetEcmaVM()->GetGlobalEnv();
1130     SetFunctionAtSymbol(thread, env, linkedListFuncPrototype, env->GetIteratorSymbol(), "[Symbol.iterator]",
1131                         ContainersLinkedList::GetIteratorObj, FuncLength::ONE);
1132 
1133     InitializeLinkedListIterator(thread, env);
1134     globalConst->SetConstant(ConstantIndex::LINKED_LIST_FUNCTION_INDEX, linkedListFunction.GetTaggedValue());
1135     return linkedListFunction;
1136 }
1137 
InitializeLinkedListIterator(JSThread *thread, const JSHandle<GlobalEnv> &env)1138 void ContainersPrivate::InitializeLinkedListIterator(JSThread *thread, const JSHandle<GlobalEnv> &env)
1139 {
1140     auto globalConst = const_cast<GlobalEnvConstants *>(thread->GlobalConstants());
1141     ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
1142     JSHandle<JSHClass> iteratorClass =
1143         JSHandle<JSHClass>(thread, globalConst->GetHandledJSAPIIteratorFuncHClass().GetObject<JSHClass>());
1144     JSHandle<JSObject> setIteratorPrototype(factory->NewJSObject(iteratorClass));
1145     SetFrozenFunction(thread, setIteratorPrototype, "next", JSAPILinkedListIterator::Next, FuncLength::ONE);
1146     SetStringTagSymbol(thread, env, setIteratorPrototype, "linkedlist Iterator");
1147     globalConst->SetConstant(ConstantIndex::LINKED_LIST_ITERATOR_PROTOTYPE_INDEX,
1148         setIteratorPrototype.GetTaggedValue());
1149 }
1150 
InitializeListIterator(JSThread *thread, const JSHandle<GlobalEnv> &env)1151 void ContainersPrivate::InitializeListIterator(JSThread *thread, const JSHandle<GlobalEnv> &env)
1152 {
1153     auto globalConst = const_cast<GlobalEnvConstants *>(thread->GlobalConstants());
1154     ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
1155     JSHandle<JSHClass> iteratorClass =
1156         JSHandle<JSHClass>(thread, globalConst->GetHandledJSAPIIteratorFuncHClass().GetObject<JSHClass>());
1157     JSHandle<JSObject> setIteratorPrototype(factory->NewJSObject(iteratorClass));
1158     SetFrozenFunction(thread, setIteratorPrototype, "next", JSAPIListIterator::Next, FuncLength::ONE);
1159     SetStringTagSymbol(thread, env, setIteratorPrototype, "list Iterator");
1160     globalConst->SetConstant(ConstantIndex::LIST_ITERATOR_PROTOTYPE_INDEX, setIteratorPrototype.GetTaggedValue());
1161 }
1162 
InitializeHashMap(JSThread *thread)1163 JSHandle<JSTaggedValue> ContainersPrivate::InitializeHashMap(JSThread *thread)
1164 {
1165     const GlobalEnvConstants *globalConst = thread->GlobalConstants();
1166     ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
1167     // HashMap.prototype
1168     JSHandle<JSObject> hashMapFuncPrototype = factory->NewEmptyJSObject();
1169     JSHandle<JSTaggedValue> hashMapFuncPrototypeValue(hashMapFuncPrototype);
1170     // HashMap.prototype_or_hclass
1171     JSHandle<JSHClass> hashMapInstanceClass =
1172         factory->NewEcmaHClass(JSAPIHashMap::SIZE, JSType::JS_API_HASH_MAP, hashMapFuncPrototypeValue);
1173 
1174     JSHandle<JSTaggedValue> hashMapFunction(NewContainerConstructor(
1175         thread, hashMapFuncPrototype, ContainersHashMap::HashMapConstructor, "HashMap", FuncLength::ZERO));
1176     JSFunction::SetFunctionPrototypeOrInstanceHClass(thread,
1177         JSHandle<JSFunction>::Cast(hashMapFunction), hashMapInstanceClass.GetTaggedValue());
1178 
1179     // "constructor" property on the prototype
1180     JSHandle<JSTaggedValue> constructorKey = globalConst->GetHandledConstructorString();
1181     JSObject::SetProperty(thread, JSHandle<JSTaggedValue>(hashMapFuncPrototype), constructorKey, hashMapFunction);
1182     RETURN_HANDLE_IF_ABRUPT_COMPLETION(JSTaggedValue, thread);
1183     // HashMap.prototype.set()
1184     SetFrozenFunction(thread, hashMapFuncPrototype, "set", ContainersHashMap::Set, FuncLength::TWO);
1185      // HashMap.prototype.setall()
1186     SetFrozenFunction(thread, hashMapFuncPrototype, "setAll", ContainersHashMap::SetAll, FuncLength::ONE);
1187     // HashMap.prototype.isEmpty()
1188     SetFrozenFunction(thread, hashMapFuncPrototype, "isEmpty", ContainersHashMap::IsEmpty, FuncLength::ZERO);
1189     // HashMap.prototype.remove()
1190     SetFrozenFunction(thread, hashMapFuncPrototype, "remove", ContainersHashMap::Remove, FuncLength::ONE);
1191      // HashMap.prototype.clear()
1192     SetFrozenFunction(thread, hashMapFuncPrototype, "clear", ContainersHashMap::Clear, FuncLength::ZERO);
1193     // HashMap.prototype.get()
1194     SetFrozenFunction(thread, hashMapFuncPrototype, "get", ContainersHashMap::Get, FuncLength::ONE);
1195     // HashMap.prototype.forEach()
1196     SetFrozenFunction(thread, hashMapFuncPrototype, "forEach", ContainersHashMap::ForEach, FuncLength::TWO,
1197                       BUILTINS_STUB_ID(HashMapForEach));
1198     // HashMap.prototype.hasKey()
1199     SetFrozenFunction(thread, hashMapFuncPrototype, "hasKey", ContainersHashMap::HasKey, FuncLength::ONE);
1200      // HashMap.prototype.hasValue()
1201     SetFrozenFunction(thread, hashMapFuncPrototype, "hasValue", ContainersHashMap::HasValue, FuncLength::ONE);
1202      // HashMap.prototype.replace()
1203     SetFrozenFunction(thread, hashMapFuncPrototype, "replace", ContainersHashMap::Replace, FuncLength::TWO);
1204     // HashMap.prototype.keys()
1205     SetFrozenFunction(thread, hashMapFuncPrototype, "keys", ContainersHashMap::Keys, FuncLength::ZERO);
1206     // HashMap.prototype.Values()
1207     SetFrozenFunction(thread, hashMapFuncPrototype, "values", ContainersHashMap::Values, FuncLength::ZERO);
1208     // HashMap.prototype.keys()
1209     SetFrozenFunction(thread, hashMapFuncPrototype, "entries", ContainersHashMap::Entries, FuncLength::ZERO);
1210     JSHandle<GlobalEnv> env = thread->GetEcmaVM()->GetGlobalEnv();
1211     // @@ToStringTag
1212     SetStringTagSymbol(thread, env, hashMapFuncPrototype, "HashMap");
1213     // %HashMapPrototype% [ @@iterator ]
1214     SetFunctionAtSymbol(thread, env, hashMapFuncPrototype, env->GetIteratorSymbol(), "[Symbol.iterator]",
1215                         ContainersHashMap::GetIteratorObj, FuncLength::ONE);
1216 
1217     JSHandle<JSTaggedValue> lengthGetter =
1218         CreateGetter(thread, ContainersHashMap::GetLength, "length", FuncLength::ZERO);
1219     JSHandle<JSTaggedValue> lengthKey(thread, globalConst->GetLengthString());
1220     SetGetter(thread, hashMapFuncPrototype, lengthKey, lengthGetter);
1221     InitializeHashMapIterator(thread);
1222     return hashMapFunction;
1223 }
1224 
InitializeHashMapIterator(JSThread *thread)1225 void ContainersPrivate::InitializeHashMapIterator(JSThread *thread)
1226 {
1227     JSHandle<GlobalEnv> env = thread->GetEcmaVM()->GetGlobalEnv();
1228     auto globalConst = const_cast<GlobalEnvConstants *>(thread->GlobalConstants());
1229     ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
1230     JSHandle<JSHClass> iteratorFuncHClass =
1231         JSHandle<JSHClass>::Cast(globalConst->GetHandledJSAPIIteratorFuncHClass());
1232     // HashMapIterator.prototype
1233     JSHandle<JSObject> hashMapIteratorPrototype(factory->NewJSObject(iteratorFuncHClass));
1234     // HashMapIterator.prototype.next()
1235     SetFrozenFunction(thread, hashMapIteratorPrototype, "next", JSAPIHashMapIterator::Next, FuncLength::ZERO);
1236     SetStringTagSymbol(thread, env, hashMapIteratorPrototype, "HashMap Iterator");
1237 
1238     globalConst->SetConstant(ConstantIndex::HASHMAP_ITERATOR_PROTOTYPE_INDEX,
1239                              hashMapIteratorPrototype.GetTaggedValue());
1240 }
1241 
InitializeHashSet(JSThread *thread)1242 JSHandle<JSTaggedValue> ContainersPrivate::InitializeHashSet(JSThread *thread)
1243 {
1244     const GlobalEnvConstants *globalConst = thread->GlobalConstants();
1245     ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
1246     // HashSet.prototype
1247     JSHandle<JSObject> hashSetFuncPrototype = factory->NewEmptyJSObject();
1248     JSHandle<JSTaggedValue> hashSetFuncPrototypeValue(hashSetFuncPrototype);
1249     // HashSet.prototype_or_hclass
1250     JSHandle<JSHClass> hashSetInstanceClass =
1251         factory->NewEcmaHClass(JSAPIHashSet::SIZE, JSType::JS_API_HASH_SET, hashSetFuncPrototypeValue);
1252 
1253     JSHandle<JSTaggedValue> hashSetFunction(NewContainerConstructor(
1254         thread, hashSetFuncPrototype, ContainersHashSet::HashSetConstructor, "HashSet", FuncLength::ZERO));
1255     JSFunction::SetFunctionPrototypeOrInstanceHClass(thread,
1256         JSHandle<JSFunction>::Cast(hashSetFunction), hashSetInstanceClass.GetTaggedValue());
1257 
1258     // "constructor" property on the prototype
1259     JSHandle<JSTaggedValue> constructorKey = globalConst->GetHandledConstructorString();
1260     JSObject::SetProperty(thread, JSHandle<JSTaggedValue>(hashSetFuncPrototype), constructorKey, hashSetFunction);
1261     RETURN_HANDLE_IF_ABRUPT_COMPLETION(JSTaggedValue, thread);
1262     SetFrozenFunction(thread, hashSetFuncPrototype, "isEmpty", ContainersHashSet::IsEmpty, FuncLength::ZERO);
1263     SetFrozenFunction(thread, hashSetFuncPrototype, "has", ContainersHashSet::Has, FuncLength::ONE);
1264     SetFrozenFunction(thread, hashSetFuncPrototype, "add", ContainersHashSet::Add, FuncLength::ONE);
1265     SetFrozenFunction(thread, hashSetFuncPrototype, "has", ContainersHashSet::Has, FuncLength::ONE);
1266     SetFrozenFunction(thread, hashSetFuncPrototype, "remove", ContainersHashSet::Remove, FuncLength::ONE);
1267     SetFrozenFunction(thread, hashSetFuncPrototype, "clear", ContainersHashSet::Clear, FuncLength::ZERO);
1268     SetFrozenFunction(thread, hashSetFuncPrototype, "values", ContainersHashSet::Values, FuncLength::ZERO);
1269     SetFrozenFunction(thread, hashSetFuncPrototype, "entries", ContainersHashSet::Entries, FuncLength::ZERO);
1270     SetFrozenFunction(thread, hashSetFuncPrototype, "forEach", ContainersHashSet::ForEach, FuncLength::TWO,
1271                       BUILTINS_STUB_ID(HashSetForEach));
1272 
1273     JSHandle<GlobalEnv> env = thread->GetEcmaVM()->GetGlobalEnv();
1274     // @@ToStringTag
1275     SetStringTagSymbol(thread, env, hashSetFuncPrototype, "HashSet");
1276     // %HashSetPrototype% [ @@iterator ]
1277     SetFunctionAtSymbol(thread, env, hashSetFuncPrototype, env->GetIteratorSymbol(), "[Symbol.iterator]",
1278                         ContainersHashSet::GetIteratorObj, FuncLength::ONE);
1279 
1280     JSHandle<JSTaggedValue> lengthGetter =
1281         CreateGetter(thread, ContainersHashSet::GetLength, "length", FuncLength::ZERO);
1282     JSHandle<JSTaggedValue> lengthKey(thread, globalConst->GetLengthString());
1283     SetGetter(thread, hashSetFuncPrototype, lengthKey, lengthGetter);
1284     InitializeHashSetIterator(thread);
1285     return hashSetFunction;
1286 }
1287 
InitializeHashSetIterator(JSThread *thread)1288 void ContainersPrivate::InitializeHashSetIterator(JSThread *thread)
1289 {
1290     JSHandle<GlobalEnv> env = thread->GetEcmaVM()->GetGlobalEnv();
1291     auto globalConst = const_cast<GlobalEnvConstants *>(thread->GlobalConstants());
1292     ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
1293     JSHandle<JSHClass> iteratorFuncHClass =
1294         JSHandle<JSHClass>::Cast(globalConst->GetHandledJSAPIIteratorFuncHClass());
1295 
1296     // HashSetIterator.prototype
1297     JSHandle<JSObject> hashSetIteratorPrototype(factory->NewJSObject(iteratorFuncHClass));
1298     // HashSetIterator.prototype.next()
1299     SetFrozenFunction(thread, hashSetIteratorPrototype, "next", JSAPIHashSetIterator::Next, FuncLength::ZERO);
1300     SetStringTagSymbol(thread, env, hashSetIteratorPrototype, "HashSet Iterator");
1301     globalConst->SetConstant(ConstantIndex::HASHSET_ITERATOR_PROTOTYPE_INDEX,
1302                              hashSetIteratorPrototype.GetTaggedValue());
1303 }
1304 }  // namespace panda::ecmascript::containers
1305