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