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