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 LOG_ECMA(FATAL) << "this branch is unreachable";
148 UNREACHABLE();
149 }
150
151 return res;
152 }
153
InitializeContainer(JSThread * thread,const JSHandle<JSObject> & obj,InitializeFunction func,const char * name)154 JSTaggedValue ContainersPrivate::InitializeContainer(JSThread *thread, const JSHandle<JSObject> &obj,
155 InitializeFunction func, const char *name)
156 {
157 ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
158 JSHandle<JSTaggedValue> key(factory->NewFromASCII(name));
159 JSTaggedValue value = ObjectFastOperator::GetPropertyByName<ObjectFastOperator::Status::UseOwn>
160 (thread, obj.GetTaggedValue(), key.GetTaggedValue());
161 if (!value.IsUndefined()) {
162 return value;
163 }
164 JSHandle<JSTaggedValue> map = func(thread);
165 SetFrozenConstructor(thread, obj, name, map);
166 return map.GetTaggedValue();
167 }
168
NewContainerConstructor(JSThread * thread,const JSHandle<JSObject> & prototype,EcmaEntrypoint ctorFunc,const char * name,int length)169 JSHandle<JSFunction> ContainersPrivate::NewContainerConstructor(JSThread *thread, const JSHandle<JSObject> &prototype,
170 EcmaEntrypoint ctorFunc, const char *name, int length)
171 {
172 JSHandle<GlobalEnv> env = thread->GetEcmaVM()->GetGlobalEnv();
173 ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
174 JSHandle<JSFunction> ctor =
175 factory->NewJSFunction(env, reinterpret_cast<void *>(ctorFunc), FunctionKind::BUILTIN_CONSTRUCTOR);
176
177 const GlobalEnvConstants *globalConst = thread->GlobalConstants();
178 JSFunction::SetFunctionLength(thread, ctor, JSTaggedValue(length));
179 JSHandle<JSTaggedValue> nameString(factory->NewFromASCII(name));
180 JSFunction::SetFunctionName(thread, JSHandle<JSFunctionBase>(ctor), nameString,
181 globalConst->GetHandledUndefined());
182 JSHandle<JSTaggedValue> constructorKey = globalConst->GetHandledConstructorString();
183 PropertyDescriptor descriptor1(thread, JSHandle<JSTaggedValue>::Cast(ctor), true, false, true);
184 JSObject::DefineOwnProperty(thread, prototype, constructorKey, descriptor1);
185
186 /* set "prototype" in constructor */
187 JSFunction::SetFunctionPrototypeOrInstanceHClass(thread, ctor, prototype.GetTaggedValue());
188
189 return ctor;
190 }
191
SetFrozenFunction(JSThread * thread,const JSHandle<JSObject> & obj,const char * key,EcmaEntrypoint func,int length,kungfu::BuiltinsStubCSigns::ID builtinId)192 void ContainersPrivate::SetFrozenFunction(JSThread *thread, const JSHandle<JSObject> &obj, const char *key,
193 EcmaEntrypoint func, int length, kungfu::BuiltinsStubCSigns::ID builtinId)
194 {
195 ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
196 JSHandle<JSTaggedValue> keyString(factory->NewFromASCII(key));
197 JSHandle<JSFunction> function = NewFunction(thread, keyString, func, length, builtinId);
198 PropertyDescriptor descriptor(thread, JSHandle<JSTaggedValue>(function), false, false, false);
199 JSObject::DefineOwnProperty(thread, obj, keyString, descriptor);
200 }
201
SetFrozenConstructor(JSThread * thread,const JSHandle<JSObject> & obj,const char * keyChar,JSHandle<JSTaggedValue> & value)202 void ContainersPrivate::SetFrozenConstructor(JSThread *thread, const JSHandle<JSObject> &obj, const char *keyChar,
203 JSHandle<JSTaggedValue> &value)
204 {
205 JSObject::PreventExtensions(thread, JSHandle<JSObject>::Cast(value));
206 ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
207 JSHandle<JSTaggedValue> key(factory->NewFromASCII(keyChar));
208 PropertyDescriptor descriptor(thread, value, false, false, false);
209 JSObject::DefineOwnProperty(thread, obj, key, descriptor);
210 }
211
NewFunction(JSThread * thread,const JSHandle<JSTaggedValue> & key,EcmaEntrypoint func,int length,kungfu::BuiltinsStubCSigns::ID builtinId)212 JSHandle<JSFunction> ContainersPrivate::NewFunction(JSThread *thread, const JSHandle<JSTaggedValue> &key,
213 EcmaEntrypoint func, int length,
214 kungfu::BuiltinsStubCSigns::ID builtinId)
215 {
216 ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
217 JSHandle<JSFunction> function =
218 factory->NewJSFunction(thread->GetEcmaVM()->GetGlobalEnv(), reinterpret_cast<void *>(func),
219 FunctionKind::NORMAL_FUNCTION, builtinId);
220 JSFunction::SetFunctionLength(thread, function, JSTaggedValue(length));
221 JSHandle<JSFunctionBase> baseFunction(function);
222 JSFunction::SetFunctionName(thread, baseFunction, key, thread->GlobalConstants()->GetHandledUndefined());
223 return function;
224 }
225
CreateGetter(JSThread * thread,EcmaEntrypoint func,const char * name,int length)226 JSHandle<JSTaggedValue> ContainersPrivate::CreateGetter(JSThread *thread, EcmaEntrypoint func, const char *name,
227 int length)
228 {
229 JSHandle<GlobalEnv> env = thread->GetEcmaVM()->GetGlobalEnv();
230 ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
231 JSHandle<JSFunction> function = factory->NewJSFunction(env, reinterpret_cast<void *>(func));
232 JSFunction::SetFunctionLength(thread, function, JSTaggedValue(length));
233 JSHandle<JSTaggedValue> funcName(factory->NewFromASCII(name));
234 JSHandle<JSTaggedValue> prefix = thread->GlobalConstants()->GetHandledGetString();
235 JSFunction::SetFunctionName(thread, JSHandle<JSFunctionBase>(function), funcName, prefix);
236 return JSHandle<JSTaggedValue>(function);
237 }
238
SetGetter(JSThread * thread,const JSHandle<JSObject> & obj,const JSHandle<JSTaggedValue> & key,const JSHandle<JSTaggedValue> & getter)239 void ContainersPrivate::SetGetter(JSThread *thread, const JSHandle<JSObject> &obj, const JSHandle<JSTaggedValue> &key,
240 const JSHandle<JSTaggedValue> &getter)
241 {
242 ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
243 JSHandle<AccessorData> accessor = factory->NewAccessorData();
244 accessor->SetGetter(thread, getter);
245 PropertyAttributes attr = PropertyAttributes::DefaultAccessor(false, false, false);
246 JSObject::AddAccessor(thread, JSHandle<JSTaggedValue>::Cast(obj), key, accessor, attr);
247 }
248
SetFunctionAtSymbol(JSThread * thread,const JSHandle<GlobalEnv> & env,const JSHandle<JSObject> & obj,const JSHandle<JSTaggedValue> & symbol,const char * name,EcmaEntrypoint func,int length)249 void ContainersPrivate::SetFunctionAtSymbol(JSThread *thread, const JSHandle<GlobalEnv> &env,
250 const JSHandle<JSObject> &obj, const JSHandle<JSTaggedValue> &symbol,
251 const char *name, EcmaEntrypoint func, int length)
252 {
253 ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
254 JSHandle<JSFunction> function = factory->NewJSFunction(env, reinterpret_cast<void *>(func));
255 JSFunction::SetFunctionLength(thread, function, JSTaggedValue(length));
256 JSHandle<JSTaggedValue> nameString(factory->NewFromASCII(name));
257 JSHandle<JSFunctionBase> baseFunction(function);
258 JSFunction::SetFunctionName(thread, baseFunction, nameString, thread->GlobalConstants()->GetHandledUndefined());
259 PropertyDescriptor descriptor(thread, JSHandle<JSTaggedValue>::Cast(function), false, false, false);
260 JSObject::DefineOwnProperty(thread, obj, symbol, descriptor);
261 }
262
SetStringTagSymbol(JSThread * thread,const JSHandle<GlobalEnv> & env,const JSHandle<JSObject> & obj,const char * key)263 void ContainersPrivate::SetStringTagSymbol(JSThread *thread, const JSHandle<GlobalEnv> &env,
264 const JSHandle<JSObject> &obj, const char *key)
265 {
266 ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
267 JSHandle<JSTaggedValue> tag(factory->NewFromASCII(key));
268 JSHandle<JSTaggedValue> symbol = env->GetToStringTagSymbol();
269 PropertyDescriptor desc(thread, tag, false, false, false);
270 JSObject::DefineOwnProperty(thread, obj, symbol, desc);
271 }
272
InitializeArrayList(JSThread * thread)273 JSHandle<JSTaggedValue> ContainersPrivate::InitializeArrayList(JSThread *thread)
274 {
275 auto globalConst = const_cast<GlobalEnvConstants *>(thread->GlobalConstants());
276 ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
277 // ArrayList.prototype
278 JSHandle<JSObject> prototype = factory->NewEmptyJSObject();
279 JSHandle<JSTaggedValue> arrayListFuncPrototypeValue(prototype);
280 // ArrayList.prototype_or_hclass
281 JSHandle<JSHClass> arrayListInstanceClass =
282 factory->NewEcmaHClass(JSAPIArrayList::SIZE, JSType::JS_API_ARRAY_LIST, arrayListFuncPrototypeValue);
283 // ArrayList() = new Function()
284 JSHandle<JSTaggedValue> arrayListFunction(NewContainerConstructor(
285 thread, prototype, ContainersArrayList::ArrayListConstructor, "ArrayList", FuncLength::ZERO));
286 JSFunction::SetFunctionPrototypeOrInstanceHClass(thread,
287 JSHandle<JSFunction>::Cast(arrayListFunction), arrayListInstanceClass.GetTaggedValue());
288
289 // "constructor" property on the prototype
290 JSHandle<JSTaggedValue> constructorKey = globalConst->GetHandledConstructorString();
291 JSObject::SetProperty(thread, JSHandle<JSTaggedValue>(prototype), constructorKey, arrayListFunction);
292
293 // ArrayList.prototype
294 SetFrozenFunction(thread, prototype, "add", ContainersArrayList::Add, FuncLength::ONE);
295 SetFrozenFunction(thread, prototype, "insert", ContainersArrayList::Insert, FuncLength::TWO);
296 SetFrozenFunction(thread, prototype, "clear", ContainersArrayList::Clear, FuncLength::ZERO);
297 SetFrozenFunction(thread, prototype, "clone", ContainersArrayList::Clone, FuncLength::ZERO);
298 SetFrozenFunction(thread, prototype, "has", ContainersArrayList::Has, FuncLength::ONE);
299 SetFrozenFunction(thread, prototype, "getCapacity", ContainersArrayList::GetCapacity, FuncLength::ZERO);
300 SetFrozenFunction(thread, prototype, "increaseCapacityTo",
301 ContainersArrayList::IncreaseCapacityTo, FuncLength::ONE);
302 SetFrozenFunction(thread, prototype, "trimToCurrentLength",
303 ContainersArrayList::TrimToCurrentLength, FuncLength::ZERO);
304 SetFrozenFunction(thread, prototype, "getIndexOf", ContainersArrayList::GetIndexOf, FuncLength::ONE);
305 SetFrozenFunction(thread, prototype, "isEmpty", ContainersArrayList::IsEmpty, FuncLength::ZERO);
306 SetFrozenFunction(thread, prototype, "getLastIndexOf", ContainersArrayList::GetLastIndexOf, FuncLength::ONE);
307 SetFrozenFunction(thread, prototype, "removeByIndex", ContainersArrayList::RemoveByIndex, FuncLength::ONE);
308 SetFrozenFunction(thread, prototype, "remove", ContainersArrayList::Remove, FuncLength::ONE);
309 SetFrozenFunction(thread, prototype, "removeByRange", ContainersArrayList::RemoveByRange, FuncLength::TWO);
310 SetFrozenFunction(thread, prototype, "replaceAllElements", ContainersArrayList::ReplaceAllElements,
311 FuncLength::TWO, BUILTINS_STUB_ID(ArrayListReplaceAllElements));
312 SetFrozenFunction(thread, prototype, "sort", ContainersArrayList::Sort, FuncLength::ONE);
313 SetFrozenFunction(thread, prototype, "subArrayList", ContainersArrayList::SubArrayList, FuncLength::TWO);
314 SetFrozenFunction(thread, prototype, "convertToArray", ContainersArrayList::ConvertToArray, FuncLength::ZERO);
315 SetFrozenFunction(thread, prototype, "forEach", ContainersArrayList::ForEach, FuncLength::TWO,
316 BUILTINS_STUB_ID(ArrayListForEach));
317
318 JSHandle<GlobalEnv> env = thread->GetEcmaVM()->GetGlobalEnv();
319 SetStringTagSymbol(thread, env, prototype, "ArrayList");
320
321 JSHandle<JSTaggedValue> lengthGetter = CreateGetter(thread, ContainersArrayList::GetSize, "length",
322 FuncLength::ZERO);
323 JSHandle<JSTaggedValue> lengthKey(thread, globalConst->GetLengthString());
324 SetGetter(thread, prototype, lengthKey, lengthGetter);
325
326 SetFunctionAtSymbol(thread, env, prototype, env->GetIteratorSymbol(), "[Symbol.iterator]",
327 ContainersArrayList::GetIteratorObj, FuncLength::ONE);
328 ContainersPrivate::InitializeArrayListIterator(thread, env, globalConst);
329 globalConst->SetConstant(ConstantIndex::ARRAYLIST_FUNCTION_INDEX, arrayListFunction.GetTaggedValue());
330 return arrayListFunction;
331 }
332
InitializeArrayListIterator(JSThread * thread,const JSHandle<GlobalEnv> & env,GlobalEnvConstants * globalConst)333 void ContainersPrivate::InitializeArrayListIterator(JSThread *thread, const JSHandle<GlobalEnv> &env,
334 GlobalEnvConstants *globalConst)
335 {
336 ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
337 // Iterator.hclass
338 JSHandle<JSHClass> iteratorFuncHClass =
339 factory->NewEcmaHClass(JSObject::SIZE, JSType::JS_ITERATOR, env->GetIteratorPrototype());
340 // ArrayListIterator.prototype
341 JSHandle<JSObject> arrayListIteratorPrototype(factory->NewJSObject(iteratorFuncHClass));
342 // Iterator.prototype.next()
343 SetFrozenFunction(thread, arrayListIteratorPrototype, "next", JSAPIArrayListIterator::Next, FuncLength::ONE);
344 SetStringTagSymbol(thread, env, arrayListIteratorPrototype, "ArrayList Iterator");
345 globalConst->SetConstant(ConstantIndex::ARRAYLIST_ITERATOR_PROTOTYPE_INDEX,
346 arrayListIteratorPrototype.GetTaggedValue());
347 }
348
InitializeLightWeightMap(JSThread * thread)349 JSHandle<JSTaggedValue> ContainersPrivate::InitializeLightWeightMap(JSThread *thread)
350 {
351 const GlobalEnvConstants *globalConst = thread->GlobalConstants();
352 ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
353 JSHandle<JSObject> funcPrototype = factory->NewEmptyJSObject();
354 JSHandle<JSTaggedValue> mapFuncPrototypeValue(funcPrototype);
355 JSHandle<JSHClass> lightWeightMapInstanceClass =
356 factory->NewEcmaHClass(JSAPILightWeightMap::SIZE, JSType::JS_API_LIGHT_WEIGHT_MAP, mapFuncPrototypeValue);
357 JSHandle<JSTaggedValue> lightWeightMapFunction(NewContainerConstructor(
358 thread, funcPrototype, ContainersLightWeightMap::LightWeightMapConstructor, "LightWeightMap",
359 FuncLength::ZERO));
360 JSFunction::SetFunctionPrototypeOrInstanceHClass(thread,
361 JSHandle<JSFunction>::Cast(lightWeightMapFunction), lightWeightMapInstanceClass.GetTaggedValue());
362
363 // "constructor" property on the prototype
364 JSHandle<JSTaggedValue> constructorKey = globalConst->GetHandledConstructorString();
365 JSObject::SetProperty(thread, JSHandle<JSTaggedValue>(funcPrototype), constructorKey, lightWeightMapFunction);
366
367 // LightWeightMap.prototype.add()
368 SetFrozenFunction(thread, funcPrototype, "hasAll", ContainersLightWeightMap::HasAll, FuncLength::ONE);
369 SetFrozenFunction(thread, funcPrototype, "hasKey", ContainersLightWeightMap::HasKey, FuncLength::ONE);
370 SetFrozenFunction(thread, funcPrototype, "hasValue", ContainersLightWeightMap::HasValue, FuncLength::ONE);
371 SetFrozenFunction(thread, funcPrototype, "increaseCapacityTo", ContainersLightWeightMap::IncreaseCapacityTo,
372 FuncLength::ONE);
373 SetFrozenFunction(thread, funcPrototype, "entries", ContainersLightWeightMap::Entries, FuncLength::ONE);
374 SetFrozenFunction(thread, funcPrototype, "get", ContainersLightWeightMap::Get, FuncLength::ONE);
375 SetFrozenFunction(thread, funcPrototype, "getIndexOfKey", ContainersLightWeightMap::GetIndexOfKey, FuncLength::ONE);
376 SetFrozenFunction(thread, funcPrototype, "getIndexOfValue", ContainersLightWeightMap::GetIndexOfValue,
377 FuncLength::ONE);
378 SetFrozenFunction(thread, funcPrototype, "isEmpty", ContainersLightWeightMap::IsEmpty, FuncLength::ONE);
379 SetFrozenFunction(thread, funcPrototype, "getKeyAt", ContainersLightWeightMap::GetKeyAt, FuncLength::ONE);
380 SetFrozenFunction(thread, funcPrototype, "keys", ContainersLightWeightMap::Keys, FuncLength::ONE);
381 SetFrozenFunction(thread, funcPrototype, "setAll", ContainersLightWeightMap::SetAll, FuncLength::ONE);
382 SetFrozenFunction(thread, funcPrototype, "set", ContainersLightWeightMap::Set, FuncLength::ONE);
383 SetFrozenFunction(thread, funcPrototype, "remove", ContainersLightWeightMap::Remove, FuncLength::ONE);
384 SetFrozenFunction(thread, funcPrototype, "removeAt", ContainersLightWeightMap::RemoveAt, FuncLength::ONE);
385 SetFrozenFunction(thread, funcPrototype, "clear", ContainersLightWeightMap::Clear, FuncLength::ONE);
386 SetFrozenFunction(thread, funcPrototype, "setValueAt", ContainersLightWeightMap::SetValueAt, FuncLength::ONE);
387 SetFrozenFunction(thread, funcPrototype, "forEach", ContainersLightWeightMap::ForEach, FuncLength::ONE,
388 BUILTINS_STUB_ID(LightWeightMapForEach));
389 SetFrozenFunction(thread, funcPrototype, "toString", ContainersLightWeightMap::ToString, FuncLength::ONE);
390 SetFrozenFunction(thread, funcPrototype, "getValueAt", ContainersLightWeightMap::GetValueAt, FuncLength::ONE);
391 SetFrozenFunction(thread, funcPrototype, "values", ContainersLightWeightMap::Values, FuncLength::ONE);
392
393 JSHandle<JSTaggedValue> lengthGetter = CreateGetter(thread, ContainersLightWeightMap::Length, "length",
394 FuncLength::ZERO);
395 JSHandle<JSTaggedValue> lengthKey(factory->NewFromASCII("length"));
396 SetGetter(thread, funcPrototype, lengthKey, lengthGetter);
397
398 JSHandle<GlobalEnv> env = thread->GetEcmaVM()->GetGlobalEnv();
399 SetFunctionAtSymbol(thread, env, funcPrototype, env->GetIteratorSymbol(), "[Symbol.iterator]",
400 ContainersLightWeightMap::Entries, FuncLength::ONE);
401
402 ContainersPrivate::InitializeLightWeightMapIterator(thread);
403 return lightWeightMapFunction;
404 }
405
InitializeLightWeightMapIterator(JSThread * thread)406 void ContainersPrivate::InitializeLightWeightMapIterator(JSThread *thread)
407 {
408 JSHandle<GlobalEnv> env = thread->GetEcmaVM()->GetGlobalEnv();
409 ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
410 JSHandle<JSHClass> iteratorClass = factory->NewEcmaHClass(JSObject::SIZE, JSType::JS_ITERATOR,
411 env->GetIteratorPrototype());
412 JSHandle<JSObject> lightWeightMapIteratorPrototype(factory->NewJSObject(iteratorClass));
413 SetFrozenFunction(thread, lightWeightMapIteratorPrototype, "next", JSAPILightWeightMapIterator::Next,
414 FuncLength::ONE);
415 SetStringTagSymbol(thread, env, lightWeightMapIteratorPrototype, "LightWeightMap Iterator");
416 auto globalConst = const_cast<GlobalEnvConstants *>(thread->GlobalConstants());
417 globalConst->SetConstant(ConstantIndex::LIGHTWEIGHTMAP_ITERATOR_PROTOTYPE_INDEX,
418 lightWeightMapIteratorPrototype.GetTaggedValue());
419 }
420
InitializeLightWeightSet(JSThread * thread)421 JSHandle<JSTaggedValue> ContainersPrivate::InitializeLightWeightSet(JSThread *thread)
422 {
423 const GlobalEnvConstants *globalConst = thread->GlobalConstants();
424 ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
425 // LightWeightSet.prototype
426 JSHandle<JSObject> funcPrototype = factory->NewEmptyJSObject();
427 JSHandle<JSTaggedValue> funcPrototypeValue(funcPrototype);
428 // LightWeightSet.prototype_or_hclass
429 JSHandle<JSHClass> lightweightSetInstanceClass =
430 factory->NewEcmaHClass(JSAPILightWeightSet::SIZE, JSType::JS_API_LIGHT_WEIGHT_SET, funcPrototypeValue);
431 JSHandle<JSTaggedValue> lightweightSetFunction(
432 NewContainerConstructor(thread, funcPrototype, ContainersLightWeightSet::LightWeightSetConstructor,
433 "LightWeightSet", FuncLength::ZERO));
434 JSFunction::SetFunctionPrototypeOrInstanceHClass(thread,
435 JSHandle<JSFunction>::Cast(lightweightSetFunction), lightweightSetInstanceClass.GetTaggedValue());
436 // "constructor" property on the prototype
437 JSHandle<JSTaggedValue> constructorKey = globalConst->GetHandledConstructorString();
438 JSObject::SetProperty(thread, JSHandle<JSTaggedValue>(funcPrototype), constructorKey, lightweightSetFunction);
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
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
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 // PlainArray.prototype.add()
658 SetFrozenFunction(thread, plainArrayFuncPrototype, "add", ContainersPlainArray::Add, FuncLength::ONE);
659 SetFrozenFunction(thread, plainArrayFuncPrototype, "clear", ContainersPlainArray::Clear, FuncLength::ONE);
660 SetFrozenFunction(thread, plainArrayFuncPrototype, "clone", ContainersPlainArray::Clone, FuncLength::ONE);
661 SetFrozenFunction(thread, plainArrayFuncPrototype, "has", ContainersPlainArray::Has, FuncLength::ONE);
662 SetFrozenFunction(thread, plainArrayFuncPrototype, "get", ContainersPlainArray::Get, FuncLength::ONE);
663 SetFrozenFunction(thread, plainArrayFuncPrototype, "forEach", ContainersPlainArray::ForEach, FuncLength::ONE,
664 BUILTINS_STUB_ID(PlainArrayForEach));
665 SetFrozenFunction(thread, plainArrayFuncPrototype, "toString", ContainersPlainArray::ToString,
666 FuncLength::ZERO);
667 SetFrozenFunction(thread, plainArrayFuncPrototype, "getIndexOfKey", ContainersPlainArray::GetIndexOfKey,
668 FuncLength::ZERO);
669 SetFrozenFunction(thread, plainArrayFuncPrototype, "getIndexOfValue", ContainersPlainArray::GetIndexOfValue,
670 FuncLength::ZERO);
671 SetFrozenFunction(thread, plainArrayFuncPrototype, "isEmpty", ContainersPlainArray::IsEmpty, FuncLength::ZERO);
672 SetFrozenFunction(thread, plainArrayFuncPrototype, "getKeyAt",
673 ContainersPlainArray::GetKeyAt, FuncLength::ZERO);
674 SetFrozenFunction(thread, plainArrayFuncPrototype, "remove", ContainersPlainArray::Remove, FuncLength::ZERO);
675 SetFrozenFunction(thread, plainArrayFuncPrototype, "removeAt", ContainersPlainArray::RemoveAt,
676 FuncLength::ZERO);
677 SetFrozenFunction(thread, plainArrayFuncPrototype, "removeRangeFrom", ContainersPlainArray::RemoveRangeFrom,
678 FuncLength::ZERO);
679 SetFrozenFunction(thread, plainArrayFuncPrototype, "setValueAt", ContainersPlainArray::SetValueAt,
680 FuncLength::ZERO);
681 SetFrozenFunction(thread, plainArrayFuncPrototype, "getValueAt", ContainersPlainArray::GetValueAt,
682 FuncLength::ZERO);
683
684 JSHandle<JSTaggedValue> lengthGetter = CreateGetter(thread, ContainersPlainArray::GetSize, "length",
685 FuncLength::ZERO);
686 JSHandle<JSTaggedValue> lengthKey = globalConst->GetHandledLengthString();
687 SetGetter(thread, plainArrayFuncPrototype, lengthKey, lengthGetter);
688
689 JSHandle<GlobalEnv> env = thread->GetEcmaVM()->GetGlobalEnv();
690 SetFunctionAtSymbol(thread, env, plainArrayFuncPrototype, env->GetIteratorSymbol(), "[Symbol.iterator]",
691 ContainersPlainArray::GetIteratorObj, FuncLength::ONE);
692 InitializePlainArrayIterator(thread);
693 globalConst->SetConstant(ConstantIndex::PLAIN_ARRAY_FUNCTION_INDEX, plainArrayFunction.GetTaggedValue());
694 return plainArrayFunction;
695 }
696
InitializePlainArrayIterator(JSThread * thread)697 void ContainersPrivate::InitializePlainArrayIterator(JSThread *thread)
698 {
699 JSHandle<GlobalEnv> env = thread->GetEcmaVM()->GetGlobalEnv();
700 ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
701 auto globalConst = const_cast<GlobalEnvConstants *>(thread->GlobalConstants());
702 JSHandle<JSHClass> iteratorClass =
703 JSHandle<JSHClass>(thread, globalConst->GetHandledJSAPIIteratorFuncHClass().GetObject<JSHClass>());
704 JSHandle<JSObject> plainarrayIteratorPrototype(factory->NewJSObject(iteratorClass));
705 SetFrozenFunction(thread, plainarrayIteratorPrototype, "next", JSAPIPlainArrayIterator::Next, FuncLength::ONE);
706 SetStringTagSymbol(thread, env, plainarrayIteratorPrototype, "PlainArray Iterator");
707 globalConst->SetConstant(ConstantIndex::PLAIN_ARRAY_ITERATOR_PROTOTYPE_INDEX,
708 plainarrayIteratorPrototype.GetTaggedValue());
709 }
710
InitializeStack(JSThread * thread)711 JSHandle<JSTaggedValue> ContainersPrivate::InitializeStack(JSThread *thread)
712 {
713 auto globalConst = const_cast<GlobalEnvConstants *>(thread->GlobalConstants());
714 ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
715 // Stack.prototype
716 JSHandle<JSObject> stackFuncPrototype = factory->NewEmptyJSObject();
717 JSHandle<JSTaggedValue> stackFuncPrototypeValue(stackFuncPrototype);
718 // Stack.prototype_or_hclass
719 JSHandle<JSHClass> stackInstanceClass =
720 factory->NewEcmaHClass(JSAPIStack::SIZE, JSType::JS_API_STACK, stackFuncPrototypeValue);
721 // Stack() = new Function()
722 JSHandle<JSTaggedValue> stackFunction(NewContainerConstructor(
723 thread, stackFuncPrototype, ContainersStack::StackConstructor, "Stack", FuncLength::ZERO));
724 JSFunction::SetFunctionPrototypeOrInstanceHClass(thread,
725 JSHandle<JSFunction>::Cast(stackFunction), stackInstanceClass.GetTaggedValue());
726
727 // "constructor" property on the prototype
728 JSHandle<JSTaggedValue> constructorKey = globalConst->GetHandledConstructorString();
729 JSObject::SetProperty(thread, JSHandle<JSTaggedValue>(stackFuncPrototype), constructorKey, stackFunction);
730
731 // Stack.prototype.push()
732 SetFrozenFunction(thread, stackFuncPrototype, "push", ContainersStack::Push, FuncLength::ONE);
733 // Stack.prototype.empty()
734 SetFrozenFunction(thread, stackFuncPrototype, "isEmpty", ContainersStack::IsEmpty, FuncLength::ONE);
735 // Stack.prototype.peek()
736 SetFrozenFunction(thread, stackFuncPrototype, "peek", ContainersStack::Peek, FuncLength::ONE);
737 // Stack.prototype.pop()
738 SetFrozenFunction(thread, stackFuncPrototype, "pop", ContainersStack::Pop, FuncLength::ONE);
739 // Stack.prototype.search()
740 SetFrozenFunction(thread, stackFuncPrototype, "locate", ContainersStack::Locate, FuncLength::ONE);
741 // Stack.prototype.forEach()
742 SetFrozenFunction(thread, stackFuncPrototype, "forEach", ContainersStack::ForEach, FuncLength::ONE,
743 BUILTINS_STUB_ID(StackForEach));
744 JSHandle<GlobalEnv> env = thread->GetEcmaVM()->GetGlobalEnv();
745 SetStringTagSymbol(thread, env, stackFuncPrototype, "Stack");
746
747 JSHandle<JSTaggedValue> lengthGetter = CreateGetter(thread, ContainersStack::GetLength, "length", FuncLength::ZERO);
748 JSHandle<JSTaggedValue> lengthKey = globalConst->GetHandledLengthString();
749 SetGetter(thread, stackFuncPrototype, lengthKey, lengthGetter);
750
751 SetFunctionAtSymbol(thread, env, stackFuncPrototype, env->GetIteratorSymbol(), "[Symbol.iterator]",
752 ContainersStack::Iterator, FuncLength::ONE);
753
754 ContainersPrivate::InitializeStackIterator(thread, globalConst);
755 return stackFunction;
756 }
757
InitializeStackIterator(JSThread * thread,GlobalEnvConstants * globalConst)758 void ContainersPrivate::InitializeStackIterator(JSThread *thread, GlobalEnvConstants *globalConst)
759 {
760 ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
761 JSHandle<JSHClass> iteratorFuncHClass = JSHandle<JSHClass>(thread, globalConst->
762 GetHandledJSAPIIteratorFuncHClass().GetObject<JSHClass>());
763 // StackIterator.prototype
764 JSHandle<JSObject> stackIteratorPrototype(factory->NewJSObject(iteratorFuncHClass));
765 // Iterator.prototype.next()
766 SetFrozenFunction(thread, stackIteratorPrototype, "next", JSAPIStackIterator::Next, FuncLength::ONE);
767 globalConst->SetConstant(ConstantIndex::STACK_ITERATOR_PROTOTYPE_INDEX, stackIteratorPrototype.GetTaggedValue());
768 }
769
InitializeVector(JSThread * thread)770 JSHandle<JSTaggedValue> ContainersPrivate::InitializeVector(JSThread *thread)
771 {
772 auto globalConst = const_cast<GlobalEnvConstants *>(thread->GlobalConstants());
773 ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
774 // Vector.prototype
775 JSHandle<JSObject> prototype = factory->NewEmptyJSObject();
776 JSHandle<JSTaggedValue> vectorFuncPrototypeValue(prototype);
777 // Vector.prototype_or_hclass
778 JSHandle<JSHClass> vectorInstanceClass =
779 factory->NewEcmaHClass(JSAPIVector::SIZE, JSType::JS_API_VECTOR, vectorFuncPrototypeValue);
780 // Vector() = new Function()
781 JSHandle<JSTaggedValue> vectorFunction(NewContainerConstructor(
782 thread, prototype, ContainersVector::VectorConstructor, "Vector", FuncLength::ZERO));
783 JSFunction::SetFunctionPrototypeOrInstanceHClass(thread,
784 JSHandle<JSFunction>::Cast(vectorFunction), vectorInstanceClass.GetTaggedValue());
785
786 // "constructor" property on the prototype
787 JSHandle<JSTaggedValue> constructorKey = globalConst->GetHandledConstructorString();
788 JSObject::SetProperty(thread, JSHandle<JSTaggedValue>(prototype), constructorKey, vectorFunction);
789
790 // Vector.prototype
791 SetFrozenFunction(thread, prototype, "add", ContainersVector::Add, FuncLength::ONE);
792 SetFrozenFunction(thread, prototype, "insert", ContainersVector::Insert, FuncLength::TWO);
793 SetFrozenFunction(thread, prototype, "setLength", ContainersVector::SetLength, FuncLength::ONE);
794 SetFrozenFunction(thread, prototype, "getCapacity", ContainersVector::GetCapacity, FuncLength::ZERO);
795 SetFrozenFunction(thread, prototype, "increaseCapacityTo", ContainersVector::IncreaseCapacityTo, FuncLength::ONE);
796 SetFrozenFunction(thread, prototype, "get", ContainersVector::Get, FuncLength::ONE);
797 SetFrozenFunction(thread, prototype, "getIndexOf", ContainersVector::GetIndexOf, FuncLength::ONE);
798 SetFrozenFunction(thread, prototype, "getIndexFrom", ContainersVector::GetIndexFrom, FuncLength::TWO);
799 SetFrozenFunction(thread, prototype, "isEmpty", ContainersVector::IsEmpty, FuncLength::ZERO);
800 SetFrozenFunction(thread, prototype, "getLastElement", ContainersVector::GetLastElement, FuncLength::ZERO);
801 SetFrozenFunction(thread, prototype, "getLastIndexOf", ContainersVector::GetLastIndexOf, FuncLength::ONE);
802 SetFrozenFunction(thread, prototype, "getLastIndexFrom", ContainersVector::GetLastIndexFrom, FuncLength::TWO);
803 SetFrozenFunction(thread, prototype, "remove", ContainersVector::Remove, FuncLength::ONE);
804 SetFrozenFunction(thread, prototype, "removeByIndex", ContainersVector::RemoveByIndex, FuncLength::ONE);
805 SetFrozenFunction(thread, prototype, "removeByRange", ContainersVector::RemoveByRange, FuncLength::TWO);
806 SetFrozenFunction(thread, prototype, "set", ContainersVector::Set, FuncLength::TWO);
807 SetFrozenFunction(thread, prototype, "subVector", ContainersVector::SubVector, FuncLength::TWO);
808 SetFrozenFunction(thread, prototype, "toString", ContainersVector::ToString, FuncLength::ZERO);
809 SetFrozenFunction(thread, prototype, "forEach", ContainersVector::ForEach, FuncLength::TWO,
810 BUILTINS_STUB_ID(VectorForEach));
811 SetFrozenFunction(thread, prototype, "replaceAllElements", ContainersVector::ReplaceAllElements, FuncLength::TWO,
812 BUILTINS_STUB_ID(VectorReplaceAllElements));
813 SetFrozenFunction(thread, prototype, "has", ContainersVector::Has, FuncLength::ONE);
814 SetFrozenFunction(thread, prototype, "sort", ContainersVector::Sort, FuncLength::ZERO);
815 SetFrozenFunction(thread, prototype, "clear", ContainersVector::Clear, FuncLength::ZERO);
816 SetFrozenFunction(thread, prototype, "clone", ContainersVector::Clone, FuncLength::ZERO);
817 SetFrozenFunction(thread, prototype, "copyToArray", ContainersVector::CopyToArray, FuncLength::ONE);
818 SetFrozenFunction(thread, prototype, "convertToArray", ContainersVector::ConvertToArray, FuncLength::ZERO);
819 SetFrozenFunction(thread, prototype, "getFirstElement", ContainersVector::GetFirstElement, FuncLength::ZERO);
820 SetFrozenFunction(thread, prototype, "trimToCurrentLength",
821 ContainersVector::TrimToCurrentLength, FuncLength::ZERO);
822
823 JSHandle<GlobalEnv> env = thread->GetEcmaVM()->GetGlobalEnv();
824 SetStringTagSymbol(thread, env, prototype, "Vector");
825
826 JSHandle<JSTaggedValue> lengthGetter = CreateGetter(thread, ContainersVector::GetSize, "length", FuncLength::ZERO);
827 JSHandle<JSTaggedValue> lengthKey(thread, globalConst->GetLengthString());
828 SetGetter(thread, prototype, lengthKey, lengthGetter);
829
830 SetFunctionAtSymbol(thread, env, prototype, env->GetIteratorSymbol(), "[Symbol.iterator]",
831 ContainersVector::GetIteratorObj, FuncLength::ONE);
832
833 ContainersPrivate::InitializeVectorIterator(thread, env, globalConst);
834 globalConst->SetConstant(ConstantIndex::VECTOR_FUNCTION_INDEX, vectorFunction.GetTaggedValue());
835 return vectorFunction;
836 }
837
InitializeVectorIterator(JSThread * thread,const JSHandle<GlobalEnv> & env,GlobalEnvConstants * globalConst)838 void ContainersPrivate::InitializeVectorIterator(JSThread *thread, const JSHandle<GlobalEnv> &env,
839 GlobalEnvConstants *globalConst)
840 {
841 ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
842 JSHandle<JSHClass> iteratorFuncHClass = JSHandle<JSHClass>(thread, globalConst->
843 GetHandledJSAPIIteratorFuncHClass().GetObject<JSHClass>());
844 // VectorIterator.prototype
845 JSHandle<JSObject> vectorIteratorPrototype(factory->NewJSObject(iteratorFuncHClass));
846 // Iterator.prototype.next()
847 SetFrozenFunction(thread, vectorIteratorPrototype, "next", JSAPIVectorIterator::Next, FuncLength::ONE);
848 SetStringTagSymbol(thread, env, vectorIteratorPrototype, "Vector Iterator");
849 globalConst->SetConstant(ConstantIndex::VECTOR_ITERATOR_PROTOTYPE_INDEX, vectorIteratorPrototype.GetTaggedValue());
850 }
851
InitializeQueue(JSThread * thread)852 JSHandle<JSTaggedValue> ContainersPrivate::InitializeQueue(JSThread *thread)
853 {
854 auto globalConst = const_cast<GlobalEnvConstants *>(thread->GlobalConstants());
855 ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
856 // Queue.prototype
857 JSHandle<JSObject> queueFuncPrototype = factory->NewEmptyJSObject();
858 JSHandle<JSTaggedValue> queueFuncPrototypeValue(queueFuncPrototype);
859 // Queue.prototype_or_hclass
860 JSHandle<JSHClass> queueInstanceClass =
861 factory->NewEcmaHClass(JSAPIQueue::SIZE, JSType::JS_API_QUEUE, queueFuncPrototypeValue);
862 // Queue() = new Function()
863 JSHandle<JSTaggedValue> queueFunction(NewContainerConstructor(
864 thread, queueFuncPrototype, ContainersQueue::QueueConstructor, "Queue", FuncLength::ZERO));
865 JSFunction::SetFunctionPrototypeOrInstanceHClass(thread,
866 JSHandle<JSFunction>::Cast(queueFunction), queueInstanceClass.GetTaggedValue());
867
868 // "constructor" property on the prototype
869 JSHandle<JSTaggedValue> constructorKey = globalConst->GetHandledConstructorString();
870 JSObject::SetProperty(thread, JSHandle<JSTaggedValue>(queueFuncPrototype), constructorKey, queueFunction);
871
872 // Queue.prototype.add()
873 SetFrozenFunction(thread, queueFuncPrototype, "add", ContainersQueue::Add, FuncLength::ONE);
874 SetFrozenFunction(thread, queueFuncPrototype, "getFirst", ContainersQueue::GetFirst, FuncLength::ZERO);
875 SetFrozenFunction(thread, queueFuncPrototype, "pop", ContainersQueue::Pop, FuncLength::ZERO);
876 SetFrozenFunction(thread, queueFuncPrototype, "forEach", ContainersQueue::ForEach, FuncLength::TWO,
877 BUILTINS_STUB_ID(QueueForEach));
878
879 JSHandle<GlobalEnv> env = thread->GetEcmaVM()->GetGlobalEnv();
880 SetStringTagSymbol(thread, env, queueFuncPrototype, "Queue");
881
882 JSHandle<JSTaggedValue> lengthGetter = CreateGetter(thread, ContainersQueue::GetSize, "length", FuncLength::ZERO);
883 JSHandle<JSTaggedValue> lengthKey(thread, globalConst->GetLengthString());
884 SetGetter(thread, queueFuncPrototype, lengthKey, lengthGetter);
885
886 SetFunctionAtSymbol(thread, env, queueFuncPrototype, env->GetIteratorSymbol(), "[Symbol.iterator]",
887 ContainersQueue::GetIteratorObj, FuncLength::ONE);
888
889 ContainersPrivate::InitializeQueueIterator(thread, env, globalConst);
890 return queueFunction;
891 }
892
InitializeQueueIterator(JSThread * thread,const JSHandle<GlobalEnv> & env,GlobalEnvConstants * globalConst)893 void ContainersPrivate::InitializeQueueIterator(JSThread *thread, const JSHandle<GlobalEnv> &env,
894 GlobalEnvConstants *globalConst)
895 {
896 ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
897 JSHandle<JSHClass> iteratorFuncHClass =
898 factory->NewEcmaHClass(JSObject::SIZE, JSType::JS_ITERATOR, env->GetIteratorPrototype());
899 // QueueIterator.prototype
900 JSHandle<JSObject> queueIteratorPrototype(factory->NewJSObject(iteratorFuncHClass));
901 // Iterator.prototype.next()
902 SetFrozenFunction(thread, queueIteratorPrototype, "next", JSAPIQueueIterator::Next, FuncLength::ONE);
903 SetStringTagSymbol(thread, env, queueIteratorPrototype, "Queue Iterator");
904 globalConst->SetConstant(ConstantIndex::QUEUE_ITERATOR_PROTOTYPE_INDEX, queueIteratorPrototype.GetTaggedValue());
905 }
906
InitializeDeque(JSThread * thread)907 JSHandle<JSTaggedValue> ContainersPrivate::InitializeDeque(JSThread *thread)
908 {
909 auto globalConst = const_cast<GlobalEnvConstants *>(thread->GlobalConstants());
910 ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
911 // Deque.prototype
912 JSHandle<JSObject> dequeFuncPrototype = factory->NewEmptyJSObject();
913 JSHandle<JSTaggedValue> dequeFuncPrototypeValue(dequeFuncPrototype);
914 // Deque.prototype_or_hclass
915 JSHandle<JSHClass> dequeInstanceClass =
916 factory->NewEcmaHClass(JSAPIDeque::SIZE, JSType::JS_API_DEQUE, dequeFuncPrototypeValue);
917 // Deque() = new Function()
918 JSHandle<JSTaggedValue> dequeFunction(NewContainerConstructor(
919 thread, dequeFuncPrototype, ContainersDeque::DequeConstructor, "Deque", FuncLength::ZERO));
920 JSFunction::SetFunctionPrototypeOrInstanceHClass(thread,
921 JSHandle<JSFunction>::Cast(dequeFunction), dequeInstanceClass.GetTaggedValue());
922
923 // "constructor" property on the prototype
924 JSHandle<JSTaggedValue> constructorKey = globalConst->GetHandledConstructorString();
925 JSObject::SetProperty(thread, JSHandle<JSTaggedValue>(dequeFuncPrototype), constructorKey, dequeFunction);
926
927 SetFrozenFunction(thread, dequeFuncPrototype, "insertFront", ContainersDeque::InsertFront, FuncLength::ONE);
928 SetFrozenFunction(thread, dequeFuncPrototype, "insertEnd", ContainersDeque::InsertEnd, FuncLength::ONE);
929 SetFrozenFunction(thread, dequeFuncPrototype, "getFirst", ContainersDeque::GetFirst, FuncLength::ZERO);
930 SetFrozenFunction(thread, dequeFuncPrototype, "getLast", ContainersDeque::GetLast, FuncLength::ZERO);
931 SetFrozenFunction(thread, dequeFuncPrototype, "has", ContainersDeque::Has, FuncLength::ONE);
932 SetFrozenFunction(thread, dequeFuncPrototype, "popFirst", ContainersDeque::PopFirst, FuncLength::ZERO);
933 SetFrozenFunction(thread, dequeFuncPrototype, "popLast", ContainersDeque::PopLast, FuncLength::ZERO);
934 SetFrozenFunction(thread, dequeFuncPrototype, "forEach", ContainersDeque::ForEach, FuncLength::TWO,
935 BUILTINS_STUB_ID(DequeForEach));
936
937 JSHandle<GlobalEnv> env = thread->GetEcmaVM()->GetGlobalEnv();
938 SetStringTagSymbol(thread, env, dequeFuncPrototype, "Deque");
939
940 JSHandle<JSTaggedValue> lengthGetter = CreateGetter(thread, ContainersDeque::GetSize, "length", FuncLength::ZERO);
941 JSHandle<JSTaggedValue> lengthKey = globalConst->GetHandledLengthString();
942 SetGetter(thread, dequeFuncPrototype, lengthKey, lengthGetter);
943
944 SetFunctionAtSymbol(thread, env, dequeFuncPrototype, env->GetIteratorSymbol(), "[Symbol.iterator]",
945 ContainersDeque::GetIteratorObj, FuncLength::ONE);
946
947 ContainersPrivate::InitializeDequeIterator(thread, env, globalConst);
948
949 return dequeFunction;
950 }
951
InitializeDequeIterator(JSThread * thread,const JSHandle<GlobalEnv> & env,GlobalEnvConstants * globalConst)952 void ContainersPrivate::InitializeDequeIterator(JSThread *thread, const JSHandle<GlobalEnv> &env,
953 GlobalEnvConstants *globalConst)
954 {
955 ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
956 JSHandle<JSHClass> iteratorFuncHClass = JSHandle<JSHClass>(thread, globalConst->
957 GetHandledJSAPIIteratorFuncHClass().GetObject<JSHClass>());
958 JSHandle<JSObject> dequeIteratorPrototype(factory->NewJSObject(iteratorFuncHClass));
959 SetFrozenFunction(thread, dequeIteratorPrototype, "next", JSAPIDequeIterator::Next, FuncLength::ONE);
960 SetStringTagSymbol(thread, env, dequeIteratorPrototype, "Deque Iterator");
961 globalConst->SetConstant(ConstantIndex::DEQUE_ITERATOR_PROTOTYPE_INDEX, dequeIteratorPrototype.GetTaggedValue());
962 }
963
InitializeList(JSThread * thread)964 JSHandle<JSTaggedValue> ContainersPrivate::InitializeList(JSThread *thread)
965 {
966 auto globalConst = const_cast<GlobalEnvConstants *>(thread->GlobalConstants());
967 ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
968 JSHandle<JSObject> listFuncPrototype = factory->NewEmptyJSObject();
969 JSHandle<JSTaggedValue> listFuncPrototypeValue(listFuncPrototype);
970 JSHandle<JSHClass> listInstanceClass =
971 factory->NewEcmaHClass(JSAPIList::SIZE, JSType::JS_API_LIST, listFuncPrototypeValue);
972 JSHandle<JSTaggedValue> listFunction(NewContainerConstructor(
973 thread, listFuncPrototype, ContainersList::ListConstructor, "List", FuncLength::ZERO));
974 JSFunction::SetFunctionPrototypeOrInstanceHClass(thread,
975 JSHandle<JSFunction>::Cast(listFunction), listInstanceClass.GetTaggedValue());
976
977 JSHandle<JSTaggedValue> constructorKey = globalConst->GetHandledConstructorString();
978 JSObject::SetProperty(thread, JSHandle<JSTaggedValue>(listFuncPrototype), constructorKey, listFunction);
979
980 SetFrozenFunction(thread, listFuncPrototype, "add", ContainersList::Add, FuncLength::ONE);
981 SetFrozenFunction(thread, listFuncPrototype, "getFirst", ContainersList::GetFirst, FuncLength::ONE);
982 SetFrozenFunction(thread, listFuncPrototype, "getLast", ContainersList::GetLast, FuncLength::ONE);
983 SetFrozenFunction(thread, listFuncPrototype, "insert", ContainersList::Insert, FuncLength::ONE);
984 SetFrozenFunction(thread, listFuncPrototype, "clear", ContainersList::Clear, FuncLength::ONE);
985 SetFrozenFunction(thread, listFuncPrototype, "removeByIndex", ContainersList::RemoveByIndex, FuncLength::ONE);
986 SetFrozenFunction(thread, listFuncPrototype, "remove", ContainersList::Remove, FuncLength::ONE);
987 SetFrozenFunction(thread, listFuncPrototype, "has", ContainersList::Has, FuncLength::ONE);
988 SetFrozenFunction(thread, listFuncPrototype, "isEmpty", ContainersList::IsEmpty, FuncLength::ONE);
989 SetFrozenFunction(thread, listFuncPrototype, "get", ContainersList::Get, FuncLength::ONE);
990 SetFrozenFunction(thread, listFuncPrototype, "getIndexOf", ContainersList::GetIndexOf, FuncLength::ONE);
991 SetFrozenFunction(thread, listFuncPrototype, "getLastIndexOf", ContainersList::GetLastIndexOf, FuncLength::ONE);
992 SetFrozenFunction(thread, listFuncPrototype, "set", ContainersList::Set, FuncLength::ONE);
993 SetFrozenFunction(thread, listFuncPrototype, "forEach", ContainersList::ForEach, FuncLength::ONE,
994 BUILTINS_STUB_ID(ListForEach));
995 SetFrozenFunction(thread, listFuncPrototype, "replaceAllElements", ContainersList::ReplaceAllElements,
996 FuncLength::ONE);
997 SetFrozenFunction(thread, listFuncPrototype, "equal", ContainersList::Equal, FuncLength::ONE);
998 SetFrozenFunction(thread, listFuncPrototype, "sort", ContainersList::Sort, FuncLength::ONE);
999 SetFrozenFunction(thread, listFuncPrototype, "convertToArray", ContainersList::ConvertToArray, FuncLength::ONE);
1000 SetFrozenFunction(thread, listFuncPrototype, "getSubList", ContainersList::GetSubList, FuncLength::ONE);
1001
1002 JSHandle<JSTaggedValue> lengthGetter = CreateGetter(thread, ContainersList::Length, "length", FuncLength::ZERO);
1003 JSHandle<JSTaggedValue> lengthKey(factory->NewFromASCII("length"));
1004 SetGetter(thread, listFuncPrototype, lengthKey, lengthGetter);
1005
1006 JSHandle<GlobalEnv> env = thread->GetEcmaVM()->GetGlobalEnv();
1007 SetFunctionAtSymbol(thread, env, listFuncPrototype, env->GetIteratorSymbol(), "[Symbol.iterator]",
1008 ContainersList::GetIteratorObj, FuncLength::ONE);
1009
1010 InitializeListIterator(thread, env);
1011 globalConst->SetConstant(ConstantIndex::LIST_FUNCTION_INDEX, listFunction.GetTaggedValue());
1012 return listFunction;
1013 }
1014
InitializeLinkedList(JSThread * thread)1015 JSHandle<JSTaggedValue> ContainersPrivate::InitializeLinkedList(JSThread *thread)
1016 {
1017 auto globalConst = const_cast<GlobalEnvConstants *>(thread->GlobalConstants());
1018 ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
1019 JSHandle<JSObject> linkedListFuncPrototype = factory->NewEmptyJSObject();
1020 JSHandle<JSTaggedValue> linkedListFuncPrototypeValue(linkedListFuncPrototype);
1021 JSHandle<JSHClass> linkedListInstanceClass =
1022 factory->NewEcmaHClass(JSAPILinkedList::SIZE, JSType::JS_API_LINKED_LIST, linkedListFuncPrototypeValue);
1023 JSHandle<JSTaggedValue> linkedListFunction(NewContainerConstructor(
1024 thread, linkedListFuncPrototype, ContainersLinkedList::LinkedListConstructor, "LinkedList", FuncLength::ZERO));
1025 JSFunction::SetFunctionPrototypeOrInstanceHClass(thread,
1026 JSHandle<JSFunction>::Cast(linkedListFunction), linkedListInstanceClass.GetTaggedValue());
1027
1028 JSHandle<JSTaggedValue> constructorKey = globalConst->GetHandledConstructorString();
1029 JSObject::SetProperty(thread, JSHandle<JSTaggedValue>(linkedListFuncPrototype), constructorKey, linkedListFunction);
1030
1031 SetFrozenFunction(thread, linkedListFuncPrototype, "add", ContainersLinkedList::Add, FuncLength::ONE);
1032 SetFrozenFunction(thread, linkedListFuncPrototype, "insert", ContainersLinkedList::Insert, FuncLength::ONE);
1033 SetFrozenFunction(thread, linkedListFuncPrototype, "clear", ContainersLinkedList::Clear, FuncLength::ONE);
1034 SetFrozenFunction(thread, linkedListFuncPrototype, "clone", ContainersLinkedList::Clone, FuncLength::ONE);
1035 SetFrozenFunction(thread, linkedListFuncPrototype, "removeFirst", ContainersLinkedList::RemoveFirst,
1036 FuncLength::ONE);
1037 SetFrozenFunction(thread, linkedListFuncPrototype, "removeLast", ContainersLinkedList::RemoveLast, FuncLength::ONE);
1038 SetFrozenFunction(thread, linkedListFuncPrototype, "removeFirstFound", ContainersLinkedList::RemoveFirstFound,
1039 FuncLength::ONE);
1040 SetFrozenFunction(thread, linkedListFuncPrototype, "removeByIndex", ContainersLinkedList::RemoveByIndex,
1041 FuncLength::ONE);
1042 SetFrozenFunction(thread, linkedListFuncPrototype, "remove", ContainersLinkedList::Remove, FuncLength::ONE);
1043 SetFrozenFunction(thread, linkedListFuncPrototype, "removeLastFound", ContainersLinkedList::RemoveLastFound,
1044 FuncLength::ONE);
1045 SetFrozenFunction(thread, linkedListFuncPrototype, "has", ContainersLinkedList::Has, FuncLength::ONE);
1046 SetFrozenFunction(thread, linkedListFuncPrototype, "get", ContainersLinkedList::Get, FuncLength::ONE);
1047 SetFrozenFunction(thread, linkedListFuncPrototype, "addFirst", ContainersLinkedList::AddFirst, FuncLength::ONE);
1048 SetFrozenFunction(thread, linkedListFuncPrototype, "getFirst", ContainersLinkedList::GetFirst, FuncLength::ONE);
1049 SetFrozenFunction(thread, linkedListFuncPrototype, "getLast", ContainersLinkedList::GetLast, FuncLength::ONE);
1050 SetFrozenFunction(thread, linkedListFuncPrototype, "getIndexOf", ContainersLinkedList::GetIndexOf, FuncLength::ONE);
1051 SetFrozenFunction(thread, linkedListFuncPrototype, "getLastIndexOf", ContainersLinkedList::GetLastIndexOf,
1052 FuncLength::ONE);
1053 SetFrozenFunction(thread, linkedListFuncPrototype, "convertToArray", ContainersLinkedList::ConvertToArray,
1054 FuncLength::ONE);
1055 SetFrozenFunction(thread, linkedListFuncPrototype, "set", ContainersLinkedList::Set, FuncLength::ONE);
1056 SetFrozenFunction(thread, linkedListFuncPrototype, "forEach", ContainersLinkedList::ForEach, FuncLength::ONE,
1057 BUILTINS_STUB_ID(LinkedListForEach));
1058
1059 JSHandle<JSTaggedValue> lengthGetter = CreateGetter(thread, ContainersLinkedList::Length, "length",
1060 FuncLength::ZERO);
1061 JSHandle<JSTaggedValue> lengthKey(factory->NewFromASCII("length"));
1062 SetGetter(thread, linkedListFuncPrototype, lengthKey, lengthGetter);
1063
1064 JSHandle<GlobalEnv> env = thread->GetEcmaVM()->GetGlobalEnv();
1065 SetFunctionAtSymbol(thread, env, linkedListFuncPrototype, env->GetIteratorSymbol(), "[Symbol.iterator]",
1066 ContainersLinkedList::GetIteratorObj, FuncLength::ONE);
1067
1068 InitializeLinkedListIterator(thread, env);
1069 globalConst->SetConstant(ConstantIndex::LINKED_LIST_FUNCTION_INDEX, linkedListFunction.GetTaggedValue());
1070 return linkedListFunction;
1071 }
1072
InitializeLinkedListIterator(JSThread * thread,const JSHandle<GlobalEnv> & env)1073 void ContainersPrivate::InitializeLinkedListIterator(JSThread *thread, const JSHandle<GlobalEnv> &env)
1074 {
1075 auto globalConst = const_cast<GlobalEnvConstants *>(thread->GlobalConstants());
1076 ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
1077 JSHandle<JSHClass> iteratorClass =
1078 JSHandle<JSHClass>(thread, globalConst->GetHandledJSAPIIteratorFuncHClass().GetObject<JSHClass>());
1079 JSHandle<JSObject> setIteratorPrototype(factory->NewJSObject(iteratorClass));
1080 SetFrozenFunction(thread, setIteratorPrototype, "next", JSAPILinkedListIterator::Next, FuncLength::ONE);
1081 SetStringTagSymbol(thread, env, setIteratorPrototype, "linkedlist Iterator");
1082 globalConst->SetConstant(ConstantIndex::LINKED_LIST_ITERATOR_PROTOTYPE_INDEX,
1083 setIteratorPrototype.GetTaggedValue());
1084 }
1085
InitializeListIterator(JSThread * thread,const JSHandle<GlobalEnv> & env)1086 void ContainersPrivate::InitializeListIterator(JSThread *thread, const JSHandle<GlobalEnv> &env)
1087 {
1088 auto globalConst = const_cast<GlobalEnvConstants *>(thread->GlobalConstants());
1089 ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
1090 JSHandle<JSHClass> iteratorClass =
1091 JSHandle<JSHClass>(thread, globalConst->GetHandledJSAPIIteratorFuncHClass().GetObject<JSHClass>());
1092 JSHandle<JSObject> setIteratorPrototype(factory->NewJSObject(iteratorClass));
1093 SetFrozenFunction(thread, setIteratorPrototype, "next", JSAPIListIterator::Next, FuncLength::ONE);
1094 SetStringTagSymbol(thread, env, setIteratorPrototype, "list Iterator");
1095 globalConst->SetConstant(ConstantIndex::LIST_ITERATOR_PROTOTYPE_INDEX, setIteratorPrototype.GetTaggedValue());
1096 }
1097
InitializeHashMap(JSThread * thread)1098 JSHandle<JSTaggedValue> ContainersPrivate::InitializeHashMap(JSThread *thread)
1099 {
1100 const GlobalEnvConstants *globalConst = thread->GlobalConstants();
1101 ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
1102 // HashMap.prototype
1103 JSHandle<JSObject> hashMapFuncPrototype = factory->NewEmptyJSObject();
1104 JSHandle<JSTaggedValue> hashMapFuncPrototypeValue(hashMapFuncPrototype);
1105 // HashMap.prototype_or_hclass
1106 JSHandle<JSHClass> hashMapInstanceClass =
1107 factory->NewEcmaHClass(JSAPIHashMap::SIZE, JSType::JS_API_HASH_MAP, hashMapFuncPrototypeValue);
1108
1109 JSHandle<JSTaggedValue> hashMapFunction(NewContainerConstructor(
1110 thread, hashMapFuncPrototype, ContainersHashMap::HashMapConstructor, "HashMap", FuncLength::ZERO));
1111 JSFunction::SetFunctionPrototypeOrInstanceHClass(thread,
1112 JSHandle<JSFunction>::Cast(hashMapFunction), hashMapInstanceClass.GetTaggedValue());
1113
1114 // "constructor" property on the prototype
1115 JSHandle<JSTaggedValue> constructorKey = globalConst->GetHandledConstructorString();
1116 JSObject::SetProperty(thread, JSHandle<JSTaggedValue>(hashMapFuncPrototype), constructorKey, hashMapFunction);
1117 // HashMap.prototype.set()
1118 SetFrozenFunction(thread, hashMapFuncPrototype, "set", ContainersHashMap::Set, FuncLength::TWO);
1119 // HashMap.prototype.setall()
1120 SetFrozenFunction(thread, hashMapFuncPrototype, "setAll", ContainersHashMap::SetAll, FuncLength::ONE);
1121 // HashMap.prototype.isEmpty()
1122 SetFrozenFunction(thread, hashMapFuncPrototype, "isEmpty", ContainersHashMap::IsEmpty, FuncLength::ZERO);
1123 // HashMap.prototype.remove()
1124 SetFrozenFunction(thread, hashMapFuncPrototype, "remove", ContainersHashMap::Remove, FuncLength::ONE);
1125 // HashMap.prototype.clear()
1126 SetFrozenFunction(thread, hashMapFuncPrototype, "clear", ContainersHashMap::Clear, FuncLength::ZERO);
1127 // HashMap.prototype.get()
1128 SetFrozenFunction(thread, hashMapFuncPrototype, "get", ContainersHashMap::Get, FuncLength::ONE);
1129 // HashMap.prototype.forEach()
1130 SetFrozenFunction(thread, hashMapFuncPrototype, "forEach", ContainersHashMap::ForEach, FuncLength::TWO,
1131 BUILTINS_STUB_ID(HashMapForEach));
1132 // HashMap.prototype.hasKey()
1133 SetFrozenFunction(thread, hashMapFuncPrototype, "hasKey", ContainersHashMap::HasKey, FuncLength::ONE);
1134 // HashMap.prototype.hasValue()
1135 SetFrozenFunction(thread, hashMapFuncPrototype, "hasValue", ContainersHashMap::HasValue, FuncLength::ONE);
1136 // HashMap.prototype.replace()
1137 SetFrozenFunction(thread, hashMapFuncPrototype, "replace", ContainersHashMap::Replace, FuncLength::TWO);
1138 // HashMap.prototype.keys()
1139 SetFrozenFunction(thread, hashMapFuncPrototype, "keys", ContainersHashMap::Keys, FuncLength::ZERO);
1140 // HashMap.prototype.Values()
1141 SetFrozenFunction(thread, hashMapFuncPrototype, "values", ContainersHashMap::Values, FuncLength::ZERO);
1142 // HashMap.prototype.keys()
1143 SetFrozenFunction(thread, hashMapFuncPrototype, "entries", ContainersHashMap::Entries, FuncLength::ZERO);
1144 JSHandle<GlobalEnv> env = thread->GetEcmaVM()->GetGlobalEnv();
1145 // @@ToStringTag
1146 SetStringTagSymbol(thread, env, hashMapFuncPrototype, "HashMap");
1147 // %HashMapPrototype% [ @@iterator ]
1148 JSHandle<JSTaggedValue> iteratorSymbol = env->GetIteratorSymbol();
1149 JSHandle<JSTaggedValue> entries(factory->NewFromASCII("entries"));
1150 JSHandle<JSTaggedValue> entriesFunc =
1151 JSObject::GetMethod(thread, JSHandle<JSTaggedValue>::Cast(hashMapFuncPrototype), entries);
1152 RETURN_HANDLE_IF_ABRUPT_COMPLETION(JSTaggedValue, thread);
1153 PropertyDescriptor descriptor(thread, entriesFunc, false, false, false);
1154 JSObject::DefineOwnProperty(thread, hashMapFuncPrototype, iteratorSymbol, descriptor);
1155
1156 JSHandle<JSTaggedValue> lengthGetter =
1157 CreateGetter(thread, ContainersHashMap::GetLength, "length", FuncLength::ZERO);
1158 JSHandle<JSTaggedValue> lengthKey(thread, globalConst->GetLengthString());
1159 SetGetter(thread, hashMapFuncPrototype, lengthKey, lengthGetter);
1160 InitializeHashMapIterator(thread);
1161 return hashMapFunction;
1162 }
1163
InitializeHashMapIterator(JSThread * thread)1164 void ContainersPrivate::InitializeHashMapIterator(JSThread *thread)
1165 {
1166 JSHandle<GlobalEnv> env = thread->GetEcmaVM()->GetGlobalEnv();
1167 auto globalConst = const_cast<GlobalEnvConstants *>(thread->GlobalConstants());
1168 ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
1169 JSHandle<JSHClass> iteratorFuncHClass =
1170 JSHandle<JSHClass>::Cast(globalConst->GetHandledJSAPIIteratorFuncHClass());
1171 // HashMapIterator.prototype
1172 JSHandle<JSObject> hashMapIteratorPrototype(factory->NewJSObject(iteratorFuncHClass));
1173 // HashMapIterator.prototype.next()
1174 SetFrozenFunction(thread, hashMapIteratorPrototype, "next", JSAPIHashMapIterator::Next, FuncLength::ZERO);
1175 SetStringTagSymbol(thread, env, hashMapIteratorPrototype, "HashMap Iterator");
1176
1177 globalConst->SetConstant(ConstantIndex::HASHMAP_ITERATOR_PROTOTYPE_INDEX,
1178 hashMapIteratorPrototype.GetTaggedValue());
1179 }
1180
InitializeHashSet(JSThread * thread)1181 JSHandle<JSTaggedValue> ContainersPrivate::InitializeHashSet(JSThread *thread)
1182 {
1183 const GlobalEnvConstants *globalConst = thread->GlobalConstants();
1184 ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
1185 // HashSet.prototype
1186 JSHandle<JSObject> hashSetFuncPrototype = factory->NewEmptyJSObject();
1187 JSHandle<JSTaggedValue> hashSetFuncPrototypeValue(hashSetFuncPrototype);
1188 // HashSet.prototype_or_hclass
1189 JSHandle<JSHClass> hashSetInstanceClass =
1190 factory->NewEcmaHClass(JSAPIHashSet::SIZE, JSType::JS_API_HASH_SET, hashSetFuncPrototypeValue);
1191
1192 JSHandle<JSTaggedValue> hashSetFunction(NewContainerConstructor(
1193 thread, hashSetFuncPrototype, ContainersHashSet::HashSetConstructor, "HashSet", FuncLength::ZERO));
1194 JSFunction::SetFunctionPrototypeOrInstanceHClass(thread,
1195 JSHandle<JSFunction>::Cast(hashSetFunction), hashSetInstanceClass.GetTaggedValue());
1196
1197 // "constructor" property on the prototype
1198 JSHandle<JSTaggedValue> constructorKey = globalConst->GetHandledConstructorString();
1199 JSObject::SetProperty(thread, JSHandle<JSTaggedValue>(hashSetFuncPrototype), constructorKey, hashSetFunction);
1200
1201 SetFrozenFunction(thread, hashSetFuncPrototype, "isEmpty", ContainersHashSet::IsEmpty, FuncLength::ZERO);
1202 SetFrozenFunction(thread, hashSetFuncPrototype, "has", ContainersHashSet::Has, FuncLength::ONE);
1203 SetFrozenFunction(thread, hashSetFuncPrototype, "add", ContainersHashSet::Add, FuncLength::ONE);
1204 SetFrozenFunction(thread, hashSetFuncPrototype, "has", ContainersHashSet::Has, FuncLength::ONE);
1205 SetFrozenFunction(thread, hashSetFuncPrototype, "remove", ContainersHashSet::Remove, FuncLength::ONE);
1206 SetFrozenFunction(thread, hashSetFuncPrototype, "clear", ContainersHashSet::Clear, FuncLength::ZERO);
1207 SetFrozenFunction(thread, hashSetFuncPrototype, "values", ContainersHashSet::Values, FuncLength::ZERO);
1208 SetFrozenFunction(thread, hashSetFuncPrototype, "entries", ContainersHashSet::Entries, FuncLength::ZERO);
1209 SetFrozenFunction(thread, hashSetFuncPrototype, "forEach", ContainersHashSet::ForEach, FuncLength::TWO,
1210 BUILTINS_STUB_ID(HashSetForEach));
1211
1212 JSHandle<GlobalEnv> env = thread->GetEcmaVM()->GetGlobalEnv();
1213 // @@ToStringTag
1214 SetStringTagSymbol(thread, env, hashSetFuncPrototype, "HashSet");
1215 // %HashSetPrototype% [ @@iterator ]
1216 JSHandle<JSTaggedValue> iteratorSymbol = env->GetIteratorSymbol();
1217 JSHandle<JSTaggedValue> values(thread, globalConst->GetValuesString());
1218 JSHandle<JSTaggedValue> valuesFunc =
1219 JSObject::GetMethod(thread, JSHandle<JSTaggedValue>::Cast(hashSetFuncPrototype), values);
1220 RETURN_HANDLE_IF_ABRUPT_COMPLETION(JSTaggedValue, thread);
1221 PropertyDescriptor descriptor(thread, valuesFunc, false, false, false);
1222 JSObject::DefineOwnProperty(thread, hashSetFuncPrototype, iteratorSymbol, descriptor);
1223
1224 JSHandle<JSTaggedValue> lengthGetter =
1225 CreateGetter(thread, ContainersHashSet::GetLength, "length", FuncLength::ZERO);
1226 JSHandle<JSTaggedValue> lengthKey(thread, globalConst->GetLengthString());
1227 SetGetter(thread, hashSetFuncPrototype, lengthKey, lengthGetter);
1228 InitializeHashSetIterator(thread);
1229 return hashSetFunction;
1230 }
1231
InitializeHashSetIterator(JSThread * thread)1232 void ContainersPrivate::InitializeHashSetIterator(JSThread *thread)
1233 {
1234 JSHandle<GlobalEnv> env = thread->GetEcmaVM()->GetGlobalEnv();
1235 auto globalConst = const_cast<GlobalEnvConstants *>(thread->GlobalConstants());
1236 ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
1237 JSHandle<JSHClass> iteratorFuncHClass =
1238 JSHandle<JSHClass>::Cast(globalConst->GetHandledJSAPIIteratorFuncHClass());
1239
1240 // HashSetIterator.prototype
1241 JSHandle<JSObject> hashSetIteratorPrototype(factory->NewJSObject(iteratorFuncHClass));
1242 // HashSetIterator.prototype.next()
1243 SetFrozenFunction(thread, hashSetIteratorPrototype, "next", JSAPIHashSetIterator::Next, FuncLength::ZERO);
1244 SetStringTagSymbol(thread, env, hashSetIteratorPrototype, "HashSet Iterator");
1245 globalConst->SetConstant(ConstantIndex::HASHSET_ITERATOR_PROTOTYPE_INDEX,
1246 hashSetIteratorPrototype.GetTaggedValue());
1247 }
1248 } // namespace panda::ecmascript::containers
1249