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