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