• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2021-2025 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/builtins/builtins.h"
17 
18 #include "ecmascript/builtins/builtins_ark_tools.h"
19 #include "ecmascript/builtins/builtins_array.h"
20 #include "ecmascript/builtins/builtins_arraybuffer.h"
21 #include "ecmascript/builtins/builtins_async_from_sync_iterator.h"
22 #include "ecmascript/builtins/builtins_async_function.h"
23 #include "ecmascript/builtins/builtins_async_iterator.h"
24 #include "ecmascript/builtins/builtins_async_generator.h"
25 #include "ecmascript/builtins/builtins_atomics.h"
26 #include "ecmascript/builtins/builtins_bigint.h"
27 #include "ecmascript/builtins/builtins_boolean.h"
28 #include "ecmascript/builtins/builtins_cjs_module.h"
29 #include "ecmascript/builtins/builtins_cjs_require.h"
30 #include "ecmascript/builtins/builtins_cjs_exports.h"
31 #include "ecmascript/builtins/builtins_dataview.h"
32 #include "ecmascript/builtins/builtins_date.h"
33 #include "ecmascript/builtins/builtins_errors.h"
34 #include "ecmascript/builtins/builtins_finalization_registry.h"
35 #include "ecmascript/builtins/builtins_function.h"
36 #include "ecmascript/builtins/builtins_gc.h"
37 #include "ecmascript/builtins/builtins_generator.h"
38 #include "ecmascript/builtins/builtins_global.h"
39 #include "ecmascript/builtins/builtins_iterator.h"
40 #include "ecmascript/builtins/builtins_json.h"
41 #include "ecmascript/builtins/builtins_map.h"
42 #include "ecmascript/builtins/builtins_math.h"
43 #include "ecmascript/builtins/builtins_number.h"
44 #include "ecmascript/builtins/builtins_object.h"
45 #include "ecmascript/builtins/builtins_promise.h"
46 #include "ecmascript/builtins/builtins_promise_handler.h"
47 #include "ecmascript/builtins/builtins_promise_job.h"
48 #include "ecmascript/builtins/builtins_proxy.h"
49 #include "ecmascript/builtins/builtins_reflect.h"
50 #include "ecmascript/builtins/builtins_regexp.h"
51 #include "ecmascript/builtins/builtins_set.h"
52 #include "ecmascript/builtins/builtins_sharedarraybuffer.h"
53 #include "ecmascript/builtins/builtins_shared_typedarray.h"
54 #include "ecmascript/builtins/builtins_string_iterator.h"
55 #include "ecmascript/builtins/builtins_symbol.h"
56 #include "ecmascript/builtins/builtins_typedarray.h"
57 #include "ecmascript/builtins/builtins_weak_map.h"
58 #include "ecmascript/builtins/builtins_weak_ref.h"
59 #include "ecmascript/builtins/builtins_weak_set.h"
60 #include "ecmascript/containers/containers_private.h"
61 #include "ecmascript/dfx/native_module_failure_info.h"
62 #include "ecmascript/js_arraybuffer.h"
63 #include "ecmascript/js_array_iterator.h"
64 #include "ecmascript/js_async_function.h"
65 #include "ecmascript/js_async_generator_object.h"
66 #include "ecmascript/js_for_in_iterator.h"
67 #include "ecmascript/js_finalization_registry.h"
68 #include "ecmascript/js_map.h"
69 #include "ecmascript/js_map_iterator.h"
70 #include "ecmascript/js_primitive_ref.h"
71 #include "ecmascript/js_regexp_iterator.h"
72 #include "ecmascript/js_set.h"
73 #include "ecmascript/js_set_iterator.h"
74 #include "ecmascript/js_string_iterator.h"
75 #include "ecmascript/js_async_from_sync_iterator.h"
76 #include "ecmascript/js_weak_container.h"
77 #include "ecmascript/js_weak_ref.h"
78 #include "ecmascript/require/js_cjs_module_cache.h"
79 #include "ecmascript/require/js_cjs_require.h"
80 #include "ecmascript/shared_objects/js_shared_array_iterator.h"
81 #include "ecmascript/shared_objects/js_shared_map_iterator.h"
82 #include "ecmascript/shared_objects/js_shared_set_iterator.h"
83 #include "ecmascript/marker_cell.h"
84 #ifdef ARK_SUPPORT_INTL
85 #include "ecmascript/builtins/builtins_collator.h"
86 #include "ecmascript/builtins/builtins_date_time_format.h"
87 #include "ecmascript/builtins/builtins_displaynames.h"
88 #include "ecmascript/builtins/builtins_intl.h"
89 #include "ecmascript/builtins/builtins_list_format.h"
90 #include "ecmascript/builtins/builtins_locale.h"
91 #include "ecmascript/builtins/builtins_number_format.h"
92 #include "ecmascript/builtins/builtins_plural_rules.h"
93 #include "ecmascript/builtins/builtins_relative_time_format.h"
94 #include "ecmascript/builtins/builtins_segmenter.h"
95 #include "ecmascript/builtins/builtins_segments.h"
96 #include "ecmascript/builtins/builtins_segment_iterator.h"
97 #include "ecmascript/js_collator.h"
98 #include "ecmascript/js_date_time_format.h"
99 #include "ecmascript/js_displaynames.h"
100 #include "ecmascript/js_list_format.h"
101 #include "ecmascript/js_number_format.h"
102 #include "ecmascript/js_plural_rules.h"
103 #include "ecmascript/js_segments.h"
104 #include "ecmascript/js_segment_iterator.h"
105 #endif
106 
107 
108 namespace panda::ecmascript {
109 using Number = builtins::BuiltinsNumber;
110 using BuiltinsBigInt = builtins::BuiltinsBigInt;
111 using Object = builtins::BuiltinsObject;
112 using Date = builtins::BuiltinsDate;
113 using Symbol = builtins::BuiltinsSymbol;
114 using Boolean = builtins::BuiltinsBoolean;
115 using BuiltinsLazyCallback = builtins::BuiltinsLazyCallback;
116 using BuiltinsMap = builtins::BuiltinsMap;
117 using BuiltinsSet = builtins::BuiltinsSet;
118 using BuiltinsWeakMap = builtins::BuiltinsWeakMap;
119 using BuiltinsWeakSet = builtins::BuiltinsWeakSet;
120 using BuiltinsWeakRef = builtins::BuiltinsWeakRef;
121 using BuiltinsFinalizationRegistry = builtins::BuiltinsFinalizationRegistry;
122 using BuiltinsArray = builtins::BuiltinsArray;
123 using BuiltinsTypedArray = builtins::BuiltinsTypedArray;
124 using BuiltinsIterator = builtins::BuiltinsIterator;
125 
126 using Error = builtins::BuiltinsError;
127 using RangeError = builtins::BuiltinsRangeError;
128 using ReferenceError = builtins::BuiltinsReferenceError;
129 using TypeError = builtins::BuiltinsTypeError;
130 using AggregateError = builtins::BuiltinsAggregateError;
131 using URIError = builtins::BuiltinsURIError;
132 using SyntaxError = builtins::BuiltinsSyntaxError;
133 using EvalError = builtins::BuiltinsEvalError;
134 using OOMError = builtins::BuiltinsOOMError;
135 using TerminationError = builtins::BuiltinsTerminationError;
136 using ErrorType = base::ErrorType;
137 using RandomGenerator = base::RandomGenerator;
138 using Global = builtins::BuiltinsGlobal;
139 using BuiltinsString = builtins::BuiltinsString;
140 using StringIterator = builtins::BuiltinsStringIterator;
141 using BuiltinsAsyncFromSyncIterator = builtins::BuiltinsAsyncFromSyncIterator;
142 using RegExp = builtins::BuiltinsRegExp;
143 using Function = builtins::BuiltinsFunction;
144 using Math = builtins::BuiltinsMath;
145 using Atomics = builtins::BuiltinsAtomics;
146 using ArrayBuffer = builtins::BuiltinsArrayBuffer;
147 using Json = builtins::BuiltinsJson;
148 using SendableJson = builtins::BuiltinsSendableJson;
149 using BigIntJson = builtins::BuiltinsBigIntJson;
150 using Proxy = builtins::BuiltinsProxy;
151 using Reflect = builtins::BuiltinsReflect;
152 using AsyncFunction = builtins::BuiltinsAsyncFunction;
153 using GeneratorObject = builtins::BuiltinsGenerator;
154 using Promise = builtins::BuiltinsPromise;
155 using BuiltinsPromiseHandler = builtins::BuiltinsPromiseHandler;
156 using BuiltinsPromiseJob = builtins::BuiltinsPromiseJob;
157 using ErrorType = base::ErrorType;
158 using DataView = builtins::BuiltinsDataView;
159 #ifdef ARK_SUPPORT_INTL
160 using Intl = builtins::BuiltinsIntl;
161 using Locale = builtins::BuiltinsLocale;
162 using DateTimeFormat = builtins::BuiltinsDateTimeFormat;
163 using RelativeTimeFormat = builtins::BuiltinsRelativeTimeFormat;
164 using NumberFormat = builtins::BuiltinsNumberFormat;
165 using Collator = builtins::BuiltinsCollator;
166 using PluralRules = builtins::BuiltinsPluralRules;
167 using DisplayNames = builtins::BuiltinsDisplayNames;
168 using Segmenter = builtins::BuiltinsSegmenter;
169 using Segments = builtins::BuiltinsSegments;
170 using SegmentIterator = builtins::BuiltinsSegmentIterator;
171 using ListFormat = builtins::BuiltinsListFormat;
172 #endif
173 using BuiltinsCjsModule = builtins::BuiltinsCjsModule;
174 using BuiltinsCjsExports = builtins::BuiltinsCjsExports;
175 using BuiltinsCjsRequire = builtins::BuiltinsCjsRequire;
176 
177 using ContainersPrivate = containers::ContainersPrivate;
178 using SharedArrayBuffer = builtins::BuiltinsSharedArrayBuffer;
179 
180 using BuiltinsAsyncIterator = builtins::BuiltinsAsyncIterator;
181 using AsyncGeneratorObject = builtins::BuiltinsAsyncGenerator;
182 
183 static constexpr size_t REGEXP_INLINE_PROPS = 18;
184 
Initialize(const JSHandle<GlobalEnv> & env,JSThread * thread,bool lazyInit,bool isRealm)185 void Builtins::Initialize(const JSHandle<GlobalEnv> &env, JSThread *thread, bool lazyInit, bool isRealm)
186 {
187     thread->CheckSafepointIfSuspended();
188     thread_ = thread;
189     vm_ = thread->GetEcmaVM();
190     factory_ = vm_->GetFactory();
191     sHeap_ = SharedHeap::GetInstance();
192     [[maybe_unused]] EcmaHandleScope scope(thread_);
193     JSHandle<JSTaggedValue> nullHandle(thread, JSTaggedValue::Null());
194 
195     // Object.prototype[hclass]
196     JSHandle<JSHClass> objPrototypeHClass = factory_->NewEcmaHClass(JSObject::SIZE, JSType::JS_OBJECT, nullHandle);
197 
198     // Object.prototype
199     JSHandle<JSObject> objFuncPrototype = factory_->NewJSObject(objPrototypeHClass);
200     JSHandle<JSTaggedValue> objFuncPrototypeVal(objFuncPrototype);
201 
202     // Object.prototype_or_hclass
203     JSHandle<JSHClass> objFuncClass =
204         factory_->NewEcmaHClass(JSObject::SIZE, JSType::JS_OBJECT, objFuncPrototypeVal);
205     env->SetObjectFunctionClass(thread_, objFuncClass);
206 
207     // GLobalObject.prototype_or_hclass
208     JSHandle<JSHClass> globalObjFuncClass =
209         factory_->NewEcmaHClass(JSObject::SIZE, JSType::JS_GLOBAL_OBJECT, 0);
210     globalObjFuncClass->SetPrototype(thread_, objFuncPrototypeVal.GetTaggedValue());
211     globalObjFuncClass->SetIsDictionaryMode(true);
212 
213     // PrimitiveRef.prototype_or_hclass
214     JSHandle<JSHClass> primRefObjHClass =
215         factory_->NewEcmaHClass(JSPrimitiveRef::SIZE, JSType::JS_PRIMITIVE_REF, objFuncPrototypeVal);
216 
217     // init global object
218     JSHandle<JSObject> globalObject = factory_->NewNonMovableJSObject(globalObjFuncClass);
219     env->SetJSGlobalObject(thread_, globalObject);
220 
221     // init global patch
222     JSHandle<TaggedArray> globalPatch = factory_->EmptyArray();
223     env->SetGlobalPatch(thread, globalPatch);
224 
225     auto runtimeGlobalEnv = Runtime::GetInstance()->GetGlobalEnv();
226     if (runtimeGlobalEnv.IsHole()) {
227         InitializeSSymbolAttributes(env);
228         InitializeSObjectAndSFunction(env);
229     } else {
230         CopySObjectAndSFunction(env, runtimeGlobalEnv);
231         RegisterSendableContainers(env);
232     }
233     InitializeFunction(env, objFuncPrototypeVal);
234 
235     thread->CheckSafepointIfSuspended();
236     JSHandle<JSHClass> asyncAwaitStatusFuncClass =
237         factory_->CreateFunctionClass(FunctionKind::NORMAL_FUNCTION, JSAsyncAwaitStatusFunction::SIZE,
238                                       JSType::JS_ASYNC_AWAIT_STATUS_FUNCTION, env->GetFunctionPrototype());
239     env->SetAsyncAwaitStatusFunctionClass(thread_, asyncAwaitStatusFuncClass);
240 
241     JSHandle<JSHClass> asyncGeneratorResNextRetProRstFtnClass =
242         factory_->NewEcmaHClass(JSAsyncGeneratorResNextRetProRstFtn::SIZE,
243                                 JSType::JS_ASYNC_GENERATOR_RESUME_NEXT_RETURN_PROCESSOR_RST_FTN,
244                                 env->GetFunctionPrototype());
245     asyncGeneratorResNextRetProRstFtnClass->SetCallable(true);
246     asyncGeneratorResNextRetProRstFtnClass->SetExtensible(true);
247     env->SetAsyncGeneratorResNextRetProRstFtnClass(thread_, asyncGeneratorResNextRetProRstFtnClass);
248 
249     JSHandle<JSHClass> proxyRevocFuncClass = factory_->NewEcmaHClass(
250         JSProxyRevocFunction::SIZE, JSType::JS_PROXY_REVOC_FUNCTION, env->GetFunctionPrototype());
251     proxyRevocFuncClass->SetCallable(true);
252     proxyRevocFuncClass->SetExtensible(true);
253     env->SetProxyRevocFunctionClass(thread_, proxyRevocFuncClass);
254 
255     // Object = new Function()
256     JSHandle<JSObject> objectFunction(
257         NewBuiltinConstructor(env, objFuncPrototype, Object::ObjectConstructor, "Object",
258                               FunctionLength::ONE, BUILTINS_STUB_ID(ObjectConstructor)));
259     JSFunction::SetFunctionPrototypeOrInstanceHClass(thread_, JSHandle<JSFunction>(objectFunction),
260                                                      objFuncClass.GetTaggedValue());
261     // initialize object method.
262     env->SetObjectFunction(thread_, objectFunction);
263     env->SetObjectFunctionPrototype(thread_, objFuncPrototype);
264     thread_->SetInitialBuiltinHClass(
265         BuiltinTypeId::OBJECT, objectFunction->GetJSHClass(), *objFuncClass, objFuncPrototype->GetJSHClass());
266 
267     JSHandle<JSHClass> functionClass = factory_->CreateFunctionClass(FunctionKind::BASE_CONSTRUCTOR, JSFunction::SIZE,
268                                                                      JSType::JS_FUNCTION, env->GetFunctionPrototype());
269     env->SetFunctionClassWithProto(thread_, functionClass);
270     functionClass = factory_->CreateFunctionClass(FunctionKind::NORMAL_FUNCTION, JSFunction::SIZE, JSType::JS_FUNCTION,
271                                                   env->GetFunctionPrototype());
272     env->SetFunctionClassWithoutProto(thread_, functionClass);
273     functionClass = factory_->CreateFunctionClass(FunctionKind::CLASS_CONSTRUCTOR, JSFunction::SIZE,
274                                                   JSType::JS_FUNCTION, env->GetFunctionPrototype());
275     env->SetFunctionClassWithoutName(thread_, functionClass);
276 
277     thread->CheckSafepointIfSuspended();
278     InitializeBoundFunctionClass(env);
279     if (!isRealm) {
280         InitializeAllTypeError(env, objFuncClass);
281         InitializeSymbol(env, primRefObjHClass);
282         InitializeBigInt(env, primRefObjHClass);
283     } else {
284         // error and symbol need to be shared when initialize realm
285         InitializeAllTypeErrorWithRealm(env);
286         InitializeSymbolWithRealm(env, primRefObjHClass);
287         InitializeBigIntWithRealm(env);
288     }
289 
290     thread->CheckSafepointIfSuspended();
291     InitializeArray(env, objFuncPrototypeVal, isRealm);
292     if (lazyInit) {
293         LazyInitializeDate(env);
294         LazyInitializeSet(env);
295         LazyInitializeMap(env);
296         LazyInitializeWeakMap(env);
297         LazyInitializeWeakSet(env);
298         LazyInitializeWeakRef(env);
299         LazyInitializeFinalizationRegistry(env);
300         LazyInitializeTypedArray(env);
301         LazyInitializeArrayBuffer(env);
302         LazyInitializeDataView(env);
303         LazyInitializeSharedArrayBuffer(env);
304     } else {
305         InitializeDate(env, objFuncPrototypeVal);
306         InitializeSet(env, objFuncPrototypeVal);
307         InitializeMap(env, objFuncPrototypeVal);
308         InitializeWeakMap(env, objFuncClass);
309         InitializeWeakSet(env, objFuncClass);
310         InitializeWeakRef(env, objFuncClass);
311         InitializeFinalizationRegistry(env, objFuncClass);
312         InitializeTypedArray(env, objFuncPrototypeVal);
313         InitializeArrayBuffer(env, objFuncClass);
314         InitializeDataView(env, objFuncPrototypeVal);
315         InitializeSharedArrayBuffer(env, objFuncClass);
316     }
317     thread->CheckSafepointIfSuspended();
318     InitializeNumber(env, globalObject, primRefObjHClass);
319     InitializeObject(env, objFuncPrototype, objectFunction);
320     InitializeBoolean(env, primRefObjHClass);
321     InitializeRegExp(env);
322     InitializeString(env, objFuncPrototypeVal);
323     JSHandle<JSHClass> argumentsClass = factory_->CreateJSArguments(env);
324     env->SetArgumentsClass(thread_, argumentsClass);
325     SetArgumentsSharedAccessor(env);
326 
327     InitializeMath(env, objFuncPrototypeVal);
328     InitializeGlobalObject(env, globalObject);
329     InitializeAtomics(env, objFuncPrototypeVal);
330     InitializeJson(env, objFuncPrototypeVal);
331     InitializeIterator(env, objFuncClass);
332     InitializeAsyncIterator(env, objFuncClass);
333     InitializeAsyncFromSyncIterator(env, objFuncClass);
334     InitializeProxy(env);
335     InitializeReflect(env, objFuncPrototypeVal);
336     InitializeAsyncFunction(env, objFuncClass);
337     InitializeGenerator(env, objFuncClass);
338     InitializeAsyncGenerator(env, objFuncClass);
339     InitializeGeneratorFunction(env, objFuncClass);
340     InitializeAsyncGeneratorFunction(env, objFuncClass);
341     InitializePromise(env, objFuncClass);
342     InitializePromiseJob(env);
343     thread->CheckSafepointIfSuspended();
344 #ifdef ARK_SUPPORT_INTL
345     InitializeIntl(env, objFuncPrototypeVal);
346     if (lazyInit) {
347         LazyInitializeLocale(env);
348         LazyInitializeDateTimeFormat(env);
349         LazyInitializeNumberFormat(env);
350         LazyInitializeRelativeTimeFormat(env);
351         LazyInitializeCollator(env);
352         LazyInitializePluralRules(env);
353         LazyInitializeDisplayNames(env);
354         LazyInitializeListFormat(env);
355         LazyInitializeSegments(env);
356         LazyInitializeSegmenter(env);
357     } else {
358         InitializeLocale(env);
359         InitializeDateTimeFormat(env);
360         InitializeNumberFormat(env);
361         InitializeRelativeTimeFormat(env);
362         InitializeCollator(env);
363         InitializePluralRules(env);
364         InitializeDisplayNames(env);
365         InitializeListFormat(env);
366         InitializeSegments(env);
367         InitializeSegmenter(env);
368     }
369     thread->CheckSafepointIfSuspended();
370 #endif
371     InitializeModuleNamespace(env, objFuncClass);
372     InitializeNativeModuleFailureInfo(env, objFuncClass);
373     InitializeCjsModule(env);
374     InitializeCjsExports(env);
375     InitializeCjsRequire(env);
376     InitializeDefaultExportOfScript(env);
377     InitializePropertyDetector(env, lazyInit);
378     InitializeNapiHClass(env, objFuncClass);
379     JSHandle<JSHClass> generatorFuncClass =
380         factory_->CreateFunctionClass(FunctionKind::GENERATOR_FUNCTION, JSFunction::SIZE, JSType::JS_GENERATOR_FUNCTION,
381                                       env->GetGeneratorFunctionPrototype());
382     env->SetGeneratorFunctionClass(thread_, generatorFuncClass);
383 
384     JSHandle<JSHClass> asyncGenetatorFuncClass =
385         factory_->CreateFunctionClass(FunctionKind::ASYNC_GENERATOR_FUNCTION, JSFunction::SIZE,
386                                       JSType::JS_ASYNC_GENERATOR_FUNCTION, env->GetAsyncGeneratorFunctionPrototype());
387     env->SetAsyncGeneratorFunctionClass(thread_, asyncGenetatorFuncClass);
388     env->SetObjectFunctionPrototypeClass(thread_, JSTaggedValue(objFuncPrototype->GetClass()));
389     JSHandle<JSHClass> asyncFuncClass = factory_->CreateFunctionClass(
390         FunctionKind::ASYNC_FUNCTION, JSAsyncFunction::SIZE, JSType::JS_ASYNC_FUNCTION,
391         env->GetAsyncFunctionPrototype());
392     env->SetAsyncFunctionClass(thread_, asyncFuncClass);
393     env->InitializeGuardians();
394 
395     thread->CheckSafepointIfSuspended();
396     if (vm_->GetJSOptions().IsEnableLoweringBuiltin() && !isRealm) {
397         if (!lazyInit) {
398             thread_->InitializeBuiltinObject(env);
399         }
400     }
401 }
402 
InitializeBoundFunctionClass(const JSHandle<GlobalEnv> & env) const403 void Builtins::InitializeBoundFunctionClass(const JSHandle<GlobalEnv> &env) const
404 {
405     JSHandle<JSTaggedValue> proto = env->GetFunctionPrototype();
406     JSHandle<JSHClass> hclass = factory_->NewEcmaHClass(JSBoundFunction::SIZE, JSType::JS_BOUND_FUNCTION, proto);
407     hclass->SetCallable(true);
408 
409     // set hclass layout
410     uint32_t fieldOrder = 0;
411     const GlobalEnvConstants *globalConst = thread_->GlobalConstants();
412     ASSERT(JSFunction::LENGTH_INLINE_PROPERTY_INDEX == fieldOrder);
413     JSHandle<LayoutInfo> layoutInfoHandle = factory_->CreateLayoutInfo(JSFunction::LENGTH_OF_INLINE_PROPERTIES);
414     {
415         PropertyAttributes attributes = PropertyAttributes::DefaultAccessor(false, false, true);
416         attributes.SetIsInlinedProps(true);
417         attributes.SetRepresentation(Representation::TAGGED);
418         attributes.SetOffset(fieldOrder);
419         layoutInfoHandle->AddKey(thread_, fieldOrder, globalConst->GetLengthString(), attributes);
420         fieldOrder++;
421     }
422 
423     ASSERT(JSFunction::NAME_INLINE_PROPERTY_INDEX == fieldOrder);
424     // not set name in-object property on class which may have a name() method
425     {
426         PropertyAttributes attributes = PropertyAttributes::DefaultAccessor(false, false, true);
427         attributes.SetIsInlinedProps(true);
428         attributes.SetRepresentation(Representation::TAGGED);
429         attributes.SetOffset(fieldOrder);
430         layoutInfoHandle->AddKey(thread_, fieldOrder,
431                                  globalConst->GetHandledNameString().GetTaggedValue(), attributes);
432         fieldOrder++;
433     }
434 
435     {
436         hclass->SetLayout(thread_, layoutInfoHandle);
437         hclass->SetNumberOfProps(fieldOrder);
438     }
439     env->SetBoundFunctionClass(thread_, hclass);
440 }
441 
InitializePropertyDetector(const JSHandle<GlobalEnv> & env,bool lazyInit) const442 void Builtins::InitializePropertyDetector(const JSHandle<GlobalEnv> &env, bool lazyInit) const
443 {
444     if (lazyInit) {
445         env->SetBitField(GlobalEnv::DEFAULT_LAZY_BITFIELD_VALUE);
446     }
447 }
448 
InitializeNapiHClass(const JSHandle<GlobalEnv> & env,const JSHandle<JSHClass> & objFuncClass) const449 void Builtins::InitializeNapiHClass(const JSHandle<GlobalEnv> &env,
450                                     const JSHandle<JSHClass> &objFuncClass) const
451 {
452     JSHandle<JSHClass> newJsHClass = JSHClass::Clone(thread_, objFuncClass);
453     env->SetObjectFunctionNapiClass(thread_, newJsHClass);
454     env->SetObjectFunctionTsNapiClass(thread_, newJsHClass);
455 }
456 
SetLazyAccessor(const JSHandle<JSObject> & object,const JSHandle<JSTaggedValue> & key,const JSHandle<AccessorData> & accessor) const457 void Builtins::SetLazyAccessor(const JSHandle<JSObject> &object, const JSHandle<JSTaggedValue> &key,
458     const JSHandle<AccessorData> &accessor) const
459 {
460     PropertyDescriptor descriptor(thread_, JSHandle<JSTaggedValue>::Cast(accessor), true, false, true);
461     JSObject::DefineOwnProperty(thread_, object, key, descriptor);
462 }
463 
InitializeGlobalObject(const JSHandle<GlobalEnv> & env,const JSHandle<JSObject> & globalObject)464 void Builtins::InitializeGlobalObject(const JSHandle<GlobalEnv> &env, const JSHandle<JSObject> &globalObject)
465 {
466     [[maybe_unused]] EcmaHandleScope scope(thread_);
467 
468     // Global object test
469     SetFunction(env, globalObject, "print", Global::PrintEntrypoint, 0);
470     SetFunction(env, globalObject, "markModuleCollectable", Global::MarkModuleCollectable, 0);
471     SetFunction(env, globalObject, "isSendable", Global::IsSendable, 0);
472     SetFunction(env, globalObject, "loadNativeModule", Global::LoadNativeModule, 0);
473 #if ECMASCRIPT_ENABLE_RUNTIME_STAT
474     SetFunction(env, globalObject, "startRuntimeStat", Global::StartRuntimeStat, 0);
475     SetFunction(env, globalObject, "stopRuntimeStat", Global::StopRuntimeStat, 0);
476 #endif
477 
478 #if ECMASCRIPT_ENABLE_OPT_CODE_PROFILER
479     SetFunction(env, globalObject, "printOptStat", Global::PrintOptStat, 0);
480 #endif
481 
482 #if ECMASCRIPT_ENABLE_MEGA_PROFILER
483     SetFunction(env, globalObject, "printMegaICStat", Global::PrintMegaICStat, 0);
484 #endif
485 
486 #if ECMASCRIPT_ENABLE_FUNCTION_CALL_TIMER
487     SetFunction(env, globalObject, "printFunctionCallStat", Global::PrintFunctionCallStat, 0);
488 #endif
489 
490     if (vm_->GetJSOptions().EnableArkTools()) {
491         JSHandle<JSTaggedValue> arkTools(InitializeArkTools(env));
492         SetConstantObject(globalObject, "ArkTools", arkTools);
493     }
494 
495 #if ECMASCRIPT_ENABLE_ARK_CONTAINER
496     // Set ArkPrivate
497     JSHandle<JSTaggedValue> arkPrivate(InitializeArkPrivate(env));
498     SetConstantObject(globalObject, "ArkPrivate", arkPrivate);
499 #endif
500 
501     // Global object function
502     SetFunction(env, globalObject, "eval", Global::NotSupportEval, FunctionLength::ONE);
503     SetFunction(env, globalObject, "isFinite", Global::IsFinite, FunctionLength::ONE,
504                 BUILTINS_STUB_ID(GlobalIsFinite));
505     SetFunction(env, globalObject, "isNaN", Global::IsNaN, FunctionLength::ONE,
506                 BUILTINS_STUB_ID(GlobalIsNan));
507     SetFunction(env, globalObject, "decodeURI", Global::DecodeURI, FunctionLength::ONE);
508     SetFunction(env, globalObject, "encodeURI", Global::EncodeURI, FunctionLength::ONE);
509     SetFunction(env, globalObject, "escape", Global::Escape, FunctionLength::ONE);
510     SetFunction(env, globalObject, "unescape", Global::Unescape, FunctionLength::ONE);
511     SetFunction(env, globalObject, "decodeURIComponent", Global::DecodeURIComponent, FunctionLength::ONE,
512                 BUILTINS_STUB_ID(GlobalDecodeURIComponent));
513     SetFunction(env, globalObject, "encodeURIComponent", Global::EncodeURIComponent, FunctionLength::ONE);
514     SetFunction(env, globalObject, "__getCurrentModuleName__", Global::GetCurrentModuleName, FunctionLength::ZERO);
515     SetFunction(env, globalObject, "__getCurrentBundleName__", Global::GetCurrentBundleName, FunctionLength::ZERO);
516 
517     // Global object property
518     SetGlobalThis(globalObject, "globalThis", JSHandle<JSTaggedValue>::Cast(globalObject));
519     SetConstant(globalObject, "Infinity", JSTaggedValue(base::POSITIVE_INFINITY));
520     SetConstant(globalObject, "NaN", JSTaggedValue(base::NAN_VALUE));
521     SetConstant(globalObject, "undefined", JSTaggedValue::Undefined());
522 }
523 
CreateFunctionPrototypeHClass(const JSHandle<GlobalEnv> & env,const JSHandle<JSTaggedValue> & ObjPrototypeVal) const524 JSHandle<JSHClass> Builtins::CreateFunctionPrototypeHClass(const JSHandle<GlobalEnv> &env,
525     const JSHandle<JSTaggedValue> &ObjPrototypeVal) const
526 {
527     uint32_t index = 0;
528     PropertyAttributes attributes = PropertyAttributes::Default(false, false, false);
529     attributes.SetIsInlinedProps(true);
530     attributes.SetRepresentation(Representation::TAGGED);
531     auto properties = Function::GetFunctionPrototypeProperties();
532     uint32_t length = properties.size();
533     JSHandle<LayoutInfo> layout = factory_->CreateLayoutInfo(length);
534     JSHandle<JSTaggedValue> keyString;
535     for (const base::BuiltinsPropertyConfig &each : properties) {
536         attributes.SetOffset(index);
537         attributes.SetIsAccessor(each.GetIsAccessor());
538         attributes.SetWritable(each.GetWritable());
539         attributes.SetEnumerable(each.GetEnumerable());
540         attributes.SetConfigurable(each.GetConfigurable());
541         if (each.GetName() == "[Symbol.hasInstance]") {
542             keyString = env->GetHasInstanceSymbol();
543         } else {
544             keyString = JSHandle<JSTaggedValue>(factory_->NewFromUtf8ReadOnly(each.GetName()));
545         }
546         layout->AddKey(thread_, index++, keyString.GetTaggedValue(), attributes);
547     }
548     JSHandle<JSHClass> objPrototypeHClass =
549         factory_->NewEcmaHClass(JSFunction::SIZE, length, JSType::JS_FUNCTION, ObjPrototypeVal,
550                                 JSHandle<JSTaggedValue>(layout));
551     objPrototypeHClass->SetCallable(true);
552     return objPrototypeHClass;
553 }
554 
CreateFunctionHClass(const JSHandle<JSFunction> & funcPrototype) const555 JSHandle<JSHClass> Builtins::CreateFunctionHClass(const JSHandle<JSFunction> &funcPrototype) const
556 {
557     uint32_t index = 0;
558     PropertyAttributes attributes = PropertyAttributes::Default(false, false, false);
559     attributes.SetIsInlinedProps(true);
560     attributes.SetRepresentation(Representation::TAGGED);
561     auto properties = Function::GetFunctionProperties();
562     uint32_t length = properties.size();
563     JSHandle<LayoutInfo> layout = factory_->CreateLayoutInfo(length);
564     for (const base::BuiltinsPropertyConfig &each : properties) {
565         attributes.SetOffset(index);
566         attributes.SetIsAccessor(each.GetIsAccessor());
567         attributes.SetWritable(each.GetWritable());
568         attributes.SetEnumerable(each.GetEnumerable());
569         attributes.SetConfigurable(each.GetConfigurable());
570         JSHandle<JSTaggedValue> keyString(factory_->NewFromUtf8ReadOnly(each.GetName()));
571         layout->AddKey(thread_, index++, keyString.GetTaggedValue(), attributes);
572     }
573     JSHandle<JSHClass> objPrototypeHClass =
574         factory_->NewEcmaHClass(JSFunction::SIZE, length, JSType::JS_FUNCTION,
575                                 JSHandle<JSTaggedValue>(funcPrototype), JSHandle<JSTaggedValue>(layout));
576     objPrototypeHClass->SetConstructor(true);
577     objPrototypeHClass->SetCallable(true);
578     return objPrototypeHClass;
579 }
580 
SetFunctionName(const JSHandle<JSFunction> & ctor,std::string_view name) const581 void Builtins::SetFunctionName(const JSHandle<JSFunction> &ctor, std::string_view name) const
582 {
583     JSHandle<JSTaggedValue> nameString(factory_->NewFromUtf8ReadOnly(name));
584     SetSFunctionName(ctor, nameString);
585 }
586 
SetFunctionName(const JSHandle<JSFunction> & ctor,const JSHandle<JSTaggedValue> & name) const587 void Builtins::SetFunctionName(const JSHandle<JSFunction> &ctor, const JSHandle<JSTaggedValue> &name) const
588 {
589     auto nameIndex = JSFunction::NAME_INLINE_PROPERTY_INDEX;
590     ctor->SetPropertyInlinedProps(thread_, nameIndex, name.GetTaggedValue());
591 }
592 
SetFunctionLength(const JSHandle<JSFunction> & ctor,int length) const593 void Builtins::SetFunctionLength(const JSHandle<JSFunction> &ctor, int length) const
594 {
595     JSTaggedValue taggedLength(length);
596     auto lengthIndex = JSFunction::LENGTH_INLINE_PROPERTY_INDEX;
597     ctor->SetPropertyInlinedProps(thread_, lengthIndex, taggedLength);
598 }
599 
SetFunctionPrototype(const JSHandle<JSFunction> & ctor,const JSTaggedValue & prototype) const600 void Builtins::SetFunctionPrototype(const JSHandle<JSFunction> &ctor, const JSTaggedValue &prototype) const
601 {
602     auto prototypeIndex = JSFunction::PROTOTYPE_INLINE_PROPERTY_INDEX;
603     ctor->SetPropertyInlinedProps(thread_, prototypeIndex, prototype);
604 }
605 
SetInlineFunction(const JSHandle<GlobalEnv> & env,const JSHandle<JSObject> & obj,std::string_view key,EcmaEntrypoint func,uint32_t index,int length,kungfu::BuiltinsStubCSigns::ID builtinId) const606 void Builtins::SetInlineFunction(const JSHandle<GlobalEnv> &env, const JSHandle<JSObject> &obj, std::string_view key,
607                                  EcmaEntrypoint func, uint32_t index, int length,
608                                  kungfu::BuiltinsStubCSigns::ID builtinId) const
609 {
610     JSHandle<JSTaggedValue> keyString(factory_->NewFromUtf8ReadOnly(key));
611     SetInlineFunction(env, obj, keyString, func, index, length, builtinId);
612 }
613 
SetInlineFunction(const JSHandle<GlobalEnv> & env,const JSHandle<JSObject> & obj,const JSHandle<JSTaggedValue> & key,EcmaEntrypoint func,uint32_t index,int length,kungfu::BuiltinsStubCSigns::ID builtinId) const614 void Builtins::SetInlineFunction(const JSHandle<GlobalEnv> &env, const JSHandle<JSObject> &obj,
615                                  const JSHandle<JSTaggedValue> &key, EcmaEntrypoint func, uint32_t index, int length,
616                                  kungfu::BuiltinsStubCSigns::ID builtinId) const
617 {
618     JSHandle<JSFunction> function(NewFunction(env, key, func, length, builtinId));
619     obj->SetPropertyInlinedProps(thread_, index, function.GetTaggedValue());
620 }
621 
SetInlineFunctionAndRetJSFunction(const JSHandle<GlobalEnv> & env,const JSHandle<JSObject> & obj,std::string_view key,EcmaEntrypoint func,uint32_t index,int length,kungfu::BuiltinsStubCSigns::ID builtinId) const622 JSHandle<JSFunction> Builtins::SetInlineFunctionAndRetJSFunction(const JSHandle<GlobalEnv> &env,
623     const JSHandle<JSObject> &obj, std::string_view key,
624     EcmaEntrypoint func, uint32_t index, int length,
625     kungfu::BuiltinsStubCSigns::ID builtinId) const
626 {
627     JSHandle<JSTaggedValue> keyString(factory_->NewFromUtf8ReadOnly(key));
628     JSHandle<JSFunction> function(NewFunction(env, keyString, func, length, builtinId));
629     obj->SetPropertyInlinedProps(thread_, index, function.GetTaggedValue());
630     return function;
631 }
632 
SetInlineAccessor(const JSHandle<JSObject> & obj,uint32_t index,const JSHandle<JSTaggedValue> & getter,const JSHandle<JSTaggedValue> & setter) const633 void Builtins::SetInlineAccessor(const JSHandle<JSObject> &obj, uint32_t index,
634                                  const JSHandle<JSTaggedValue> &getter, const JSHandle<JSTaggedValue> &setter) const
635 {
636     JSHandle<AccessorData> accessor = factory_->NewAccessorData();
637     accessor->SetGetter(thread_, getter);
638     accessor->SetSetter(thread_, setter);
639     obj->SetPropertyInlinedProps(thread_, index, accessor.GetTaggedValue());
640 }
641 
StrictModeForbiddenAccessCallerArguments(const JSHandle<GlobalEnv> & env,uint32_t & index,const JSHandle<JSObject> & prototype) const642 void Builtins::StrictModeForbiddenAccessCallerArguments(const JSHandle<GlobalEnv> &env, uint32_t &index,
643                                                         const JSHandle<JSObject> &prototype) const
644 {
645     auto function = JSHandle<JSTaggedValue>::Cast(
646         factory_->NewJSBuiltinFunction(env, reinterpret_cast<void *>(JSFunction::AccessCallerArgumentsThrowTypeError)));
647     // "caller"
648     SetInlineAccessor(prototype, index++, function, function);
649     // "arguments"
650     SetInlineAccessor(prototype, index++, function, function);
651 }
652 
InitializeFunctionPrototype(const JSHandle<GlobalEnv> & env,JSHandle<JSFunction> & funcFuncPrototype,JSHandle<JSFunction> & funcFunc) const653 void Builtins::InitializeFunctionPrototype(const JSHandle<GlobalEnv> &env, JSHandle<JSFunction> &funcFuncPrototype,
654                                            JSHandle<JSFunction> &funcFunc) const
655 {
656     auto funcFuncPrototypeObj = JSHandle<JSObject>(funcFuncPrototype);
657     SetFunctionLength(funcFuncPrototype, FunctionLength::ZERO);
658     SetFunctionName(funcFuncPrototype, thread_->GlobalConstants()->GetHandledEmptyString());
659     uint32_t fieldIndex = 2; // 2: length and name
660     funcFuncPrototype->SetPropertyInlinedProps(thread_, fieldIndex++, funcFunc.GetTaggedValue()); // constructor
661     StrictModeForbiddenAccessCallerArguments(env, fieldIndex, funcFuncPrototypeObj);
662     // Function.prototype method
663     for (const base::BuiltinFunctionEntry &entry: Function::GetFunctionPrototypeFunctions()) {
664         SetInlineFunction(env, funcFuncPrototypeObj, entry.GetName(), entry.GetEntrypoint(), fieldIndex++,
665                           entry.GetLength(), entry.GetBuiltinStubId());
666     }
667     // 19.2.3.5 Function.prototype.toString ( )
668     SetInlineFunction(env, funcFuncPrototypeObj, thread_->GlobalConstants()->GetHandledToStringString(),
669                       Function::FunctionPrototypeToString, fieldIndex++, FunctionLength::ZERO);
670     JSHandle<JSFunction> function = SetInlineFunctionAndRetJSFunction(
671         env, funcFuncPrototypeObj, "[Symbol.hasInstance]",
672         Function::FunctionPrototypeHasInstance, fieldIndex++, FunctionLength::ONE,
673         BUILTINS_STUB_ID(FunctionPrototypeHasInstance));
674     env->SetHasInstanceFunction(thread_, function);
675 }
676 
InitializeFunction(const JSHandle<GlobalEnv> & env,JSHandle<JSTaggedValue> & objFuncPrototypeVal) const677 void Builtins::InitializeFunction(const JSHandle<GlobalEnv> &env, JSHandle<JSTaggedValue> &objFuncPrototypeVal) const
678 {
679     [[maybe_unused]] EcmaHandleScope scope(thread_);
680     // Function.prototype.hclass
681     JSHandle<JSHClass> funcPrototypeHClass = CreateFunctionPrototypeHClass(env, objFuncPrototypeVal);
682     // Function.prototype
683     JSHandle<JSFunction> funcFuncPrototype = factory_->NewJSFunctionByHClassWithoutAccessor(
684         env, reinterpret_cast<void *>(Function::FunctionPrototypeInvokeSelf), funcPrototypeHClass);
685 
686     JSHandle<JSTaggedValue> funcFuncPrototypeValue(funcFuncPrototype);
687     // Function.prototype_or_hclass
688     JSHandle<JSHClass> funcFuncIntanceHClass =
689         factory_->NewEcmaHClass(JSFunction::SIZE, JSType::JS_FUNCTION, funcFuncPrototypeValue);
690     funcFuncIntanceHClass->SetConstructor(true);
691     // Function.hclass
692     JSHandle<JSHClass> funcHClass = CreateFunctionHClass(funcFuncPrototype);
693     // Function = new Function() (forbidden use NewBuiltinConstructor)
694     JSHandle<JSFunction> funcFunc =
695         factory_->NewJSFunctionByHClassWithoutAccessor(env, reinterpret_cast<void *>(Function::FunctionConstructor),
696         funcHClass, FunctionKind::BUILTIN_CONSTRUCTOR);
697 
698     // set properties for Function
699     SetFunctionLength(funcFunc, FunctionLength::ONE);
700     SetFunctionName(funcFunc, "Function");
701     SetFunctionPrototype(funcFunc, funcFuncPrototypeValue.GetTaggedValue());
702 
703     JSHandle<JSTaggedValue> nameString(factory_->NewFromUtf8ReadOnly("Function"));
704     JSHandle<JSObject> globalObject(thread_, env->GetGlobalObject());
705     PropertyDescriptor descriptor2(thread_, JSHandle<JSTaggedValue>::Cast(funcFunc), true, false, true);
706     JSObject::DefineOwnProperty(thread_, globalObject, nameString, descriptor2);
707 
708     JSFunction::SetFunctionPrototypeOrInstanceHClass(thread_, funcFunc, funcFuncIntanceHClass.GetTaggedValue());
709     env->SetFunctionFunction(thread_, funcFunc);
710     env->SetFunctionPrototype(thread_, funcFuncPrototype);
711 
712     JSHandle<JSHClass> normalFuncClass =
713         factory_->NewEcmaHClass(JSFunction::SIZE, JSType::JS_FUNCTION, env->GetFunctionPrototype());
714     env->SetNormalFunctionClass(thread_, normalFuncClass);
715 
716     JSHandle<JSHClass> jSIntlBoundFunctionClass =
717         factory_->CreateFunctionClass(FunctionKind::NORMAL_FUNCTION, JSIntlBoundFunction::SIZE,
718                                       JSType::JS_INTL_BOUND_FUNCTION, env->GetFunctionPrototype());
719     env->SetJSIntlBoundFunctionClass(thread_, jSIntlBoundFunctionClass);
720 
721     JSHandle<JSHClass> constructorFunctionClass =
722         factory_->NewEcmaHClass(JSFunction::SIZE, JSType::JS_FUNCTION, env->GetFunctionPrototype());
723     constructorFunctionClass->SetConstructor(true);
724     env->SetConstructorFunctionClass(thread_, constructorFunctionClass);
725     InitializeFunctionPrototype(env, funcFuncPrototype, funcFunc);
726 }
727 
InitializeObject(const JSHandle<GlobalEnv> & env,const JSHandle<JSObject> & objFuncPrototype,const JSHandle<JSObject> & objFunc)728 void Builtins::InitializeObject(const JSHandle<GlobalEnv> &env, const JSHandle<JSObject> &objFuncPrototype,
729                                 const JSHandle<JSObject> &objFunc)
730 {
731     [[maybe_unused]] EcmaHandleScope scope(thread_);
732     // Object method.
733     for (const base::BuiltinFunctionEntry &entry: Object::GetObjectFunctions()) {
734         SetFunction(env, objFunc, entry.GetName(), entry.GetEntrypoint(),
735                     entry.GetLength(), entry.GetBuiltinStubId());
736     }
737     // Object.prototype method
738     for (const base::BuiltinFunctionEntry &entry: Object::GetObjectPrototypeFunctions()) {
739         SetFunction(env, objFuncPrototype, entry.GetName(), entry.GetEntrypoint(),
740                     entry.GetLength(), entry.GetBuiltinStubId());
741     }
742 
743     // B.2.2.1 Object.prototype.__proto__
744     JSHandle<JSTaggedValue> protoKey(factory_->NewFromASCIIReadOnly("__proto__"));
745     JSHandle<JSTaggedValue> protoGetter = CreateGetter(env, Object::ProtoGetter, "__proto__", FunctionLength::ZERO);
746     JSHandle<JSTaggedValue> protoSetter = CreateSetter(env, Object::ProtoSetter, "__proto__", FunctionLength::ONE);
747     SetAccessor(objFuncPrototype, protoKey, protoGetter, protoSetter);
748 
749     env->SetObjectGetProto(thread_, protoGetter);
750 
751     GlobalIndex globalIndex;
752     globalIndex.UpdateGlobalEnvId(static_cast<size_t>(GlobalEnvField::OBJECT_FUNCTION_CLASS_INDEX));
753     thread_->SetInitialBuiltinGlobalHClass(objFunc->GetJSHClass(), globalIndex);
754 }
755 
InitializeSymbol(const JSHandle<GlobalEnv> & env,const JSHandle<JSHClass> & objFuncClass) const756 void Builtins::InitializeSymbol(const JSHandle<GlobalEnv> &env, const JSHandle<JSHClass> &objFuncClass) const
757 {
758     [[maybe_unused]] EcmaHandleScope scope(thread_);
759     const GlobalEnvConstants *globalConst = thread_->GlobalConstants();
760     // Symbol.prototype
761     JSHandle<JSObject> symbolFuncPrototype = factory_->NewJSObjectWithInit(objFuncClass);
762     JSHandle<JSTaggedValue> symbolFuncPrototypeValue(symbolFuncPrototype);
763 
764     // Symbol.prototype_or_hclass
765     JSHandle<JSHClass> symbolFuncInstanceHClass =
766         factory_->NewEcmaHClass(JSPrimitiveRef::SIZE, JSType::JS_PRIMITIVE_REF, symbolFuncPrototypeValue);
767 
768     // Symbol = new Function()
769     JSHandle<JSObject> symbolFunction(
770         NewBuiltinConstructor(env, symbolFuncPrototype, Symbol::SymbolConstructor, "Symbol", FunctionLength::ZERO));
771     JSFunction::SetFunctionPrototypeOrInstanceHClass(thread_,
772         JSHandle<JSFunction>(symbolFunction), symbolFuncInstanceHClass.GetTaggedValue());
773 
774     // "constructor" property on the prototype
775     JSHandle<JSTaggedValue> constructorKey = globalConst->GetHandledConstructorString();
776     PropertyDescriptor descriptor(thread_, JSHandle<JSTaggedValue>::Cast(symbolFunction), true, false, true);
777     JSObject::DefineOwnProperty(thread_, symbolFuncPrototype, constructorKey, descriptor);
778 
779     for (const base::BuiltinFunctionEntry &entry: Symbol::GetSymbolFunctions()) {
780         SetFunction(env, symbolFunction, entry.GetName(), entry.GetEntrypoint(),
781                     entry.GetLength(), entry.GetBuiltinStubId());
782     }
783 
784     // Symbol attributes
785 #define REGISTER_SYMBOL(name, Name) \
786     SetNoneAttributeProperty(symbolFunction, #name, env->Get##Name##Symbol());
787 
788 BUILTIN_ALL_SYMBOLS(REGISTER_SYMBOL)
789     env->SetSymbolFunction(thread_, symbolFunction);
790 
791     // symbol.prototype.description
792     PropertyDescriptor descriptionDesc(thread_);
793     JSHandle<JSTaggedValue> getterKey(factory_->NewFromASCIIReadOnly("description"));
794     JSHandle<JSTaggedValue> getter(
795         factory_->NewJSBuiltinFunction(env, reinterpret_cast<void *>(Symbol::DescriptionGetter)));
796     SetGetter(symbolFuncPrototype, getterKey, getter);
797 
798     // Setup symbol.prototype[@@toPrimitive]
799     SetFunctionAtSymbol<JSSymbol::SYMBOL_TO_PRIMITIVE_TYPE>(
800         env, symbolFuncPrototype, env->GetToPrimitiveSymbol(), "[Symbol.toPrimitive]",
801         Symbol::ToPrimitive, FunctionLength::ONE);
802     // install the Symbol.prototype methods
803     SetFunction(env, symbolFuncPrototype, thread_->GlobalConstants()->GetHandledToStringString(), Symbol::ToString,
804                 FunctionLength::ZERO);
805     SetFunction(env, symbolFuncPrototype, thread_->GlobalConstants()->GetHandledValueOfString(), Symbol::ValueOf,
806                 FunctionLength::ZERO);
807 
808     // Setup %SymbolPrototype%
809     SetStringTagSymbol(env, symbolFuncPrototype, "Symbol");
810 
811     JSHandle<JSTaggedValue> holeySymbol(factory_->NewPrivateNameSymbolWithChar("holey"));
812     env->SetHoleySymbol(thread_, holeySymbol.GetTaggedValue());
813     JSHandle<JSTaggedValue> elementIcSymbol(factory_->NewPrivateNameSymbolWithChar("element-ic"));
814     env->SetElementICSymbol(thread_, elementIcSymbol.GetTaggedValue());
815     if (Runtime::GetInstance()->IsHybridVm() && env->GetInterfaceTypeSymbol().GetTaggedValue().IsUndefined()) {
816         JSHandle<JSTaggedValue> interfaceTypeSymbol(factory_->NewPrivateNameSymbolWithChar("interfaceType"));
817         env->SetInterfaceTypeSymbol(thread_, interfaceTypeSymbol.GetTaggedValue());
818     } else {
819         env->SetInterfaceTypeSymbol(thread_, JSTaggedValue::Undefined());
820     }
821 }
822 
InitializeSymbolWithRealm(const JSHandle<GlobalEnv> & realm,const JSHandle<JSHClass> & objFuncInstanceHClass)823 void Builtins::InitializeSymbolWithRealm(const JSHandle<GlobalEnv> &realm,
824                                          const JSHandle<JSHClass> &objFuncInstanceHClass)
825 {
826     [[maybe_unused]] EcmaHandleScope scope(thread_);
827     JSHandle<GlobalEnv> env = vm_->GetGlobalEnv();
828     // Symbol.prototype
829     JSHandle<JSObject> symbolFuncPrototype = factory_->NewJSObjectWithInit(objFuncInstanceHClass);
830     JSHandle<JSTaggedValue> symbolFuncPrototypeValue(symbolFuncPrototype);
831 
832     // Symbol.prototype_or_hclass
833     JSHandle<JSHClass> symbolFuncInstanceHClass =
834         factory_->NewEcmaHClass(JSPrimitiveRef::SIZE, JSType::JS_PRIMITIVE_REF, symbolFuncPrototypeValue);
835 
836     // Symbol = new Function()
837     JSHandle<JSObject> symbolFunction(
838         NewBuiltinConstructor(realm, symbolFuncPrototype, Symbol::SymbolConstructor, "Symbol", FunctionLength::ZERO));
839     JSFunction::SetFunctionPrototypeOrInstanceHClass(thread_,
840                                                      JSHandle<JSFunction>(symbolFunction),
841                                                      symbolFuncInstanceHClass.GetTaggedValue());
842 
843     // "constructor" property on the prototype
844     JSHandle<JSTaggedValue> constructorKey = thread_->GlobalConstants()->GetHandledConstructorString();
845     PropertyDescriptor descriptor(thread_, JSHandle<JSTaggedValue>::Cast(symbolFunction), true, false, true);
846     JSObject::DefineOwnProperty(thread_, symbolFuncPrototype, constructorKey, descriptor);
847 
848     for (const base::BuiltinFunctionEntry &entry: Symbol::GetSymbolFunctions()) {
849         SetFunction(realm, symbolFunction, entry.GetName(), entry.GetEntrypoint(),
850                     entry.GetLength(), entry.GetBuiltinStubId());
851     }
852 
853 #define BUILTIN_SYMBOL_CREATE_WITH_REALM(name, Name)                            \
854     SetNoneAttributeProperty(symbolFunction, #name, env->Get##Name##Symbol());  \
855     realm->Set##Name##Symbol(thread_, env->Get##Name##Symbol());
856 
857     realm->SetSymbolFunction(thread_, symbolFunction);
858     // Symbol attribute
859     BUILTIN_ALL_SYMBOLS(BUILTIN_SYMBOL_CREATE_WITH_REALM)
860 
861     // symbol.prototype.description
862     PropertyDescriptor descriptionDesc(thread_);
863     JSHandle<JSTaggedValue> getterKey(factory_->NewFromASCIIReadOnly("description"));
864     JSHandle<JSTaggedValue> getter(
865         factory_->NewJSBuiltinFunction(realm, reinterpret_cast<void *>(Symbol::DescriptionGetter)));
866     SetGetter(symbolFuncPrototype, getterKey, getter);
867 
868     // Setup symbol.prototype[@@toPrimitive]
869     SetFunctionAtSymbol<JSSymbol::SYMBOL_TO_PRIMITIVE_TYPE>(realm, symbolFuncPrototype, env->GetToPrimitiveSymbol(),
870                                                             "[Symbol.toPrimitive]", Symbol::ToPrimitive,
871                                                             FunctionLength::ONE);
872     // install the Symbol.prototype methods
873     for (const base::BuiltinFunctionEntry &entry: Symbol::GetSymbolPrototypeFunctions()) {
874         SetFunction(realm, symbolFuncPrototype, entry.GetName(), entry.GetEntrypoint(),
875                     entry.GetLength(), entry.GetBuiltinStubId());
876     }
877     // Setup %SymbolPrototype%
878     SetStringTagSymbol(realm, symbolFuncPrototype, "Symbol");
879 
880     JSHandle<JSTaggedValue> holeySymbol(factory_->NewPrivateNameSymbolWithChar("holey"));
881     realm->SetHoleySymbol(thread_, holeySymbol.GetTaggedValue());
882     JSHandle<JSTaggedValue> elementIcSymbol(factory_->NewPrivateNameSymbolWithChar("element-ic"));
883     realm->SetElementICSymbol(thread_, elementIcSymbol.GetTaggedValue());
884     if (Runtime::GetInstance()->IsHybridVm() && env->GetInterfaceTypeSymbol().GetTaggedValue().IsUndefined()) {
885         JSHandle<JSTaggedValue> interfaceTypeSymbol(factory_->NewPrivateNameSymbolWithChar("interfaceType"));
886         realm->SetInterfaceTypeSymbol(thread_, interfaceTypeSymbol.GetTaggedValue());
887     } else {
888         realm->SetInterfaceTypeSymbol(thread_, JSTaggedValue::Undefined());
889     }
890 }
891 #undef BUILTIN_SYMBOL_CREATE_WITH_REALM
892 
InitializeNumber(const JSHandle<GlobalEnv> & env,const JSHandle<JSObject> & globalObject,const JSHandle<JSHClass> & primRefObjHClass)893 void Builtins::InitializeNumber(const JSHandle<GlobalEnv> &env, const JSHandle<JSObject> &globalObject,
894                                 const JSHandle<JSHClass> &primRefObjHClass)
895 {
896     [[maybe_unused]] EcmaHandleScope scope(thread_);
897     // Number.prototype
898     JSHandle<JSTaggedValue> toObject(thread_, JSTaggedValue(FunctionLength::ZERO));
899     JSHandle<JSObject> numFuncPrototype =
900         JSHandle<JSObject>::Cast(factory_->NewJSPrimitiveRef(primRefObjHClass, toObject));
901     JSHandle<JSTaggedValue> numFuncPrototypeValue(numFuncPrototype);
902 
903     // Number.prototype_or_hclass
904     JSHandle<JSHClass> numFuncInstanceHClass =
905         factory_->NewEcmaHClass(JSPrimitiveRef::SIZE, JSType::JS_PRIMITIVE_REF, numFuncPrototypeValue);
906 
907     // Number = new Function()
908     JSHandle<JSObject> numFunction(
909         NewBuiltinConstructor(env, numFuncPrototype, Number::NumberConstructor, "Number", FunctionLength::ONE,
910             BUILTINS_STUB_ID(NumberConstructor)));
911     JSFunction::SetFunctionPrototypeOrInstanceHClass(thread_,
912                                                      JSHandle<JSFunction>(numFunction),
913                                                      numFuncInstanceHClass.GetTaggedValue());
914 
915     // Number.prototype method
916     for (const base::BuiltinFunctionEntry &entry: Number::GetNumberPrototypeFunctions()) {
917         SetFunction(env, numFuncPrototype, entry.GetName(), entry.GetEntrypoint(),
918                     entry.GetLength(), entry.GetBuiltinStubId());
919     }
920     // Number method
921     for (const base::BuiltinFunctionEntry &entry: Number::GetNumberNonGlobalFunctions()) {
922         SetFunction(env, numFunction, entry.GetName(), entry.GetEntrypoint(),
923                     entry.GetLength(), entry.GetBuiltinStubId());
924     }
925     for (const base::BuiltinFunctionEntry &entry: Number::GetNumberGlobalFunctions()) {
926         SetFuncToObjAndGlobal(env, globalObject, numFunction,
927                               entry.GetName(), entry.GetEntrypoint(), entry.GetLength(), entry.GetBuiltinStubId());
928     }
929     // Number constant
930     for (const base::BuiltinConstantEntry &entry: Number::GetNumberConstants()) {
931         SetConstant(numFunction, entry.GetName(), entry.GetTaggedValue());
932     }
933 
934     env->SetNumberFunction(thread_, numFunction);
935     env->SetNumberPrototype(thread_, numFuncPrototype);
936 }
InitializeBigIntWithRealm(const JSHandle<GlobalEnv> & realm) const937 void Builtins::InitializeBigIntWithRealm(const JSHandle<GlobalEnv> &realm) const
938 {
939     [[maybe_unused]] EcmaHandleScope scope(thread_);
940     JSHandle<GlobalEnv> env = vm_->GetGlobalEnv();
941     realm->SetBigIntFunction(thread_, env->GetBigIntFunction());
942 
943     JSHandle<JSTaggedValue> nameString(factory_->NewFromASCIIReadOnly("BigInt"));
944     JSHandle<JSObject> globalObject(thread_, realm->GetGlobalObject());
945     PropertyDescriptor descriptor(thread_, env->GetBigIntFunction(), true, false, true);
946     JSObject::DefineOwnProperty(thread_, globalObject, nameString, descriptor);
947 }
948 
InitializeBigInt(const JSHandle<GlobalEnv> & env,const JSHandle<JSHClass> & primRefObjHClass) const949 void Builtins::InitializeBigInt(const JSHandle<GlobalEnv> &env, const JSHandle<JSHClass> &primRefObjHClass) const
950 {
951     [[maybe_unused]] EcmaHandleScope scope(thread_);
952     // BigInt.prototype
953     JSHandle<JSObject> bigIntFuncPrototype = factory_->NewJSObjectWithInit(primRefObjHClass);
954     JSHandle<JSTaggedValue> bigIntFuncPrototypeValue(bigIntFuncPrototype);
955 
956     // BigInt.prototype_or_hclass
957     JSHandle<JSHClass> bigIntFuncInstanceHClass =
958         factory_->NewEcmaHClass(JSPrimitiveRef::SIZE, JSType::JS_PRIMITIVE_REF, bigIntFuncPrototypeValue);
959     // BigInt = new Function()
960     JSHandle<JSObject> bigIntFunction(
961         NewBuiltinConstructor(env, bigIntFuncPrototype, BuiltinsBigInt::BigIntConstructor, "BigInt",
962                               FunctionLength::ONE, BUILTINS_STUB_ID(BigIntConstructor)));
963     JSFunction::SetFunctionPrototypeOrInstanceHClass(thread_,
964                                                      JSHandle<JSFunction>(bigIntFunction),
965                                                      bigIntFuncInstanceHClass.GetTaggedValue());
966 
967     // BigInt.prototype method
968     for (const auto &entry : BuiltinsBigInt::GetBigIntPrototypeFunctions()) {
969         SetFunction(env, bigIntFuncPrototype, entry.GetName(), entry.GetEntrypoint(),
970                     entry.GetLength(), entry.GetBuiltinStubId());
971     }
972 
973     // BigInt method
974     for (const auto &entry : BuiltinsBigInt::GetBigIntFunctions()) {
975         SetFunction(env, bigIntFunction, entry.GetName(), entry.GetEntrypoint(),
976                     entry.GetLength(), entry.GetBuiltinStubId());
977     }
978 
979     // @@ToStringTag
980     SetStringTagSymbol(env, bigIntFuncPrototype, "BigInt");
981     env->SetBigIntFunction(thread_, bigIntFunction);
982 }
983 
InitializeDate(const JSHandle<GlobalEnv> & env,JSHandle<JSTaggedValue> objFuncPrototypeVal) const984 void Builtins::InitializeDate(const JSHandle<GlobalEnv> &env, JSHandle<JSTaggedValue> objFuncPrototypeVal) const
985 {
986     [[maybe_unused]] EcmaHandleScope scope(thread_);
987     // Date.prototype
988     JSHandle<JSHClass> dateFuncPrototypeHClass = factory_->NewEcmaHClass(
989         JSObject::SIZE, Date::GetNumPrototypeInlinedProperties(), JSType::JS_OBJECT, objFuncPrototypeVal);
990     JSHandle<JSObject> dateFuncPrototype = factory_->NewJSObjectWithInit(dateFuncPrototypeHClass);
991     JSHandle<JSTaggedValue> dateFuncPrototypeValue(dateFuncPrototype);
992 
993     // Date.prototype_or_hclass
994     JSHandle<JSHClass> dateFuncInstanceHClass =
995         factory_->NewEcmaHClass(JSDate::SIZE, JSType::JS_DATE, dateFuncPrototypeValue);
996 
997     // Date = new Function()
998     JSHandle<JSObject> dateFunction(
999         NewBuiltinConstructor(env, dateFuncPrototype, Date::DateConstructor, "Date", FunctionLength::ONE,
1000                               BUILTINS_STUB_ID(DateConstructor)));
1001     JSFunction::SetFunctionPrototypeOrInstanceHClass(thread_,
1002                                                      JSHandle<JSFunction>(dateFunction),
1003                                                      dateFuncInstanceHClass.GetTaggedValue());
1004 
1005     // Date.prototype method
1006     for (const base::BuiltinFunctionEntry &entry: Date::GetDatePrototypeFunctions()) {
1007         SetFunction(env, dateFuncPrototype, entry.GetName(), entry.GetEntrypoint(),
1008                     entry.GetLength(), entry.GetBuiltinStubId());
1009     }
1010     SetFunctionAtSymbol(env, dateFuncPrototype, env->GetToPrimitiveSymbol(), "[Symbol.toPrimitive]", Date::ToPrimitive,
1011                         FunctionLength::ONE);
1012 
1013     // Date method
1014     for (const base::BuiltinFunctionEntry &entry: Date::GetDateFunctions()) {
1015         SetFunction(env, dateFunction, entry.GetName(), entry.GetEntrypoint(),
1016                     entry.GetLength(), entry.GetBuiltinStubId());
1017     }
1018     // Date.length
1019     SetConstant(dateFunction, "length", JSTaggedValue(Date::UTC_LENGTH));
1020 
1021     env->SetDateFunction(thread_, dateFunction);
1022     env->SetDatePrototype(thread_, dateFuncPrototype);
1023     thread_->SetInitialBuiltinHClass(BuiltinTypeId::DATE,
1024         dateFunction->GetJSHClass(),
1025         *dateFuncInstanceHClass,
1026         dateFuncPrototype->GetJSHClass());
1027 }
1028 
LazyInitializeDate(const JSHandle<GlobalEnv> & env) const1029 void Builtins::LazyInitializeDate(const JSHandle<GlobalEnv> &env) const
1030 {
1031     [[maybe_unused]] EcmaHandleScope scope(thread_);
1032     JSHandle<JSObject> globalObject(thread_, env->GetGlobalObject());
1033     JSHandle<JSTaggedValue> key(factory_->NewFromUtf8ReadOnly("Date"));
1034     auto accessor = factory_->NewInternalAccessor(nullptr, reinterpret_cast<void *>(BuiltinsLazyCallback::Date));
1035     SetLazyAccessor(globalObject, key, accessor);
1036     env->SetDateFunction(thread_, accessor);
1037     env->SetDatePrototype(thread_, accessor);
1038 }
1039 
InitializeBoolean(const JSHandle<GlobalEnv> & env,const JSHandle<JSHClass> & primRefObjHClass) const1040 void Builtins::InitializeBoolean(const JSHandle<GlobalEnv> &env, const JSHandle<JSHClass> &primRefObjHClass) const
1041 {
1042     [[maybe_unused]] EcmaHandleScope scope(thread_);
1043     // Boolean.prototype
1044     JSHandle<JSTaggedValue> toObject(thread_, JSTaggedValue::False());
1045     JSHandle<JSObject> booleanFuncPrototype =
1046         JSHandle<JSObject>::Cast(factory_->NewJSPrimitiveRef(primRefObjHClass, toObject));
1047     JSHandle<JSTaggedValue> booleanFuncPrototypeValue(booleanFuncPrototype);
1048 
1049     // Boolean.prototype_or_hclass
1050     JSHandle<JSHClass> booleanFuncInstanceHClass =
1051         factory_->NewEcmaHClass(JSPrimitiveRef::SIZE, JSType::JS_PRIMITIVE_REF, booleanFuncPrototypeValue);
1052 
1053     // new Boolean Function()
1054     JSHandle<JSFunction> booleanFunction = NewBuiltinConstructor(env, booleanFuncPrototype, Boolean::BooleanConstructor,
1055         "Boolean", FunctionLength::ONE, BUILTINS_STUB_ID(BooleanConstructor));
1056     JSFunction::SetFunctionPrototypeOrInstanceHClass(thread_, booleanFunction,
1057                                                      booleanFuncInstanceHClass.GetTaggedValue());
1058 
1059     // Boolean.prototype method
1060     SetFunction(env, booleanFuncPrototype, thread_->GlobalConstants()->GetHandledToStringString(),
1061                 Boolean::BooleanPrototypeToString, FunctionLength::ZERO);
1062     SetFunction(env, booleanFuncPrototype, thread_->GlobalConstants()->GetHandledValueOfString(),
1063                 Boolean::BooleanPrototypeValueOf, FunctionLength::ZERO);
1064 
1065     env->SetBooleanFunction(thread_, booleanFunction);
1066     env->SetBooleanPrototype(thread_, booleanFuncPrototype);
1067 }
1068 
InitializeProxy(const JSHandle<GlobalEnv> & env)1069 void Builtins::InitializeProxy(const JSHandle<GlobalEnv> &env)
1070 {
1071     // 2: The number of parameters is 2
1072     JSHandle<JSObject> proxyFunction(InitializeExoticConstructor(env, Proxy::ProxyConstructor, "Proxy", 2));
1073 
1074     // Proxy method
1075     SetFunction(env, proxyFunction, "revocable", Proxy::Revocable, FunctionLength::TWO);
1076     env->SetProxyFunction(thread_, proxyFunction);
1077 }
1078 
InitializeExoticConstructor(const JSHandle<GlobalEnv> & env,EcmaEntrypoint ctorFunc,std::string_view name,int length)1079 JSHandle<JSFunction> Builtins::InitializeExoticConstructor(const JSHandle<GlobalEnv> &env, EcmaEntrypoint ctorFunc,
1080                                                            std::string_view name, int length)
1081 {
1082     JSHandle<JSFunction> ctor = factory_->NewJSBuiltinFunction(env, reinterpret_cast<void *>(ctorFunc),
1083                                                                FunctionKind::BUILTIN_PROXY_CONSTRUCTOR,
1084                                                                BUILTINS_STUB_ID(ProxyConstructor));
1085 
1086     JSFunction::SetFunctionLength(thread_, ctor, JSTaggedValue(length));
1087     JSHandle<JSTaggedValue> nameString(factory_->NewFromUtf8ReadOnly(name));
1088     JSFunction::SetFunctionName(thread_, JSHandle<JSFunctionBase>(ctor), nameString,
1089                                 JSHandle<JSTaggedValue>(thread_, JSTaggedValue::Undefined()));
1090 
1091     JSHandle<JSObject> globalObject(thread_, env->GetGlobalObject());
1092     PropertyDescriptor descriptor(thread_, JSHandle<JSTaggedValue>(ctor), true, false, true);
1093     JSObject::DefineOwnProperty(thread_, globalObject, nameString, descriptor);
1094     return ctor;
1095 }
1096 
InitializeAsyncFunction(const JSHandle<GlobalEnv> & env,const JSHandle<JSHClass> & objFuncClass) const1097 void Builtins::InitializeAsyncFunction(const JSHandle<GlobalEnv> &env, const JSHandle<JSHClass> &objFuncClass) const
1098 {
1099     [[maybe_unused]] EcmaHandleScope scope(thread_);
1100     const GlobalEnvConstants *globalConst = thread_->GlobalConstants();
1101     // AsyncFunction.prototype
1102     JSHandle<JSObject> asyncFuncPrototype = factory_->NewJSObjectWithInit(objFuncClass);
1103     JSObject::SetPrototype(thread_, asyncFuncPrototype, env->GetFunctionPrototype());
1104     JSHandle<JSTaggedValue> asyncFuncPrototypeValue(asyncFuncPrototype);
1105 
1106     // AsyncFunction.prototype_or_hclass
1107     JSHandle<JSHClass> asyncFuncInstanceHClass =
1108         factory_->NewEcmaHClass(JSAsyncFunction::SIZE, JSType::JS_ASYNC_FUNCTION, asyncFuncPrototypeValue);
1109 
1110     // AsyncFunction = new Function()
1111     JSHandle<JSFunction> asyncFunction = NewBuiltinConstructor(
1112         env, asyncFuncPrototype, AsyncFunction::AsyncFunctionConstructor, "AsyncFunction", FunctionLength::ONE);
1113     JSObject::SetPrototype(thread_, JSHandle<JSObject>::Cast(asyncFunction), env->GetFunctionFunction());
1114     JSHandle<JSTaggedValue> constructorKey = globalConst->GetHandledConstructorString();
1115     PropertyDescriptor asyncDesc(thread_, JSHandle<JSTaggedValue>::Cast(asyncFunction), false, false, true);
1116     JSObject::DefineOwnProperty(thread_, asyncFuncPrototype, constructorKey, asyncDesc);
1117     asyncFunction->SetProtoOrHClass(thread_, asyncFuncInstanceHClass.GetTaggedValue());
1118 
1119     // AsyncFunction.prototype property
1120     SetStringTagSymbol(env, asyncFuncPrototype, "AsyncFunction");
1121     env->SetAsyncFunction(thread_, asyncFunction);
1122     env->SetAsyncFunctionPrototype(thread_, asyncFuncPrototype);
1123 }
1124 
InitializeAllTypeError(const JSHandle<GlobalEnv> & env,const JSHandle<JSHClass> & objFuncClass) const1125 void Builtins::InitializeAllTypeError(const JSHandle<GlobalEnv> &env, const JSHandle<JSHClass> &objFuncClass) const
1126 {
1127     // Error.prototype
1128     JSHandle<JSObject> errorFuncPrototype = factory_->NewJSObjectWithInit(objFuncClass);
1129     JSHandle<JSTaggedValue> errorFuncPrototypeValue(errorFuncPrototype);
1130     // Error.prototype_or_hclass
1131     JSHandle<JSHClass> errorFuncInstanceHClass =
1132         factory_->NewEcmaHClass(JSObject::SIZE, JSType::JS_ERROR, errorFuncPrototypeValue);
1133     // Error() = new Function()
1134     JSHandle<JSFunction> errorFunction(NewBuiltinConstructor(env, errorFuncPrototype, Error::ErrorConstructor, "Error",
1135                                                              FunctionLength::ONE, BUILTINS_STUB_ID(ErrorConstructor)));
1136     JSFunction::SetFunctionPrototypeOrInstanceHClass(thread_, errorFunction, errorFuncInstanceHClass.GetTaggedValue());
1137 
1138     // Error.prototype method
1139     SetFunction(env, errorFuncPrototype, thread_->GlobalConstants()->GetHandledToStringString(), Error::ToString,
1140                 FunctionLength::ZERO);
1141 
1142     // Error.prototype Attribute
1143     SetAttribute(errorFuncPrototype, "name", "Error");
1144     SetAttribute(errorFuncPrototype, "message", "");
1145     env->SetErrorFunction(thread_, errorFunction);
1146 
1147     JSHandle<JSHClass> nativeErrorFuncClass =
1148         factory_->NewEcmaHClass(JSFunction::SIZE, JSType::JS_FUNCTION, env->GetErrorFunction());
1149     nativeErrorFuncClass->SetConstructor(true);
1150     env->SetNativeErrorFunctionClass(thread_, nativeErrorFuncClass);
1151 
1152     JSHandle<JSHClass> errorNativeFuncInstanceHClass =
1153         factory_->NewEcmaHClass(JSObject::SIZE, JSType::JS_OBJECT, errorFuncPrototypeValue);
1154     InitializeError(env, errorNativeFuncInstanceHClass, JSType::JS_RANGE_ERROR);
1155     InitializeError(env, errorNativeFuncInstanceHClass, JSType::JS_REFERENCE_ERROR);
1156     InitializeError(env, errorNativeFuncInstanceHClass, JSType::JS_TYPE_ERROR);
1157     InitializeError(env, errorNativeFuncInstanceHClass, JSType::JS_AGGREGATE_ERROR);
1158     InitializeError(env, errorNativeFuncInstanceHClass, JSType::JS_URI_ERROR);
1159     InitializeError(env, errorNativeFuncInstanceHClass, JSType::JS_SYNTAX_ERROR);
1160     InitializeError(env, errorNativeFuncInstanceHClass, JSType::JS_EVAL_ERROR);
1161     InitializeError(env, errorNativeFuncInstanceHClass, JSType::JS_OOM_ERROR);
1162     InitializeError(env, errorNativeFuncInstanceHClass, JSType::JS_TERMINATION_ERROR);
1163 
1164     JSHandle<EcmaString> handleMsg = factory_->NewFromUtf8ReadOnly("Default oom error");
1165     JSHandle<JSObject> oomError = factory_->NewJSError(env, ErrorType::OOM_ERROR, handleMsg, StackCheck::YES);
1166     env->SetOOMErrorObject(thread_, oomError);
1167 }
1168 
InitializeAllTypeErrorWithRealm(const JSHandle<GlobalEnv> & realm) const1169 void Builtins::InitializeAllTypeErrorWithRealm(const JSHandle<GlobalEnv> &realm) const
1170 {
1171     JSHandle<GlobalEnv> env = vm_->GetGlobalEnv();
1172 
1173     realm->SetErrorFunction(thread_, env->GetErrorFunction());
1174     realm->SetNativeErrorFunctionClass(thread_, env->GetNativeErrorFunctionClass());
1175 
1176     SetErrorWithRealm(realm, JSType::JS_RANGE_ERROR);
1177     SetErrorWithRealm(realm, JSType::JS_REFERENCE_ERROR);
1178     SetErrorWithRealm(realm, JSType::JS_TYPE_ERROR);
1179     SetErrorWithRealm(realm, JSType::JS_AGGREGATE_ERROR);
1180     SetErrorWithRealm(realm, JSType::JS_URI_ERROR);
1181     SetErrorWithRealm(realm, JSType::JS_SYNTAX_ERROR);
1182     SetErrorWithRealm(realm, JSType::JS_EVAL_ERROR);
1183     SetErrorWithRealm(realm, JSType::JS_OOM_ERROR);
1184     SetErrorWithRealm(realm, JSType::JS_TERMINATION_ERROR);
1185 }
1186 
SetErrorWithRealm(const JSHandle<GlobalEnv> & realm,const JSType & errorTag) const1187 void Builtins::SetErrorWithRealm(const JSHandle<GlobalEnv> &realm, const JSType &errorTag) const
1188 {
1189     JSHandle<GlobalEnv> env = vm_->GetGlobalEnv();
1190     JSHandle<JSObject> globalObject(thread_, realm->GetGlobalObject());
1191     JSHandle<JSTaggedValue> nameString;
1192     JSHandle<JSTaggedValue> nativeErrorFunction;
1193     switch (errorTag) {
1194         case JSType::JS_RANGE_ERROR:
1195             nativeErrorFunction = env->GetRangeErrorFunction();
1196             nameString = JSHandle<JSTaggedValue>(thread_->GlobalConstants()->GetHandledRangeErrorString());
1197             realm->SetRangeErrorFunction(thread_, nativeErrorFunction);
1198             break;
1199         case JSType::JS_EVAL_ERROR:
1200             nativeErrorFunction = env->GetEvalErrorFunction();
1201             nameString = JSHandle<JSTaggedValue>(thread_->GlobalConstants()->GetHandledEvalErrorString());
1202             realm->SetEvalErrorFunction(thread_, nativeErrorFunction);
1203             break;
1204         case JSType::JS_REFERENCE_ERROR:
1205             nativeErrorFunction = env->GetReferenceErrorFunction();
1206             nameString = JSHandle<JSTaggedValue>(thread_->GlobalConstants()->GetHandledReferenceErrorString());
1207             realm->SetReferenceErrorFunction(thread_, nativeErrorFunction);
1208             break;
1209         case JSType::JS_TYPE_ERROR:
1210             nativeErrorFunction = env->GetTypeErrorFunction();
1211             nameString = JSHandle<JSTaggedValue>(thread_->GlobalConstants()->GetHandledTypeErrorString());
1212             realm->SetTypeErrorFunction(thread_, nativeErrorFunction);
1213             realm->SetThrowTypeError(thread_, env->GetThrowTypeError());
1214             break;
1215         case JSType::JS_AGGREGATE_ERROR:
1216             nativeErrorFunction = env->GetAggregateErrorFunction();
1217             nameString = JSHandle<JSTaggedValue>(thread_->GlobalConstants()->GetHandledAggregateErrorString());
1218             realm->SetAggregateErrorFunction(thread_, nativeErrorFunction);
1219             break;
1220         case JSType::JS_URI_ERROR:
1221             nativeErrorFunction = env->GetURIErrorFunction();
1222             nameString = JSHandle<JSTaggedValue>(thread_->GlobalConstants()->GetHandledURIErrorString());
1223             realm->SetURIErrorFunction(thread_, nativeErrorFunction);
1224             break;
1225         case JSType::JS_SYNTAX_ERROR:
1226             nativeErrorFunction = env->GetSyntaxErrorFunction();
1227             nameString = JSHandle<JSTaggedValue>(thread_->GlobalConstants()->GetHandledSyntaxErrorString());
1228             realm->SetSyntaxErrorFunction(thread_, nativeErrorFunction);
1229             break;
1230         case JSType::JS_OOM_ERROR:
1231             nativeErrorFunction = env->GetOOMErrorFunction();
1232             nameString = JSHandle<JSTaggedValue>(thread_->GlobalConstants()->GetHandledOOMErrorString());
1233             realm->SetOOMErrorFunction(thread_, nativeErrorFunction);
1234             break;
1235         case JSType::JS_TERMINATION_ERROR:
1236             nativeErrorFunction = env->GetTerminationErrorFunction();
1237             nameString = JSHandle<JSTaggedValue>(thread_->GlobalConstants()->GetHandledTerminationErrorString());
1238             realm->SetTerminationErrorFunction(thread_, nativeErrorFunction);
1239             break;
1240         default:
1241             LOG_ECMA(FATAL) << "this branch is unreachable, errorTag: " << static_cast<size_t>(errorTag);
1242             UNREACHABLE();
1243     }
1244     PropertyDescriptor descriptor(thread_, nativeErrorFunction, true, false, true);
1245     JSObject::DefineOwnProperty(thread_, globalObject, nameString, descriptor);
1246 }
1247 
GeneralUpdateError(ErrorParameter * error,EcmaEntrypoint constructor,EcmaEntrypoint method,std::string_view name,JSType type) const1248 void Builtins::GeneralUpdateError(ErrorParameter *error, EcmaEntrypoint constructor, EcmaEntrypoint method,
1249                                   std::string_view name, JSType type) const
1250 {
1251     error->nativeConstructor = constructor;
1252     error->nativeMethod = method;
1253     error->nativePropertyName = name;
1254     error->nativeJstype = type;
1255 }
1256 
InitializeError(const JSHandle<GlobalEnv> & env,const JSHandle<JSHClass> & objFuncClass,const JSType & errorTag) const1257 void Builtins::InitializeError(const JSHandle<GlobalEnv> &env, const JSHandle<JSHClass> &objFuncClass,
1258                                const JSType &errorTag) const
1259 {
1260     // NativeError.prototype
1261     JSHandle<JSObject> nativeErrorFuncPrototype = factory_->NewJSObjectWithInit(objFuncClass);
1262     JSHandle<JSTaggedValue> nativeErrorFuncPrototypeValue(nativeErrorFuncPrototype);
1263 
1264     ErrorParameter errorParameter{RangeError::RangeErrorConstructor, RangeError::ToString, "RangeError",
1265                                   JSType::JS_RANGE_ERROR};
1266     switch (errorTag) {
1267         case JSType::JS_RANGE_ERROR:
1268             GeneralUpdateError(&errorParameter, RangeError::RangeErrorConstructor, RangeError::ToString, "RangeError",
1269                                JSType::JS_RANGE_ERROR);
1270             break;
1271         case JSType::JS_EVAL_ERROR:
1272             GeneralUpdateError(&errorParameter, EvalError::EvalErrorConstructor, EvalError::ToString, "EvalError",
1273                                JSType::JS_EVAL_ERROR);
1274             break;
1275         case JSType::JS_REFERENCE_ERROR:
1276             GeneralUpdateError(&errorParameter, ReferenceError::ReferenceErrorConstructor, ReferenceError::ToString,
1277                                "ReferenceError", JSType::JS_REFERENCE_ERROR);
1278             break;
1279         case JSType::JS_TYPE_ERROR:
1280             GeneralUpdateError(&errorParameter, TypeError::TypeErrorConstructor, TypeError::ToString, "TypeError",
1281                                JSType::JS_TYPE_ERROR);
1282             break;
1283         case JSType::JS_AGGREGATE_ERROR:
1284             GeneralUpdateError(&errorParameter, AggregateError::AggregateErrorConstructor, AggregateError::ToString,
1285                                "AggregateError", JSType::JS_AGGREGATE_ERROR);
1286             break;
1287         case JSType::JS_URI_ERROR:
1288             GeneralUpdateError(&errorParameter, URIError::URIErrorConstructor, URIError::ToString, "URIError",
1289                                JSType::JS_URI_ERROR);
1290             break;
1291         case JSType::JS_SYNTAX_ERROR:
1292             GeneralUpdateError(&errorParameter, SyntaxError::SyntaxErrorConstructor, SyntaxError::ToString,
1293                                "SyntaxError", JSType::JS_SYNTAX_ERROR);
1294             break;
1295         case JSType::JS_OOM_ERROR:
1296             GeneralUpdateError(&errorParameter, OOMError::OOMErrorConstructor, OOMError::ToString,
1297                                "OutOfMemoryError", JSType::JS_OOM_ERROR);
1298             break;
1299         case JSType::JS_TERMINATION_ERROR:
1300             GeneralUpdateError(&errorParameter, TerminationError::TerminationErrorConstructor,
1301                                TerminationError::ToString, "TerminationError", JSType::JS_TERMINATION_ERROR);
1302             break;
1303         default:
1304             break;
1305     }
1306 
1307     // NativeError.prototype_or_hclass
1308     JSHandle<JSHClass> nativeErrorFuncInstanceHClass =
1309         factory_->NewEcmaHClass(JSObject::SIZE, errorParameter.nativeJstype, nativeErrorFuncPrototypeValue);
1310 
1311     // NativeError() = new Error()
1312     FunctionLength functionLength = FunctionLength::ONE;
1313     if (errorTag == JSType::JS_AGGREGATE_ERROR) {
1314         functionLength = FunctionLength::TWO;
1315     }
1316     JSHandle<JSFunction> nativeErrorFunction =
1317         factory_->NewJSNativeErrorFunction(env, reinterpret_cast<void *>(errorParameter.nativeConstructor));
1318     InitializeCtor(env, nativeErrorFuncPrototype, nativeErrorFunction, errorParameter.nativePropertyName,
1319                    functionLength);
1320 
1321     JSFunction::SetFunctionPrototypeOrInstanceHClass(thread_, nativeErrorFunction,
1322                                                      nativeErrorFuncInstanceHClass.GetTaggedValue());
1323 
1324     // NativeError.prototype method
1325     SetFunction(env, nativeErrorFuncPrototype, thread_->GlobalConstants()->GetHandledToStringString(),
1326                 errorParameter.nativeMethod, FunctionLength::ZERO);
1327 
1328     // Error.prototype Attribute
1329     SetAttribute(nativeErrorFuncPrototype, "name", errorParameter.nativePropertyName);
1330     SetAttribute(nativeErrorFuncPrototype, "message", "");
1331 
1332     if (errorTag == JSType::JS_RANGE_ERROR) {
1333         env->SetRangeErrorFunction(thread_, nativeErrorFunction);
1334     } else if (errorTag == JSType::JS_REFERENCE_ERROR) {
1335         env->SetReferenceErrorFunction(thread_, nativeErrorFunction);
1336     } else if (errorTag == JSType::JS_TYPE_ERROR) {
1337         env->SetTypeErrorFunction(thread_, nativeErrorFunction);
1338         JSHandle<JSFunction> throwTypeErrorFunction =
1339             factory_->NewJSBuiltinFunction(env, reinterpret_cast<void *>(TypeError::ThrowTypeError));
1340         JSFunction::SetFunctionLength(thread_, throwTypeErrorFunction, JSTaggedValue(1), false);
1341         JSObject::PreventExtensions(thread_, JSHandle<JSObject>::Cast(throwTypeErrorFunction));
1342         env->SetThrowTypeError(thread_, throwTypeErrorFunction);
1343     } else if (errorTag == JSType::JS_AGGREGATE_ERROR) {
1344         env->SetAggregateErrorFunction(thread_, nativeErrorFunction);
1345     } else if (errorTag == JSType::JS_URI_ERROR) {
1346         env->SetURIErrorFunction(thread_, nativeErrorFunction);
1347     } else if (errorTag == JSType::JS_SYNTAX_ERROR) {
1348         env->SetSyntaxErrorFunction(thread_, nativeErrorFunction);
1349     } else if (errorTag == JSType::JS_EVAL_ERROR) {
1350         env->SetEvalErrorFunction(thread_, nativeErrorFunction);
1351     } else if (errorTag == JSType::JS_OOM_ERROR) {
1352         env->SetOOMErrorFunction(thread_, nativeErrorFunction);
1353     } else {
1354         env->SetTerminationErrorFunction(thread_, nativeErrorFunction);
1355     }
1356 }  // namespace panda::ecmascript
1357 
InitializeCtor(const JSHandle<GlobalEnv> & env,const JSHandle<JSObject> & prototype,const JSHandle<JSFunction> & ctor,std::string_view name,int length) const1358 void Builtins::InitializeCtor(const JSHandle<GlobalEnv> &env, const JSHandle<JSObject> &prototype,
1359                               const JSHandle<JSFunction> &ctor, std::string_view name, int length) const
1360 {
1361     const GlobalEnvConstants *globalConst = thread_->GlobalConstants();
1362     JSFunction::SetFunctionLength(thread_, ctor, JSTaggedValue(length));
1363     JSHandle<JSTaggedValue> nameString(factory_->NewFromUtf8ReadOnly(name));
1364     JSFunction::SetFunctionName(thread_, JSHandle<JSFunctionBase>(ctor), nameString,
1365                                 JSHandle<JSTaggedValue>(thread_, JSTaggedValue::Undefined()));
1366     JSHandle<JSTaggedValue> constructorKey = globalConst->GetHandledConstructorString();
1367     PropertyDescriptor descriptor1(thread_, JSHandle<JSTaggedValue>::Cast(ctor), true, false, true);
1368     JSObject::DefineOwnProperty(thread_, prototype, constructorKey, descriptor1);
1369 
1370     /* set "prototype" in constructor */
1371     JSFunction::SetFunctionPrototypeOrInstanceHClass(thread_, ctor, prototype.GetTaggedValue());
1372 
1373     if (!JSTaggedValue::SameValue(thread_, nameString, thread_->GlobalConstants()->GetHandledAsyncFunctionString())) {
1374         JSHandle<JSObject> globalObject(thread_, env->GetGlobalObject());
1375         PropertyDescriptor descriptor2(thread_, JSHandle<JSTaggedValue>::Cast(ctor), true, false, true);
1376         JSObject::DefineOwnProperty(thread_, globalObject, nameString, descriptor2);
1377     }
1378 }
1379 
InitializeSet(const JSHandle<GlobalEnv> & env,JSHandle<JSTaggedValue> objFuncPrototypeVal) const1380 void Builtins::InitializeSet(const JSHandle<GlobalEnv> &env, JSHandle<JSTaggedValue> objFuncPrototypeVal) const
1381 {
1382     [[maybe_unused]] EcmaHandleScope scope(thread_);
1383     const GlobalEnvConstants *globalConst = thread_->GlobalConstants();
1384     // Set.prototype
1385     JSHandle<JSHClass> setFuncPrototypeHClass = factory_->NewEcmaHClass(
1386         JSObject::SIZE, BuiltinsSet::GetNumPrototypeInlinedProperties(), JSType::JS_OBJECT, objFuncPrototypeVal);
1387     JSHandle<JSObject> setFuncPrototype = factory_->NewJSObjectWithInit(setFuncPrototypeHClass);
1388     JSHandle<JSTaggedValue> setFuncPrototypeValue(setFuncPrototype);
1389     // Set.prototype_or_hclass
1390     JSHandle<JSHClass> setFuncInstanceHClass =
1391         factory_->NewEcmaHClass(JSSet::SIZE, JSType::JS_SET, setFuncPrototypeValue);
1392     env->SetSetClass(thread_, setFuncInstanceHClass);
1393     // Set() = new Function()
1394     JSHandle<JSTaggedValue> setFunction(
1395         NewBuiltinConstructor(env, setFuncPrototype, BuiltinsSet::SetConstructor, "Set", FunctionLength::ZERO,
1396                               BUILTINS_STUB_ID(SetConstructor)));
1397     JSFunction::SetFunctionPrototypeOrInstanceHClass(thread_,
1398                                                      JSHandle<JSFunction>(setFunction),
1399                                                      setFuncInstanceHClass.GetTaggedValue());
1400 
1401     // "constructor" property on the prototype
1402     JSHandle<JSTaggedValue> constructorKey = globalConst->GetHandledConstructorString();
1403     JSObject::SetProperty(thread_, JSHandle<JSTaggedValue>(setFuncPrototype), constructorKey, setFunction);
1404     RETURN_IF_ABRUPT_COMPLETION(thread_);
1405     // Set.prototype functions, excluding keys()
1406     for (const base::BuiltinFunctionEntry &entry: BuiltinsSet::GetSetPrototypeFunctions()) {
1407         SetFunction(env, setFuncPrototype, entry.GetName(), entry.GetEntrypoint(),
1408                     entry.GetLength(), entry.GetBuiltinStubId());
1409     }
1410     // Set.prototype.keys, which is strictly equal to Set.prototype.values
1411     JSHandle<JSTaggedValue> keys(factory_->NewFromASCIIReadOnly("keys"));
1412     JSHandle<JSTaggedValue> values(factory_->NewFromASCIIReadOnly("values"));
1413     JSHandle<JSTaggedValue> valuesFunc =
1414         JSObject::GetMethod(thread_, JSHandle<JSTaggedValue>::Cast(setFuncPrototype), values);
1415     RETURN_IF_ABRUPT_COMPLETION(thread_);
1416     PropertyDescriptor descriptor(thread_, valuesFunc, true, false, true);
1417     JSObject::DefineOwnProperty(thread_, setFuncPrototype, keys, descriptor);
1418 
1419     // @@ToStringTag
1420     SetStringTagSymbol(env, setFuncPrototype, "Set");
1421 
1422     // 23.1.3.10get Set.prototype.size
1423     JSHandle<JSTaggedValue> sizeGetter = CreateGetter(env, BuiltinsSet::GetSize, "size", FunctionLength::ZERO);
1424     JSHandle<JSTaggedValue> sizeKey(factory_->NewFromASCIIReadOnly("size"));
1425     SetGetter(setFuncPrototype, sizeKey, sizeGetter);
1426 
1427     // 23.1.2.2get Set [ @@species ]
1428     JSHandle<JSTaggedValue> speciesSymbol = env->GetSpeciesSymbol();
1429     JSHandle<JSTaggedValue> speciesGetter =
1430         CreateGetter(env, BuiltinsSet::Species, "[Symbol.species]", FunctionLength::ZERO);
1431     SetGetter(JSHandle<JSObject>(setFunction), speciesSymbol, speciesGetter);
1432 
1433     // %SetPrototype% [ @@iterator ]
1434     JSHandle<JSTaggedValue> iteratorSymbol = env->GetIteratorSymbol();
1435     JSObject::DefineOwnProperty(thread_, setFuncPrototype, iteratorSymbol, descriptor);
1436 
1437     env->SetBuiltinsSetFunction(thread_, setFunction);
1438     env->SetSetPrototype(thread_, setFuncPrototype);
1439     env->SetSetProtoValuesFunction(thread_, valuesFunc);
1440     thread_->SetInitialBuiltinHClass(BuiltinTypeId::SET,
1441         setFunction->GetTaggedObject()->GetClass(),
1442         *setFuncInstanceHClass,
1443         setFuncPrototype->GetJSHClass());
1444 }
1445 
LazyInitializeSet(const JSHandle<GlobalEnv> & env)1446 void Builtins::LazyInitializeSet(const JSHandle<GlobalEnv> &env)
1447 {
1448     [[maybe_unused]] EcmaHandleScope scope(thread_);
1449     JSHandle<JSObject> globalObject(thread_, env->GetGlobalObject());
1450     JSHandle<JSTaggedValue> key(factory_->NewFromUtf8ReadOnly("Set"));
1451     auto accessor = factory_->NewInternalAccessor(nullptr, reinterpret_cast<void *>(BuiltinsLazyCallback::Set));
1452     SetLazyAccessor(globalObject, key, accessor);
1453     env->SetBuiltinsSetFunction(thread_, accessor);
1454     env->SetSetPrototype(thread_, accessor);
1455     env->SetSetProtoValuesFunction(thread_, accessor);
1456     env->SetSetClass(thread_, accessor);
1457 }
1458 
InitializeMap(const JSHandle<GlobalEnv> & env,JSHandle<JSTaggedValue> objFuncPrototypeVal) const1459 void Builtins::InitializeMap(const JSHandle<GlobalEnv> &env, JSHandle<JSTaggedValue> objFuncPrototypeVal) const
1460 {
1461     [[maybe_unused]] EcmaHandleScope scope(thread_);
1462     const GlobalEnvConstants *globalConst = thread_->GlobalConstants();
1463     // Map.prototype
1464     JSHandle<JSHClass> mapFuncPrototypeHClass = factory_->NewEcmaHClass(
1465         JSObject::SIZE, BuiltinsMap::GetNumPrototypeInlinedProperties(), JSType::JS_OBJECT, objFuncPrototypeVal);
1466     JSHandle<JSObject> mapFuncPrototype = factory_->NewJSObjectWithInit(mapFuncPrototypeHClass);
1467     JSHandle<JSTaggedValue> mapFuncPrototypeValue(mapFuncPrototype);
1468     // Map.prototype_or_hclass
1469     JSHandle<JSHClass> mapFuncInstanceHClass =
1470         factory_->NewEcmaHClass(JSMap::SIZE, JSType::JS_MAP, mapFuncPrototypeValue);
1471     env->SetMapClass(thread_, mapFuncInstanceHClass);
1472 
1473     // Map() = new Function()
1474     JSHandle<JSTaggedValue> mapFunction(
1475         NewBuiltinConstructor(env, mapFuncPrototype, BuiltinsMap::MapConstructor, "Map", FunctionLength::ZERO,
1476                               BUILTINS_STUB_ID(MapConstructor)));
1477     // Map().prototype = Map.Prototype & Map.prototype.constructor = Map()
1478     JSFunction::SetFunctionPrototypeOrInstanceHClass(thread_,
1479                                                      JSHandle<JSFunction>(mapFunction),
1480                                                      mapFuncInstanceHClass.GetTaggedValue());
1481 
1482     // "constructor" property on the prototype
1483     JSHandle<JSTaggedValue> constructorKey = globalConst->GetHandledConstructorString();
1484     JSObject::SetProperty(thread_, JSHandle<JSTaggedValue>(mapFuncPrototype), constructorKey, mapFunction);
1485     RETURN_IF_ABRUPT_COMPLETION(thread_);
1486     // Map.prototype functions
1487     for (const base::BuiltinFunctionEntry &entry: BuiltinsMap::GetMapPrototypeFunctions()) {
1488         SetFunction(env, mapFuncPrototype, entry.GetName(), entry.GetEntrypoint(),
1489                     entry.GetLength(), entry.GetBuiltinStubId());
1490     }
1491     // @@ToStringTag
1492     SetStringTagSymbol(env, mapFuncPrototype, "Map");
1493 
1494     // 23.1.3.10get Map.prototype.size
1495     JSHandle<JSTaggedValue> sizeGetter = CreateGetter(env, BuiltinsMap::GetSize, "size", FunctionLength::ZERO);
1496     JSHandle<JSTaggedValue> sizeKey(factory_->NewFromASCIIReadOnly("size"));
1497     SetGetter(mapFuncPrototype, sizeKey, sizeGetter);
1498 
1499     // 23.1.2.2get Map [ @@species ]
1500     JSHandle<JSTaggedValue> speciesSymbol = env->GetSpeciesSymbol();
1501     JSHandle<JSTaggedValue> speciesGetter =
1502         CreateGetter(env, BuiltinsMap::Species, "[Symbol.species]", FunctionLength::ZERO);
1503     SetGetter(JSHandle<JSObject>(mapFunction), speciesSymbol, speciesGetter);
1504 
1505     // %MapPrototype% [ @@iterator ]
1506     JSHandle<JSTaggedValue> iteratorSymbol = env->GetIteratorSymbol();
1507     JSHandle<JSTaggedValue> entries(factory_->NewFromASCIIReadOnly("entries"));
1508     JSHandle<JSTaggedValue> entriesFunc =
1509         JSObject::GetMethod(thread_, JSHandle<JSTaggedValue>::Cast(mapFuncPrototype), entries);
1510     RETURN_IF_ABRUPT_COMPLETION(thread_);
1511     PropertyDescriptor descriptor(thread_, entriesFunc, true, false, true);
1512     JSObject::DefineOwnProperty(thread_, mapFuncPrototype, iteratorSymbol, descriptor);
1513 
1514     env->SetBuiltinsMapFunction(thread_, mapFunction);
1515     env->SetMapPrototype(thread_, mapFuncPrototype);
1516     env->SetMapProtoEntriesFunction(thread_, entriesFunc);
1517     thread_->SetInitialBuiltinHClass(BuiltinTypeId::MAP,
1518         mapFunction->GetTaggedObject()->GetClass(),
1519         *mapFuncInstanceHClass,
1520         mapFuncPrototype->GetJSHClass());
1521 }
1522 
LazyInitializeMap(const JSHandle<GlobalEnv> & env) const1523 void Builtins::LazyInitializeMap(const JSHandle<GlobalEnv> &env) const
1524 {
1525     [[maybe_unused]] EcmaHandleScope scope(thread_);
1526     JSHandle<JSObject> globalObject(thread_, env->GetGlobalObject());
1527     JSHandle<JSTaggedValue> key(factory_->NewFromUtf8ReadOnly("Map"));
1528     auto accessor = factory_->NewInternalAccessor(nullptr, reinterpret_cast<void *>(BuiltinsLazyCallback::Map));
1529     SetLazyAccessor(globalObject, key, accessor);
1530     env->SetBuiltinsMapFunction(thread_, accessor);
1531     env->SetMapPrototype(thread_, accessor);
1532     env->SetMapProtoEntriesFunction(thread_, accessor);
1533     env->SetMapClass(thread_, accessor);
1534 }
1535 
InitializeWeakMap(const JSHandle<GlobalEnv> & env,const JSHandle<JSHClass> & objFuncClass) const1536 void Builtins::InitializeWeakMap(const JSHandle<GlobalEnv> &env, const JSHandle<JSHClass> &objFuncClass) const
1537 {
1538     [[maybe_unused]] EcmaHandleScope scope(thread_);
1539     const GlobalEnvConstants *globalConst = thread_->GlobalConstants();
1540     // WeakMap.prototype
1541     JSHandle<JSObject> weakMapFuncPrototype = factory_->NewJSObjectWithInit(objFuncClass);
1542     JSHandle<JSTaggedValue> weakMapFuncPrototypeValue(weakMapFuncPrototype);
1543     // WeakMap.prototype_or_hclass
1544     JSHandle<JSHClass> weakMapFuncInstanceHClass =
1545         factory_->NewEcmaHClass(JSWeakMap::SIZE, JSType::JS_WEAK_MAP, weakMapFuncPrototypeValue);
1546     // WeakMap() = new Function()
1547     JSHandle<JSTaggedValue> weakMapFunction(NewBuiltinConstructor(
1548         env, weakMapFuncPrototype, BuiltinsWeakMap::WeakMapConstructor, "WeakMap", FunctionLength::ZERO));
1549     // WeakMap().prototype = WeakMap.Prototype & WeakMap.prototype.constructor = WeakMap()
1550     JSFunction::Cast(weakMapFunction->GetTaggedObject())
1551         ->SetProtoOrHClass(thread_, weakMapFuncInstanceHClass.GetTaggedValue());
1552 
1553     // "constructor" property on the prototype
1554     JSHandle<JSTaggedValue> constructorKey = globalConst->GetHandledConstructorString();
1555     JSObject::SetProperty(thread_, JSHandle<JSTaggedValue>(weakMapFuncPrototype), constructorKey, weakMapFunction);
1556     RETURN_IF_ABRUPT_COMPLETION(thread_);
1557     // weakmap.prototype.set()
1558     SetFunction(env, weakMapFuncPrototype, globalConst->GetHandledSetString(), BuiltinsWeakMap::Set,
1559                 FunctionLength::TWO);
1560     // weakmap.prototype.delete()
1561     SetFunction(env, weakMapFuncPrototype, "delete", BuiltinsWeakMap::Delete, FunctionLength::ONE);
1562     // weakmap.prototype.has()
1563     SetFunction(env, weakMapFuncPrototype, "has", BuiltinsWeakMap::Has, FunctionLength::ONE);
1564     // weakmap.prototype.get()
1565     SetFunction(env, weakMapFuncPrototype, thread_->GlobalConstants()->GetHandledGetString(), BuiltinsWeakMap::Get,
1566                 FunctionLength::ONE);
1567     // @@ToStringTag
1568     SetStringTagSymbol(env, weakMapFuncPrototype, "WeakMap");
1569 
1570     env->SetBuiltinsWeakMapFunction(thread_, weakMapFunction);
1571 }
1572 
LazyInitializeWeakMap(const JSHandle<GlobalEnv> & env) const1573 void Builtins::LazyInitializeWeakMap(const JSHandle<GlobalEnv> &env) const
1574 {
1575     [[maybe_unused]] EcmaHandleScope scope(thread_);
1576     JSHandle<JSObject> globalObject(thread_, env->GetGlobalObject());
1577     JSHandle<JSTaggedValue> key(factory_->NewFromUtf8ReadOnly("WeakMap"));
1578     auto accessor = factory_->NewInternalAccessor(nullptr, reinterpret_cast<void *>(BuiltinsLazyCallback::WeakMap));
1579     SetLazyAccessor(globalObject, key, accessor);
1580     env->SetBuiltinsWeakMapFunction(thread_, accessor);
1581 }
1582 
InitializeWeakSet(const JSHandle<GlobalEnv> & env,const JSHandle<JSHClass> & objFuncClass) const1583 void Builtins::InitializeWeakSet(const JSHandle<GlobalEnv> &env, const JSHandle<JSHClass> &objFuncClass) const
1584 {
1585     [[maybe_unused]] EcmaHandleScope scope(thread_);
1586     const GlobalEnvConstants *globalConst = thread_->GlobalConstants();
1587     // Set.prototype
1588     JSHandle<JSObject> weakSetFuncPrototype = factory_->NewJSObjectWithInit(objFuncClass);
1589     JSHandle<JSTaggedValue> weakSetFuncPrototypeValue(weakSetFuncPrototype);
1590     // Set.prototype_or_hclass
1591     JSHandle<JSHClass> weakSetFuncInstanceHClass =
1592         factory_->NewEcmaHClass(JSWeakSet::SIZE, JSType::JS_WEAK_SET, weakSetFuncPrototypeValue);
1593     // Set() = new Function()
1594     JSHandle<JSTaggedValue> weakSetFunction(NewBuiltinConstructor(
1595         env, weakSetFuncPrototype, BuiltinsWeakSet::WeakSetConstructor, "WeakSet", FunctionLength::ZERO));
1596     JSHandle<JSFunction>(weakSetFunction)->SetProtoOrHClass(thread_, weakSetFuncInstanceHClass.GetTaggedValue());
1597 
1598     // "constructor" property on the prototype
1599     JSHandle<JSTaggedValue> constructorKey = globalConst->GetHandledConstructorString();
1600     JSObject::SetProperty(thread_, JSHandle<JSTaggedValue>(weakSetFuncPrototype), constructorKey, weakSetFunction);
1601     RETURN_IF_ABRUPT_COMPLETION(thread_);
1602     // set.prototype.add()
1603     SetFunction(env, weakSetFuncPrototype, "add", BuiltinsWeakSet::Add, FunctionLength::ONE);
1604     // set.prototype.delete()
1605     SetFunction(env, weakSetFuncPrototype, "delete", BuiltinsWeakSet::Delete, FunctionLength::ONE);
1606     // set.prototype.has()
1607     SetFunction(env, weakSetFuncPrototype, "has", BuiltinsWeakSet::Has, FunctionLength::ONE);
1608 
1609     // @@ToStringTag
1610     SetStringTagSymbol(env, weakSetFuncPrototype, "WeakSet");
1611 
1612     env->SetBuiltinsWeakSetFunction(thread_, weakSetFunction);
1613 }
1614 
LazyInitializeWeakSet(const JSHandle<GlobalEnv> & env) const1615 void Builtins::LazyInitializeWeakSet(const JSHandle<GlobalEnv> &env) const
1616 {
1617     [[maybe_unused]] EcmaHandleScope scope(thread_);
1618     JSHandle<JSObject> globalObject(thread_, env->GetGlobalObject());
1619     JSHandle<JSTaggedValue> key(factory_->NewFromUtf8ReadOnly("WeakSet"));
1620     auto accessor = factory_->NewInternalAccessor(nullptr, reinterpret_cast<void *>(BuiltinsLazyCallback::WeakSet));
1621     SetLazyAccessor(globalObject, key, accessor);
1622     env->SetBuiltinsWeakSetFunction(thread_, accessor);
1623 }
1624 
InitializeAtomics(const JSHandle<GlobalEnv> & env,const JSHandle<JSTaggedValue> & objFuncPrototypeVal) const1625 void Builtins::InitializeAtomics(const JSHandle<GlobalEnv> &env,
1626                                  const JSHandle<JSTaggedValue> &objFuncPrototypeVal) const
1627 {
1628     [[maybe_unused]] EcmaHandleScope scope(thread_);
1629     JSHandle<JSHClass> atomicsHClass = factory_->NewEcmaHClass(JSObject::SIZE, JSType::JS_OBJECT,
1630                                                                objFuncPrototypeVal);
1631     JSHandle<JSObject> atomicsObject = factory_->NewJSObject(atomicsHClass);
1632     // Atomics functions
1633     for (const base::BuiltinFunctionEntry &entry: Atomics::GetAtomicsFunctions()) {
1634         SetFunction(env, atomicsObject, entry.GetName(), entry.GetEntrypoint(),
1635                     entry.GetLength(), entry.GetBuiltinStubId());
1636     }
1637     JSHandle<JSTaggedValue> atomicsString(factory_->NewFromASCIIReadOnly("Atomics"));
1638     JSHandle<JSObject> globalObject(thread_, env->GetGlobalObject());
1639     PropertyDescriptor atomicsDesc(thread_, JSHandle<JSTaggedValue>::Cast(atomicsObject), true, false, true);
1640     JSObject::DefineOwnProperty(thread_, globalObject, atomicsString, atomicsDesc);
1641     // @@ToStringTag
1642     SetStringTagSymbol(env, atomicsObject, "Atomics");
1643     env->SetAtomicsFunction(thread_, atomicsObject);
1644 }
1645 
InitializeWeakRef(const JSHandle<GlobalEnv> & env,const JSHandle<JSHClass> & objFuncClass) const1646 void Builtins::InitializeWeakRef(const JSHandle<GlobalEnv> &env, const JSHandle<JSHClass> &objFuncClass) const
1647 {
1648     [[maybe_unused]] EcmaHandleScope scope(thread_);
1649     const GlobalEnvConstants *globalConst = thread_->GlobalConstants();
1650     // WeakRef.prototype
1651     JSHandle<JSObject> weakRefFuncPrototype = factory_->NewJSObject(objFuncClass);
1652     JSHandle<JSTaggedValue> weakRefFuncPrototypeValue(weakRefFuncPrototype);
1653     // WeakRef.prototype_or_hclass
1654     JSHandle<JSHClass> weakRefFuncInstanceHClass =
1655         factory_->NewEcmaHClass(JSWeakRef::SIZE, JSType::JS_WEAK_REF, weakRefFuncPrototypeValue);
1656     // WeakRef() = new Function()
1657     JSHandle<JSTaggedValue> weakRefFunction(NewBuiltinConstructor(
1658         env, weakRefFuncPrototype, BuiltinsWeakRef::WeakRefConstructor, "WeakRef", FunctionLength::ONE));
1659     JSHandle<JSFunction>(weakRefFunction)->SetProtoOrHClass(thread_, weakRefFuncInstanceHClass.GetTaggedValue());
1660 
1661     // "constructor" property on the prototype
1662     JSHandle<JSTaggedValue> constructorKey = globalConst->GetHandledConstructorString();
1663     JSObject::SetProperty(thread_, JSHandle<JSTaggedValue>(weakRefFuncPrototype), constructorKey, weakRefFunction);
1664     RETURN_IF_ABRUPT_COMPLETION(thread_);
1665     // WeakRef.prototype.deref()
1666     SetFunction(env, weakRefFuncPrototype, "deref", BuiltinsWeakRef::Deref, FunctionLength::ZERO);
1667 
1668     // @@ToStringTag
1669     SetStringTagSymbol(env, weakRefFuncPrototype, "WeakRef");
1670 
1671     env->SetBuiltinsWeakRefFunction(thread_, weakRefFunction);
1672 }
1673 
LazyInitializeWeakRef(const JSHandle<GlobalEnv> & env) const1674 void Builtins::LazyInitializeWeakRef(const JSHandle<GlobalEnv> &env) const
1675 {
1676     [[maybe_unused]] EcmaHandleScope scope(thread_);
1677     JSHandle<JSObject> globalObject(thread_, env->GetGlobalObject());
1678     JSHandle<JSTaggedValue> key(factory_->NewFromUtf8ReadOnly("WeakRef"));
1679     auto accessor = factory_->NewInternalAccessor(nullptr, reinterpret_cast<void *>(BuiltinsLazyCallback::WeakRef));
1680     SetLazyAccessor(globalObject, key, accessor);
1681     env->SetBuiltinsWeakRefFunction(thread_, accessor);
1682 }
1683 
InitializeFinalizationRegistry(const JSHandle<GlobalEnv> & env,const JSHandle<JSHClass> & objFuncClass) const1684 void Builtins::InitializeFinalizationRegistry(const JSHandle<GlobalEnv> &env,
1685                                               const JSHandle<JSHClass> &objFuncClass) const
1686 {
1687     [[maybe_unused]] EcmaHandleScope scope(thread_);
1688     const GlobalEnvConstants *globalConst = thread_->GlobalConstants();
1689     // FinalizationRegistry.prototype
1690     JSHandle<JSObject> finalizationRegistryFuncPrototype = factory_->NewJSObject(objFuncClass);
1691     JSHandle<JSTaggedValue> finalizationRegistryFuncPrototypeValue(finalizationRegistryFuncPrototype);
1692     // FinalizationRegistry.prototype_or_hclass
1693     JSHandle<JSHClass> finalizationRegistryFuncInstanceHClass =
1694         factory_->NewEcmaHClass(JSFinalizationRegistry::SIZE, JSType::JS_FINALIZATION_REGISTRY,
1695                                 finalizationRegistryFuncPrototypeValue);
1696     // FinalizationRegistry() = new Function()
1697     JSHandle<JSTaggedValue> finalizationRegistryFunction(NewBuiltinConstructor(
1698         env, finalizationRegistryFuncPrototype, BuiltinsFinalizationRegistry::FinalizationRegistryConstructor,
1699         "FinalizationRegistry", FunctionLength::ONE));
1700     JSHandle<JSFunction>(finalizationRegistryFunction)->SetProtoOrHClass(
1701         thread_, finalizationRegistryFuncInstanceHClass.GetTaggedValue());
1702 
1703     // "constructor" property on the prototype
1704     JSHandle<JSTaggedValue> constructorKey = globalConst->GetHandledConstructorString();
1705     JSObject::SetProperty(thread_, JSHandle<JSTaggedValue>(finalizationRegistryFuncPrototype),
1706                           constructorKey, finalizationRegistryFunction);
1707     RETURN_IF_ABRUPT_COMPLETION(thread_);
1708     // FinalizationRegistry.prototype.deref()
1709     SetFunction(env, finalizationRegistryFuncPrototype, "register",
1710                 BuiltinsFinalizationRegistry::Register, FunctionLength::TWO);
1711     SetFunction(env, finalizationRegistryFuncPrototype, "unregister",
1712                 BuiltinsFinalizationRegistry::Unregister, FunctionLength::ONE);
1713     // @@ToStringTag
1714     SetStringTagSymbol(env, finalizationRegistryFuncPrototype, "FinalizationRegistry");
1715 
1716     env->SetBuiltinsFinalizationRegistryFunction(thread_, finalizationRegistryFunction);
1717 }
1718 
LazyInitializeFinalizationRegistry(const JSHandle<GlobalEnv> & env) const1719 void Builtins::LazyInitializeFinalizationRegistry(const JSHandle<GlobalEnv> &env) const
1720 {
1721     [[maybe_unused]] EcmaHandleScope scope(thread_);
1722     JSHandle<JSObject> globalObject(thread_, env->GetGlobalObject());
1723     JSHandle<JSTaggedValue> key(factory_->NewFromUtf8ReadOnly("FinalizationRegistry"));
1724     auto accessor = factory_->NewInternalAccessor(nullptr,
1725         reinterpret_cast<void *>(BuiltinsLazyCallback::FinalizationRegistry));
1726     SetLazyAccessor(globalObject, key, accessor);
1727     env->SetBuiltinsFinalizationRegistryFunction(thread_, accessor);
1728 }
1729 
InitializeMath(const JSHandle<GlobalEnv> & env,const JSHandle<JSTaggedValue> & objFuncPrototypeVal) const1730 void Builtins::InitializeMath(const JSHandle<GlobalEnv> &env, const JSHandle<JSTaggedValue> &objFuncPrototypeVal) const
1731 {
1732     [[maybe_unused]] EcmaHandleScope scope(thread_);
1733     JSHandle<JSHClass> mathClass = factory_->NewEcmaHClass(JSObject::SIZE, JSType::JS_OBJECT, objFuncPrototypeVal);
1734     JSHandle<JSObject> mathObject = factory_->NewJSObjectWithInit(mathClass);
1735     RandomGenerator::InitRandom(thread_);
1736 
1737     for (const base::BuiltinFunctionEntry &entry: Math::GetMathFunctions()) {
1738         SetFunction(env, mathObject, entry.GetName(), entry.GetEntrypoint(),
1739                     entry.GetLength(), entry.GetBuiltinStubId());
1740     }
1741     for (const base::BuiltinConstantEntry &entry: Math::GetMathConstants()) {
1742         SetConstant(mathObject, entry.GetName(), entry.GetTaggedValue());
1743     }
1744     JSHandle<JSTaggedValue> mathString(factory_->NewFromASCIIReadOnly("Math"));
1745     JSHandle<JSObject> globalObject(thread_, env->GetGlobalObject());
1746     PropertyDescriptor mathDesc(thread_, JSHandle<JSTaggedValue>::Cast(mathObject), true, false, true);
1747     JSObject::DefineOwnProperty(thread_, globalObject, mathString, mathDesc);
1748     // @@ToStringTag
1749     SetStringTagSymbol(env, mathObject, "Math");
1750     env->SetMathFunction(thread_, mathObject);
1751     env->SetMathFunctionClass(thread_, JSHandle<JSHClass>(thread_, mathObject->GetJSHClass()));
1752 }
1753 
InitializeJson(const JSHandle<GlobalEnv> & env,const JSHandle<JSTaggedValue> & objFuncPrototypeVal) const1754 void Builtins::InitializeJson(const JSHandle<GlobalEnv> &env, const JSHandle<JSTaggedValue> &objFuncPrototypeVal) const
1755 {
1756     [[maybe_unused]] EcmaHandleScope scope(thread_);
1757     JSHandle<JSHClass> jsonHClass = factory_->NewEcmaHClass(JSObject::SIZE, JSType::JS_OBJECT, objFuncPrototypeVal);
1758     JSHandle<JSObject> jsonObject = factory_->NewJSObjectWithInit(jsonHClass);
1759 
1760     SetFunction(env, jsonObject, "parse", Json::Parse, FunctionLength::TWO);
1761     SetFunction(env, jsonObject, "parseSendable", SendableJson::Parse, FunctionLength::THREE);
1762     SetFunction(env, jsonObject, "parseBigInt", BigIntJson::Parse, FunctionLength::THREE);
1763     SetFunction(env, jsonObject, "stringify", Json::Stringify, FunctionLength::THREE, BUILTINS_STUB_ID(JsonStringify));
1764     SetFunction(env, jsonObject, "stringifySendable", SendableJson::Stringify, FunctionLength::THREE);
1765     SetFunction(env, jsonObject, "stringifyBigInt", BigIntJson::Stringify, FunctionLength::THREE);
1766 
1767     PropertyDescriptor jsonDesc(thread_, JSHandle<JSTaggedValue>::Cast(jsonObject), true, false, true);
1768     JSHandle<JSTaggedValue> jsonString(factory_->NewFromASCIIReadOnly("JSON"));
1769     JSHandle<JSObject> globalObject(thread_, env->GetGlobalObject());
1770     JSObject::DefineOwnProperty(thread_, globalObject, jsonString, jsonDesc);
1771     // @@ToStringTag
1772     SetStringTagSymbol(env, jsonObject, "JSON");
1773     env->SetJsonFunction(thread_, jsonObject);
1774 }
1775 
InitializeString(const JSHandle<GlobalEnv> & env,JSHandle<JSTaggedValue> objFuncPrototypeVal) const1776 void Builtins::InitializeString(const JSHandle<GlobalEnv> &env, JSHandle<JSTaggedValue> objFuncPrototypeVal) const
1777 {
1778     [[maybe_unused]] EcmaHandleScope scope(thread_);
1779     // String.prototype
1780     JSHandle<JSTaggedValue> toObject(factory_->GetEmptyString());
1781     JSHandle<JSHClass> primRefObjHClass =
1782         factory_->NewEcmaHClass(JSPrimitiveRef::SIZE, BuiltinsString::GetNumPrototypeInlinedProperties(),
1783                                 JSType::JS_PRIMITIVE_REF, objFuncPrototypeVal);
1784     JSHandle<JSObject> stringFuncPrototype =
1785         JSHandle<JSObject>::Cast(factory_->NewJSPrimitiveRef(primRefObjHClass, toObject));
1786     JSHandle<JSTaggedValue> stringFuncPrototypeValue(stringFuncPrototype);
1787 
1788     // String.prototype_or_hclass
1789     JSHandle<JSHClass> stringFuncInstanceHClass =
1790         factory_->NewEcmaHClass(JSPrimitiveRef::SIZE, JSType::JS_PRIMITIVE_REF, stringFuncPrototypeValue);
1791 
1792     // String = new Function()
1793     JSHandle<JSObject> stringFunction(NewBuiltinConstructor(env, stringFuncPrototype, BuiltinsString::StringConstructor,
1794                                                             "String", FunctionLength::ONE));
1795     JSFunction::SetFunctionPrototypeOrInstanceHClass(thread_,
1796                                                      JSHandle<JSFunction>(stringFunction),
1797                                                      stringFuncInstanceHClass.GetTaggedValue());
1798 
1799     // String.prototype method
1800     for (const base::BuiltinFunctionEntry &entry: BuiltinsString::GetStringPrototypeFunctions()) {
1801         SetFunction(env, stringFuncPrototype, entry.GetName(), entry.GetEntrypoint(),
1802                     entry.GetLength(), entry.GetBuiltinStubId());
1803     }
1804     JSHandle<JSTaggedValue> stringIter = SetAndReturnFunctionAtSymbol(env, stringFuncPrototype,
1805         env->GetIteratorSymbol(), "[Symbol.iterator]", BuiltinsString::GetStringIterator, FunctionLength::ZERO,
1806         BUILTINS_STUB_ID(StringGetStringIterator));
1807 
1808     // String method
1809     for (const base::BuiltinFunctionEntry &entry: BuiltinsString::GetStringFunctions()) {
1810         SetFunction(env, stringFunction, entry.GetName(), entry.GetEntrypoint(),
1811                     entry.GetLength(), entry.GetBuiltinStubId());
1812     }
1813 
1814     // String.prototype.length
1815     JSHandle<JSTaggedValue> lengthGetter = CreateGetter(env, BuiltinsString::GetLength, "length", FunctionLength::ZERO);
1816     JSHandle<JSTaggedValue> lengthKey(factory_->NewFromASCIIReadOnly("length"));
1817     SetGetter(stringFuncPrototype, lengthKey, lengthGetter);
1818 
1819     env->SetStringFunction(thread_, stringFunction);
1820     env->SetStringPrototype(thread_, stringFuncPrototype);
1821     env->SetStringProtoIterFunction(thread_, stringIter);
1822     thread_->SetInitialBuiltinHClass(BuiltinTypeId::STRING, nullptr, nullptr, stringFuncPrototype->GetJSHClass());
1823 }
1824 
InitializeStringIterator(const JSHandle<GlobalEnv> & env,const JSHandle<JSHClass> & iteratorFuncClass) const1825 void Builtins::InitializeStringIterator(const JSHandle<GlobalEnv> &env,
1826                                         const JSHandle<JSHClass> &iteratorFuncClass) const
1827 {
1828     // StringIterator.prototype
1829     JSHandle<JSObject> strIterPrototype(factory_->NewJSObjectWithInit(iteratorFuncClass));
1830 
1831     // StringIterator.prototype_or_hclass
1832     JSHandle<JSHClass> strIterFuncInstanceHClass = factory_->NewEcmaHClass(
1833         JSStringIterator::SIZE, JSType::JS_STRING_ITERATOR, JSHandle<JSTaggedValue>(strIterPrototype));
1834 
1835     JSHandle<JSFunction> strIterFunction(
1836         factory_->NewJSBuiltinFunction(env, static_cast<void *>(nullptr), FunctionKind::BASE_CONSTRUCTOR));
1837     JSFunction::SetFunctionPrototypeOrInstanceHClass(thread_, strIterFunction,
1838                                                      strIterFuncInstanceHClass.GetTaggedValue());
1839 
1840     SetFunction(env, strIterPrototype, "next", StringIterator::Next, FunctionLength::ZERO,
1841                 BUILTINS_STUB_ID(StringIteratorProtoNext));
1842     SetStringTagSymbol(env, strIterPrototype, "String Iterator");
1843 
1844     env->SetStringIterator(thread_, strIterFunction);
1845     env->SetStringIteratorClass(thread_, strIterFuncInstanceHClass);
1846     env->SetStringIteratorPrototype(thread_, strIterPrototype);
1847 }
1848 
InitializeAsyncFromSyncIterator(const JSHandle<GlobalEnv> & env,const JSHandle<JSHClass> & iteratorFuncClass) const1849 void Builtins::InitializeAsyncFromSyncIterator(const JSHandle<GlobalEnv> &env,
1850                                                const JSHandle<JSHClass> &iteratorFuncClass) const
1851 {
1852     [[maybe_unused]] EcmaHandleScope scope(thread_);
1853 
1854     JSHandle<JSObject> asyncItPrototype = factory_->NewJSObjectWithInit(iteratorFuncClass);
1855     SetFunction(env, asyncItPrototype, "next", BuiltinsAsyncFromSyncIterator::Next, FunctionLength::ONE);
1856     SetFunction(env, asyncItPrototype, "return", BuiltinsAsyncFromSyncIterator::Return, FunctionLength::ONE);
1857     SetFunction(env, asyncItPrototype, "throw", BuiltinsAsyncFromSyncIterator::Throw, FunctionLength::ONE);
1858     JSHandle<JSHClass> hclass = factory_->NewEcmaHClass(JSAsyncFromSyncIterator::SIZE,
1859                                                         JSType::JS_ASYNC_FROM_SYNC_ITERATOR,
1860                                                         JSHandle<JSTaggedValue>(asyncItPrototype));
1861     JSHandle<JSFunction> iterFunction(
1862         factory_->NewJSBuiltinFunction(env, static_cast<void *>(nullptr), FunctionKind::BASE_CONSTRUCTOR));
1863     JSFunction::SetFunctionPrototypeOrInstanceHClass(thread_, iterFunction, hclass.GetTaggedValue());
1864     env->SetAsyncFromSyncIterator(thread_, iterFunction);
1865     env->SetAsyncFromSyncIteratorPrototype(thread_, asyncItPrototype);
1866 
1867     JSHandle<JSHClass> asyncFromSyncIterUnwarpClass =
1868         factory_->NewEcmaHClass(JSAsyncFromSyncIterUnwarpFunction::SIZE,
1869                                 JSType::JS_ASYNC_FROM_SYNC_ITER_UNWARP_FUNCTION,
1870                                 env->GetFunctionPrototype());
1871     asyncFromSyncIterUnwarpClass->SetCallable(true);
1872     asyncFromSyncIterUnwarpClass->SetExtensible(true);
1873     env->SetAsyncFromSyncIterUnwarpClass(thread_, asyncFromSyncIterUnwarpClass);
1874 }
1875 
InitializeIterator(const JSHandle<GlobalEnv> & env,const JSHandle<JSHClass> & objFuncClass) const1876 void Builtins::InitializeIterator(const JSHandle<GlobalEnv> &env, const JSHandle<JSHClass> &objFuncClass) const
1877 {
1878     [[maybe_unused]] EcmaHandleScope scope(thread_);
1879     // Iterator.prototype
1880     JSHandle<JSObject> iteratorPrototype = factory_->NewJSObjectWithInit(objFuncClass);
1881     // Iterator.prototype.next()
1882     SetFunction(env, iteratorPrototype, "next", BuiltinsIterator::Next, FunctionLength::ONE);
1883     // Iterator.prototype.return()
1884     SetFunction(env, iteratorPrototype, "return", BuiltinsIterator::Return, FunctionLength::ONE,
1885         BUILTINS_STUB_ID(IteratorProtoReturn));
1886     // Iterator.prototype.throw()
1887     SetFunction(env, iteratorPrototype, "throw", BuiltinsIterator::Throw, FunctionLength::ONE);
1888     // %IteratorPrototype% [ @@iterator ]
1889     SetFunctionAtSymbol(env, iteratorPrototype, env->GetIteratorSymbol(), "[Symbol.iterator]",
1890                         BuiltinsIterator::GetIteratorObj, FunctionLength::ZERO);
1891     env->SetIteratorPrototype(thread_, iteratorPrototype);
1892 
1893     // Iterator.hclass
1894     JSHandle<JSHClass> iteratorFuncClass =
1895         factory_->NewEcmaHClass(JSObject::SIZE, JSType::JS_ITERATOR, JSHandle<JSTaggedValue>(iteratorPrototype));
1896     env->SetIteratorFuncClass(thread_, iteratorFuncClass);
1897 
1898     // Iterator result hclass
1899     JSHandle<JSHClass> iterResultHClass = factory_->CreateIteratorResultInstanceClass(env);
1900     env->SetIteratorResultClass(thread_, iterResultHClass);
1901 
1902     thread_->SetInitialBuiltinHClass(BuiltinTypeId::ITERATOR, nullptr,
1903         *iteratorFuncClass, iteratorPrototype->GetJSHClass());
1904 
1905     // iteratorPrototype hclass
1906     JSHandle<JSHClass> iteratorPrototypeHClass(thread_, iteratorPrototype->GetJSHClass());
1907 
1908     InitializeForinIterator(env, iteratorFuncClass);
1909     InitializeSetIterator(env, iteratorFuncClass);
1910     InitializeSSetIterator(env, iteratorFuncClass);
1911     InitializeMapIterator(env, iteratorFuncClass);
1912     InitializeSMapIterator(env, iteratorFuncClass);
1913     InitializeArrayIterator(env, iteratorFuncClass, iteratorPrototypeHClass);
1914     InitializeSArrayIterator(env, iteratorFuncClass);
1915     InitializeStringIterator(env, iteratorFuncClass);
1916     InitializeRegexpIterator(env, iteratorFuncClass);
1917 #ifdef ARK_SUPPORT_INTL
1918     InitializeSegmentIterator(env, iteratorFuncClass);
1919 #endif
1920 }
1921 
InitializeAsyncIterator(const JSHandle<GlobalEnv> & env,const JSHandle<JSHClass> & objFuncDynclass) const1922 void Builtins::InitializeAsyncIterator(const JSHandle<GlobalEnv> &env, const JSHandle<JSHClass> &objFuncDynclass) const
1923 {
1924     [[maybe_unused]] EcmaHandleScope scope(thread_);
1925     // AsyncIterator.prototype
1926     JSHandle<JSObject> asyncIteratorPrototype = factory_->NewJSObjectWithInit(objFuncDynclass);
1927     // AsyncIterator.prototype.next()
1928     SetFunction(env, asyncIteratorPrototype, "next", BuiltinsAsyncIterator::Next, FunctionLength::ONE);
1929     // AsyncIterator.prototype.return()
1930     SetFunction(env, asyncIteratorPrototype, "return", BuiltinsAsyncIterator::Return, FunctionLength::ONE);
1931     // AsyncIterator.prototype.throw()
1932     SetFunction(env, asyncIteratorPrototype, "throw", BuiltinsAsyncIterator::Throw, FunctionLength::ONE);
1933     // %AsyncIteratorPrototype% [ @@AsyncIterator ]
1934     SetFunctionAtSymbol(env, asyncIteratorPrototype, env->GetAsyncIteratorSymbol(), "[Symbol.asyncIterator]",
1935                         BuiltinsAsyncIterator::GetAsyncIteratorObj, FunctionLength::ZERO);
1936     env->SetAsyncIteratorPrototype(thread_, asyncIteratorPrototype);
1937 }
1938 
InitializeForinIterator(const JSHandle<GlobalEnv> & env,const JSHandle<JSHClass> & iteratorFuncClass) const1939 void Builtins::InitializeForinIterator(const JSHandle<GlobalEnv> &env,
1940                                        const JSHandle<JSHClass> &iteratorFuncClass) const
1941 {
1942     [[maybe_unused]] EcmaHandleScope scope(thread_);
1943     // Iterator.prototype
1944     JSHandle<JSObject> forinIteratorPrototype = factory_->NewJSObjectWithInit(iteratorFuncClass);
1945     JSHandle<JSHClass> hclass = factory_->NewEcmaHClass(JSForInIterator::SIZE, JSType::JS_FORIN_ITERATOR,
1946                                                         JSHandle<JSTaggedValue>(forinIteratorPrototype));
1947 
1948     // Iterator.prototype.next()
1949     SetFunction(env, forinIteratorPrototype, "next", JSForInIterator::Next, FunctionLength::ONE);
1950     env->SetForinIteratorPrototype(thread_, forinIteratorPrototype);
1951     env->SetForinIteratorClass(thread_, hclass);
1952 }
1953 
InitializeSetIterator(const JSHandle<GlobalEnv> & env,const JSHandle<JSHClass> & iteratorFuncClass) const1954 void Builtins::InitializeSetIterator(const JSHandle<GlobalEnv> &env,
1955                                      const JSHandle<JSHClass> &iteratorFuncClass) const
1956 {
1957     // SetIterator.prototype
1958     JSHandle<JSObject> setIteratorPrototype(factory_->NewJSObjectWithInit(iteratorFuncClass));
1959     // Iterator.prototype.next()
1960     SetFunction(env, setIteratorPrototype, "next", JSSetIterator::Next, FunctionLength::ZERO,
1961                 BUILTINS_STUB_ID(SetIteratorProtoNext));
1962     SetStringTagSymbol(env, setIteratorPrototype, "Set Iterator");
1963     env->SetSetIteratorPrototype(thread_, setIteratorPrototype);
1964     JSHandle<JSTaggedValue> protoValue = env->GetSetIteratorPrototype();
1965     const GlobalEnvConstants *globalConst = thread_->GlobalConstants();
1966     JSHandle<JSHClass> hclassHandle(globalConst->GetHandledJSSetIteratorClass());
1967     hclassHandle->SetPrototype(thread_, protoValue);
1968     hclassHandle->SetExtensible(true);
1969 }
1970 
InitializeSSetIterator(const JSHandle<GlobalEnv> & env,const JSHandle<JSHClass> & iteratorFuncClass) const1971 void Builtins::InitializeSSetIterator(const JSHandle<GlobalEnv> &env, const JSHandle<JSHClass> &iteratorFuncClass) const
1972 {
1973     // SetIterator.prototype
1974     JSHandle<JSObject> setIteratorPrototype(factory_->NewJSObjectWithInit(iteratorFuncClass));
1975     // Iterator.prototype.next()
1976     SetFunction(env, setIteratorPrototype, "next", JSSharedSetIterator::Next, FunctionLength::ZERO);
1977     SetStringTagSymbol(env, setIteratorPrototype, "SharedSet Iterator");
1978     env->SetSharedSetIteratorPrototype(thread_, setIteratorPrototype);
1979     JSHandle<JSTaggedValue> protoValue = env->GetSharedSetIteratorPrototype();
1980     const GlobalEnvConstants *globalConst = thread_->GlobalConstants();
1981     JSHandle<JSHClass> hclassHandle(globalConst->GetHandledJSSharedSetIteratorClass());
1982     hclassHandle->SetPrototype(thread_, protoValue);
1983     hclassHandle->SetExtensible(true);
1984 }
1985 
InitializeMapIterator(const JSHandle<GlobalEnv> & env,const JSHandle<JSHClass> & iteratorFuncClass) const1986 void Builtins::InitializeMapIterator(const JSHandle<GlobalEnv> &env,
1987                                      const JSHandle<JSHClass> &iteratorFuncClass) const
1988 {
1989     // MapIterator.prototype
1990     JSHandle<JSObject> mapIteratorPrototype(factory_->NewJSObjectWithInit(iteratorFuncClass));
1991     // Iterator.prototype.next()
1992     SetFunction(env, mapIteratorPrototype, "next", JSMapIterator::Next, FunctionLength::ZERO,
1993                 BUILTINS_STUB_ID(MapIteratorProtoNext));
1994     SetStringTagSymbol(env, mapIteratorPrototype, "Map Iterator");
1995     env->SetMapIteratorPrototype(thread_, mapIteratorPrototype);
1996     JSHandle<JSTaggedValue> protoValue = env->GetMapIteratorPrototype();
1997     const GlobalEnvConstants *globalConst = thread_->GlobalConstants();
1998     JSHandle<JSHClass> hclassHandle(globalConst->GetHandledJSMapIteratorClass());
1999     hclassHandle->SetPrototype(thread_, protoValue);
2000     hclassHandle->SetExtensible(true);
2001 }
2002 
InitializeSMapIterator(const JSHandle<GlobalEnv> & env,const JSHandle<JSHClass> & iteratorFuncClass) const2003 void Builtins::InitializeSMapIterator(const JSHandle<GlobalEnv> &env,
2004                                       const JSHandle<JSHClass> &iteratorFuncClass) const
2005 {
2006     // MapIterator.prototype
2007     JSHandle<JSObject> mapIteratorPrototype(factory_->NewJSObjectWithInit(iteratorFuncClass));
2008     // Iterator.prototype.next()
2009     SetFunction(env, mapIteratorPrototype, "next", JSSharedMapIterator::Next, FunctionLength::ZERO);
2010     SetStringTagSymbol(env, mapIteratorPrototype, "SharedMap Iterator");
2011     env->SetSharedMapIteratorPrototype(thread_, mapIteratorPrototype);
2012     JSHandle<JSTaggedValue> protoValue = env->GetSharedMapIteratorPrototype();
2013     const GlobalEnvConstants *globalConst = thread_->GlobalConstants();
2014     JSHandle<JSHClass> hclassHandle(globalConst->GetHandledJSSharedMapIteratorClass());
2015     hclassHandle->SetPrototype(thread_, protoValue);
2016     hclassHandle->SetExtensible(true);
2017 }
2018 
InitializeArrayIterator(const JSHandle<GlobalEnv> & env,const JSHandle<JSHClass> & iteratorFuncClass,const JSHandle<JSHClass> & iteratorPrototypeClass) const2019 void Builtins::InitializeArrayIterator(const JSHandle<GlobalEnv> &env,
2020                                        const JSHandle<JSHClass> &iteratorFuncClass,
2021                                        const JSHandle<JSHClass> &iteratorPrototypeClass) const
2022 {
2023     // ArrayIterator.prototype
2024     JSHandle<JSObject> arrayIteratorPrototype(factory_->NewJSObjectWithInit(iteratorFuncClass));
2025     JSHandle<JSTaggedValue> arrayIteratorPrototypeValue(arrayIteratorPrototype);
2026     auto globalConst = const_cast<GlobalEnvConstants *>(thread_->GlobalConstants());
2027     JSHandle<JSHClass> arrayIteratorInstanceHClass(globalConst->GetHandledJSArrayIteratorClass());
2028     // Iterator.prototype.next()
2029     SetFunction(env, arrayIteratorPrototype, "next", JSArrayIterator::Next, FunctionLength::ZERO,
2030                 BUILTINS_STUB_ID(ArrayIteratorProtoNext));
2031     arrayIteratorInstanceHClass->SetPrototype(thread_, arrayIteratorPrototypeValue);
2032     SetStringTagSymbol(env, arrayIteratorPrototype, "Array Iterator");
2033     thread_->SetInitialBuiltinHClass(BuiltinTypeId::ARRAY_ITERATOR, nullptr,
2034         *arrayIteratorInstanceHClass, arrayIteratorPrototype->GetJSHClass(), *iteratorPrototypeClass);
2035     env->SetArrayIteratorPrototype(thread_, arrayIteratorPrototype);
2036 }
2037 
InitializeSArrayIterator(const JSHandle<GlobalEnv> & env,const JSHandle<JSHClass> & iteratorFuncClass) const2038 void Builtins::InitializeSArrayIterator(const JSHandle<GlobalEnv> &env,
2039                                         const JSHandle<JSHClass> &iteratorFuncClass) const
2040 {
2041     // ArrayIterator.prototype
2042     JSHandle<JSObject> arrayIteratorPrototype(factory_->NewJSObjectWithInit(iteratorFuncClass));
2043     // Iterator.prototype.next()
2044     SetFunction(env, arrayIteratorPrototype, "next", JSSharedArrayIterator::Next, FunctionLength::ZERO);
2045     SetStringTagSymbol(env, arrayIteratorPrototype, "SharedArray Iterator");
2046     env->SetSharedArrayIteratorPrototype(thread_, arrayIteratorPrototype);
2047 }
2048 
InitializeRegexpIterator(const JSHandle<GlobalEnv> & env,const JSHandle<JSHClass> & iteratorFuncClass) const2049 void Builtins::InitializeRegexpIterator(const JSHandle<GlobalEnv> &env,
2050                                         const JSHandle<JSHClass> &iteratorFuncClass) const
2051 {
2052     // RegExpIterator.prototype
2053     JSHandle<JSObject> regExpIteratorPrototype(factory_->NewJSObject(iteratorFuncClass));
2054     // Iterator.prototype.next()
2055     SetFunction(env, regExpIteratorPrototype, "next", JSRegExpIterator::Next, FunctionLength::ZERO);
2056     SetStringTagSymbol(env, regExpIteratorPrototype, "RegExp String Iterator");
2057     env->SetRegExpIteratorPrototype(thread_, regExpIteratorPrototype);
2058 }
2059 
InitializeRegExp(const JSHandle<GlobalEnv> & env)2060 void Builtins::InitializeRegExp(const JSHandle<GlobalEnv> &env)
2061 {
2062     [[maybe_unused]] EcmaHandleScope scope(thread_);
2063     // RegExp.prototype
2064     JSHandle<JSFunction> objFun(env->GetObjectFunction());
2065     JSHandle<JSObject> regPrototype = factory_->NewJSObjectByConstructor(env, objFun, REGEXP_INLINE_PROPS);
2066     JSHandle<JSTaggedValue> regPrototypeValue(regPrototype);
2067 
2068     // RegExp.prototype_or_hclass
2069     JSHandle<JSHClass> regexpFuncInstanceHClass = factory_->CreateJSRegExpInstanceClass(regPrototypeValue);
2070 
2071     // RegExp = new Function()
2072     JSHandle<JSObject> regexpFunction(
2073         NewBuiltinConstructor(env, regPrototype, RegExp::RegExpConstructor, "RegExp", FunctionLength::TWO));
2074 
2075     // initialize RegExp.$1 .. $9 static and read-only attributes
2076     InitializeGlobalRegExp(regexpFunction);
2077 
2078     JSFunction::SetFunctionPrototypeOrInstanceHClass(thread_,
2079                                                      JSHandle<JSFunction>(regexpFunction),
2080                                                      regexpFuncInstanceHClass.GetTaggedValue());
2081 
2082     const GlobalEnvConstants *globalConstants = thread_->GlobalConstants();
2083     // RegExp.prototype method
2084     JSHandle<JSFunction> execFunc = SetAndReturnFunction(env, regPrototype, "exec", RegExp::Exec, FunctionLength::ONE);
2085     SetFunction(env, regPrototype, "test", RegExp::Test, FunctionLength::ONE);
2086     SetFunction(env, regPrototype, globalConstants->GetHandledToStringString(), RegExp::ToString,
2087                 FunctionLength::ZERO);
2088 
2089     JSHandle<JSTaggedValue> flagsGetter = CreateGetter(env, RegExp::GetFlags, "flags", FunctionLength::ZERO,
2090         BUILTINS_STUB_ID(RegExpGetFlags));
2091     JSHandle<JSTaggedValue> flagsKey(globalConstants->GetHandledFlagsString());
2092     SetGetter(regPrototype, flagsKey, flagsGetter);
2093 
2094     JSHandle<JSTaggedValue> sourceGetter = CreateGetter(env, RegExp::GetSource, "source", FunctionLength::ZERO);
2095     JSHandle<JSTaggedValue> sourceKey(globalConstants->GetHandledSourceString());
2096     SetGetter(regPrototype, sourceKey, sourceGetter);
2097 
2098     JSHandle<JSTaggedValue> globalGetter = CreateGetter(env, RegExp::GetGlobal, "global", FunctionLength::ZERO);
2099     JSHandle<JSTaggedValue> globalKey(globalConstants->GetHandledGlobalString());
2100     SetGetter(regPrototype, globalKey, globalGetter);
2101 
2102     JSHandle<JSTaggedValue> hasIndicesGetter =
2103         CreateGetter(env, RegExp::GetHasIndices, "hasIndices", FunctionLength::ZERO);
2104     JSHandle<JSTaggedValue> hasIndicesKey(factory_->NewFromASCIIReadOnly("hasIndices"));
2105     SetGetter(regPrototype, hasIndicesKey, hasIndicesGetter);
2106 
2107     JSHandle<JSTaggedValue> ignoreCaseGetter =
2108         CreateGetter(env, RegExp::GetIgnoreCase, "ignoreCase", FunctionLength::ZERO);
2109     JSHandle<JSTaggedValue> ignoreCaseKey(factory_->NewFromASCIIReadOnly("ignoreCase"));
2110     SetGetter(regPrototype, ignoreCaseKey, ignoreCaseGetter);
2111 
2112     JSHandle<JSTaggedValue> multilineGetter =
2113         CreateGetter(env, RegExp::GetMultiline, "multiline", FunctionLength::ZERO);
2114     JSHandle<JSTaggedValue> multilineKey(factory_->NewFromASCIIReadOnly("multiline"));
2115     SetGetter(regPrototype, multilineKey, multilineGetter);
2116 
2117     JSHandle<JSTaggedValue> dotAllGetter = CreateGetter(env, RegExp::GetDotAll, "dotAll", FunctionLength::ZERO);
2118     JSHandle<JSTaggedValue> dotAllKey(factory_->NewFromASCIIReadOnly("dotAll"));
2119     SetGetter(regPrototype, dotAllKey, dotAllGetter);
2120 
2121     JSHandle<JSTaggedValue> stickyGetter = CreateGetter(env, RegExp::GetSticky, "sticky", FunctionLength::ZERO);
2122     JSHandle<JSTaggedValue> stickyKey(globalConstants->GetHandledStickyString());
2123     SetGetter(regPrototype, stickyKey, stickyGetter);
2124 
2125     JSHandle<JSTaggedValue> unicodeGetter = CreateGetter(env, RegExp::GetUnicode, "unicode", FunctionLength::ZERO);
2126     JSHandle<JSTaggedValue> unicodeKey(globalConstants->GetHandledUnicodeString());
2127     SetGetter(regPrototype, unicodeKey, unicodeGetter);
2128 
2129     // Set RegExp [ @@species ]
2130     JSHandle<JSTaggedValue> speciesSymbol = env->GetSpeciesSymbol();
2131     JSHandle<JSTaggedValue> speciesGetter =
2132         CreateGetter(env, BuiltinsMap::Species, "[Symbol.species]", FunctionLength::ZERO);
2133     SetGetter(JSHandle<JSObject>(regexpFunction), speciesSymbol, speciesGetter);
2134 
2135     // Set RegExp.prototype[@@split]
2136     JSHandle<JSTaggedValue> splitFunc = SetAndReturnFunctionAtSymbol(
2137         env, regPrototype, env->GetSplitSymbol(), "[Symbol.split]", RegExp::Split, FunctionLength::TWO);
2138     // Set RegExp.prototype[@@search]
2139     JSHandle<JSTaggedValue> searchFunc = SetAndReturnFunctionAtSymbol(
2140         env, regPrototype, env->GetSearchSymbol(), "[Symbol.search]", RegExp::Search, FunctionLength::ONE);
2141     // Set RegExp.prototype[@@match]
2142     JSHandle<JSTaggedValue> matchFunc = SetAndReturnFunctionAtSymbol(
2143         env, regPrototype, env->GetMatchSymbol(), "[Symbol.match]", RegExp::Match, FunctionLength::ONE);
2144     // Set RegExp.prototype[@@matchAll]
2145     JSHandle<JSTaggedValue> matchAllFunc = SetAndReturnFunctionAtSymbol(
2146         env, regPrototype, env->GetMatchAllSymbol(), "[Symbol.matchAll]", RegExp::MatchAll, FunctionLength::ONE);
2147     // Set RegExp.prototype[@@replace]
2148     JSHandle<JSTaggedValue> replaceFunc = SetAndReturnFunctionAtSymbol(
2149         env, regPrototype, env->GetReplaceSymbol(), "[Symbol.replace]", RegExp::Replace, FunctionLength::TWO);
2150 
2151     env->SetRegExpFunction(thread_, regexpFunction);
2152     env->SetRegExpPrototype(thread_, regPrototype);
2153     env->SetRegExpExecFunction(thread_, execFunc);
2154     env->SetRegExpSplitFunction(thread_, splitFunc);
2155     env->SetRegExpSearchFunction(thread_, searchFunc);
2156     env->SetRegExpMatchFunction(thread_, matchFunc);
2157     env->SetRegExpMatchAllFunction(thread_, matchAllFunc);
2158     env->SetRegExpReplaceFunction(thread_, replaceFunc);
2159     // Set RegExp.prototype hclass
2160     JSHandle<JSHClass> regPrototypeClass(thread_, regPrototype->GetJSHClass());
2161     env->SetRegExpPrototypeClass(thread_, regPrototypeClass.GetTaggedValue());
2162 
2163     env->SetRegExpFuncInstanceClass(thread_, regexpFuncInstanceHClass);
2164 }
2165 
InitializeArray(const JSHandle<GlobalEnv> & env,const JSHandle<JSTaggedValue> & objFuncPrototypeVal,bool isRealm) const2166 void Builtins::InitializeArray(const JSHandle<GlobalEnv> &env, const JSHandle<JSTaggedValue> &objFuncPrototypeVal,
2167                                bool isRealm) const
2168 {
2169     [[maybe_unused]] EcmaHandleScope scope(thread_);
2170     // Arraybase.prototype
2171     JSHandle<JSHClass> arrBaseFuncInstanceHClass = JSArray::CreateJSArrayPrototypeClass(thread_, factory_,
2172         objFuncPrototypeVal, BuiltinsArray::GetNumPrototypeInlinedProperties());
2173     // Since we don't want the operations on the array prototype to go through the IR code.
2174     // Specially we set the bit of the array prototype to true.
2175     arrBaseFuncInstanceHClass->SetIsJSArrayPrototypeModified(true);
2176     // Array.prototype
2177     JSHandle<JSObject> arrFuncPrototype = factory_->NewJSObjectWithInit(arrBaseFuncInstanceHClass);
2178     JSHandle<JSArray>::Cast(arrFuncPrototype)->SetLength(FunctionLength::ZERO);
2179     auto accessor = thread_->GlobalConstants()->GetArrayLengthAccessor();
2180     JSArray::Cast(*arrFuncPrototype)->SetPropertyInlinedProps(thread_, JSArray::LENGTH_INLINE_PROPERTY_INDEX, accessor);
2181     JSHandle<JSTaggedValue> arrFuncPrototypeValue(arrFuncPrototype);
2182 
2183     //  Array.prototype_or_hclass
2184     JSMutableHandle<JSHClass> arrFuncInstanceHClass(thread_, JSTaggedValue::Undefined());
2185     arrFuncInstanceHClass.Update(factory_->CreateJSArrayInstanceClass(env, arrFuncPrototypeValue));
2186     env->SetArrayClass(thread_, arrFuncInstanceHClass);
2187     env->InitElementKindHClass(thread_, arrFuncInstanceHClass);
2188     if (thread_->GetEcmaVM()->IsEnableElementsKind()) {
2189         // for all JSArray, the initial ElementsKind should be NONE
2190         // For PGO, currently we do not support elementsKind for builtins
2191         #if ECMASCRIPT_ENABLE_ELEMENTSKIND_ALWAY_GENERIC
2192         auto index = static_cast<size_t>(GlobalEnvField::ELEMENT_HOLE_TAGGED_HCLASS_INDEX);
2193         #else
2194         auto index = static_cast<size_t>(GlobalEnvField::ELEMENT_NONE_HCLASS_INDEX);
2195         #endif
2196         auto hclassVal = env->GetGlobalEnvObjectByIndex(index).GetTaggedValue();
2197         arrFuncInstanceHClass.Update(hclassVal);
2198     }
2199 
2200     JSHandle<JSHClass> arrayFunctionHClass = JSArray::CreateJSArrayFunctionClass(thread_, factory_, env);
2201     // Array = new Function()
2202     JSHandle<JSObject> arrayFunction(
2203         NewBuiltinConstructor(env, arrFuncPrototype, BuiltinsArray::ArrayConstructor, "Array", FunctionLength::ONE,
2204                               BUILTINS_STUB_ID(ArrayConstructor), arrayFunctionHClass));
2205     JSHandle<JSFunction> arrayFuncFunction(arrayFunction);
2206 
2207     JSFunction::SetFunctionPrototypeOrInstanceHClass(thread_, arrayFuncFunction,
2208                                                      arrFuncInstanceHClass.GetTaggedValue());
2209 
2210     // Array.prototype methods (excluding constructor and '@@' internal properties)
2211     for (const base::BuiltinFunctionEntry &entry: BuiltinsArray::GetArrayPrototypeFunctions()) {
2212         SetFunction(env, arrFuncPrototype, entry.GetName(), entry.GetEntrypoint(),
2213                     entry.GetLength(), entry.GetBuiltinStubId());
2214     }
2215 
2216     // %ArrayPrototype% [ @@iterator ]
2217     JSHandle<JSTaggedValue> values(factory_->NewFromASCIIReadOnly("values"));
2218     JSHandle<JSTaggedValue> iteratorSymbol = env->GetIteratorSymbol();
2219     JSHandle<JSTaggedValue> valuesFunc =
2220         JSObject::GetMethod(thread_, JSHandle<JSTaggedValue>::Cast(arrFuncPrototype), values);
2221     RETURN_IF_ABRUPT_COMPLETION(thread_);
2222     PropertyDescriptor iteartorDesc(thread_, valuesFunc, true, false, true);
2223     JSObject::DefineOwnProperty(thread_, arrFuncPrototype, iteratorSymbol, iteartorDesc);
2224 
2225     // Array methods (excluding '@@' internal properties)
2226     for (const base::BuiltinFunctionEntry &entry: BuiltinsArray::GetArrayFunctions()) {
2227         SetFunction(env, arrayFunction, entry.GetName(), entry.GetEntrypoint(),
2228                     entry.GetLength(), entry.GetBuiltinStubId());
2229     }
2230 
2231     // 22.1.2.5 get %Array% [ @@species ]
2232     JSHandle<JSTaggedValue> speciesGetter =
2233         CreateGetter(env, BuiltinsArray::Species, "[Symbol.species]", FunctionLength::ZERO);
2234     JSHandle<AccessorData> speciesAccessor = factory_->NewAccessorData();
2235     speciesAccessor->SetGetter(thread_, speciesGetter);
2236     arrayFunction->SetPropertyInlinedProps(thread_, JSArray::ARRAY_FUNCTION_SPECIES_INDEX,
2237                                            speciesAccessor.GetTaggedValue());
2238     env->SetArraySpeciesAccessor(thread_, speciesAccessor);
2239     constexpr int arrProtoLen = 0;
2240     JSHandle<JSTaggedValue> keyString = thread_->GlobalConstants()->GetHandledLengthString();
2241     PropertyDescriptor descriptor(thread_, JSHandle<JSTaggedValue>(thread_, JSTaggedValue(arrProtoLen)), true, false,
2242                                   false);
2243     JSObject::DefineOwnProperty(thread_, arrFuncPrototype, keyString, descriptor);
2244 
2245     JSHandle<JSTaggedValue> valuesKey(factory_->NewFromASCIIReadOnly("values"));
2246     PropertyDescriptor desc(thread_);
2247     JSObject::GetOwnProperty(thread_, arrFuncPrototype, valuesKey, desc);
2248 
2249     // Array.prototype [ @@unscopables ]
2250     JSHandle<JSTaggedValue> unscopablesSymbol = env->GetUnscopablesSymbol();
2251     JSHandle<JSTaggedValue> unscopables = CreateArrayUnscopables(thread_);
2252     PropertyDescriptor unscopablesDesc(thread_, unscopables, false, false, true);
2253     JSObject::DefineOwnProperty(thread_, arrFuncPrototype, unscopablesSymbol, unscopablesDesc);
2254 
2255     env->SetArrayProtoValuesFunction(thread_, desc.GetValue());
2256     env->SetArrayFunction(thread_, arrayFunction);
2257     env->SetArrayPrototype(thread_, arrFuncPrototype);
2258 
2259     if (!isRealm) {
2260         thread_->SetInitialBuiltinHClass(BuiltinTypeId::ARRAY, arrayFunction->GetJSHClass(),
2261                                          *arrFuncInstanceHClass, arrFuncPrototype->GetJSHClass());
2262     }
2263 }
2264 
InitializeTypedArray(const JSHandle<GlobalEnv> & env,JSHandle<JSTaggedValue> objFuncPrototypeVal) const2265 void Builtins::InitializeTypedArray(const JSHandle<GlobalEnv> &env, JSHandle<JSTaggedValue> objFuncPrototypeVal) const
2266 {
2267     [[maybe_unused]] EcmaHandleScope scope(thread_);
2268     // TypedArray.prototype
2269     JSHandle<JSHClass> typedArrFuncPrototypeHClass = factory_->NewEcmaHClass(
2270         JSObject::SIZE, BuiltinsTypedArray::GetNumPrototypeInlinedProperties(),
2271         JSType::JS_OBJECT, objFuncPrototypeVal);
2272     JSHandle<JSObject> typedArrFuncPrototype = factory_->NewJSObjectWithInit(typedArrFuncPrototypeHClass);
2273     JSHandle<JSTaggedValue> typedArrFuncPrototypeValue(typedArrFuncPrototype);
2274 
2275     // TypedArray.prototype_or_hclass
2276     JSHandle<JSHClass> typedArrFuncInstanceHClass = factory_->NewEcmaHClass(
2277         JSTypedArray::SIZE, JSType::JS_TYPED_ARRAY, typedArrFuncPrototypeValue);
2278 
2279     // TypedArray = new Function()
2280     JSHandle<JSObject> typedArrayFunction(NewBuiltinConstructor(
2281         env, typedArrFuncPrototype, BuiltinsTypedArray::TypedArrayBaseConstructor, "TypedArray", FunctionLength::ZERO));
2282 
2283     JSHandle<JSFunction>(typedArrayFunction)
2284         ->SetProtoOrHClass(thread_, typedArrFuncInstanceHClass.GetTaggedValue());
2285 
2286     // TypedArray.prototype method
2287     for (const base::BuiltinFunctionEntry &entry: BuiltinsTypedArray::GetTypedArrayPrototypeFunctions()) {
2288         SetFunction(env, typedArrFuncPrototype, entry.GetName(), entry.GetEntrypoint(),
2289                     entry.GetLength(), entry.GetBuiltinStubId());
2290     }
2291     // TypedArray.prototype get accessor
2292     for (const base::BuiltinFunctionEntry &entry: BuiltinsTypedArray::GetTypedArrayPrototypeAccessors()) {
2293         JSHandle<JSTaggedValue> getter =
2294             CreateGetter(env, entry.GetEntrypoint(), entry.GetName(), entry.GetLength());
2295         JSHandle<JSTaggedValue> key(factory_->NewFromASCIIReadOnly(entry.GetName()));
2296         SetGetter(typedArrFuncPrototype, key, getter);
2297     }
2298 
2299     // %TypedArray%.prototype.toString(), which is strictly equal to Array.prototype.toString
2300     JSHandle<JSTaggedValue> arrFuncPrototype = env->GetArrayPrototype();
2301     JSHandle<JSTaggedValue> toStringFunc =
2302         JSObject::GetMethod(thread_, arrFuncPrototype, thread_->GlobalConstants()->GetHandledToStringString());
2303     RETURN_IF_ABRUPT_COMPLETION(thread_);
2304     PropertyDescriptor toStringDesc(thread_, toStringFunc, true, false, true);
2305     JSObject::DefineOwnProperty(thread_, typedArrFuncPrototype, thread_->GlobalConstants()->GetHandledToStringString(),
2306                                 toStringDesc);
2307 
2308     // %TypedArray%.prototype [ @@iterator ] ( )
2309     JSHandle<JSTaggedValue> values(factory_->NewFromASCIIReadOnly("values"));
2310     JSHandle<JSTaggedValue> iteratorSymbol = env->GetIteratorSymbol();
2311     JSHandle<JSTaggedValue> valuesFunc =
2312         JSObject::GetMethod(thread_, JSHandle<JSTaggedValue>::Cast(typedArrFuncPrototype), values);
2313     RETURN_IF_ABRUPT_COMPLETION(thread_);
2314     PropertyDescriptor iteartorDesc(thread_, valuesFunc, true, false, true);
2315     JSObject::DefineOwnProperty(thread_, typedArrFuncPrototype, iteratorSymbol, iteartorDesc);
2316 
2317     // 22.2.3.31 get %TypedArray%.prototype [ @@toStringTag ]
2318     JSHandle<JSTaggedValue> toStringTagSymbol = env->GetToStringTagSymbol();
2319     JSHandle<JSTaggedValue> toStringTagGetter =
2320         CreateGetter(env, BuiltinsTypedArray::ToStringTag, "[Symbol.toStringTag]", FunctionLength::ZERO);
2321     SetGetter(typedArrFuncPrototype, toStringTagSymbol, toStringTagGetter);
2322 
2323     // TypedArray method
2324     for (const base::BuiltinFunctionEntry &entry: BuiltinsTypedArray::GetTypedArrayFunctions()) {
2325         SetFunction(env, typedArrayFunction, entry.GetName(), entry.GetEntrypoint(),
2326                     entry.GetLength(), entry.GetBuiltinStubId());
2327     }
2328 
2329     // 22.2.2.4 get %TypedArray% [ @@species ]
2330     JSHandle<JSTaggedValue> speciesSymbol = env->GetSpeciesSymbol();
2331     JSHandle<JSTaggedValue> speciesGetter =
2332         CreateGetter(env, BuiltinsTypedArray::Species, "[Symbol.species]", FunctionLength::ZERO);
2333     SetGetter(JSHandle<JSObject>(typedArrayFunction), speciesSymbol, speciesGetter);
2334 
2335     env->SetTypedArrayFunction(thread_, typedArrayFunction.GetTaggedValue());
2336     env->SetTypedArrayPrototype(thread_, typedArrFuncPrototype);
2337     env->SetTypedArrayProtoValuesFunction(thread_, valuesFunc);
2338     thread_->SetInitialBuiltinHClass(BuiltinTypeId::TYPED_ARRAY,
2339         typedArrayFunction->GetJSHClass(),
2340         *typedArrFuncInstanceHClass,
2341         typedArrFuncPrototype->GetJSHClass());
2342 
2343     JSHandle<JSHClass> specificTypedArrayFuncClass =
2344         factory_->NewEcmaHClass(JSFunction::SIZE, JSType::JS_FUNCTION, env->GetTypedArrayFunction());
2345     specificTypedArrayFuncClass->SetConstructor(true);
2346     env->SetSpecificTypedArrayFunctionClass(thread_, specificTypedArrayFuncClass);
2347 
2348 #define BUILTIN_TYPED_ARRAY_CALL_INITIALIZE(Type, TYPE, bytesPerElement) \
2349     Initialize##Type(env, typedArrFuncInstanceHClass);
2350     BUILTIN_TYPED_ARRAY_TYPES(BUILTIN_TYPED_ARRAY_CALL_INITIALIZE)
2351 #undef BUILTIN_TYPED_ARRAY_CALL_INITIALIZE
2352 }
2353 
LazyInitializeTypedArray(const JSHandle<GlobalEnv> & env) const2354 void Builtins::LazyInitializeTypedArray(const JSHandle<GlobalEnv> &env) const
2355 {
2356     [[maybe_unused]] EcmaHandleScope scope(thread_);
2357     JSHandle<JSObject> globalObject(thread_, env->GetGlobalObject());
2358     JSHandle<JSTaggedValue> key(factory_->NewFromUtf8ReadOnly("TypedArray"));
2359     auto accessor = factory_->NewInternalAccessor(nullptr,
2360         reinterpret_cast<void *>(BuiltinsLazyCallback::TypedArray));
2361     SetLazyAccessor(globalObject, key, accessor);
2362     env->SetTypedArrayFunction(thread_, accessor);
2363     env->SetTypedArrayPrototype(thread_, accessor);
2364     env->SetSpecificTypedArrayFunctionClass(thread_, accessor);
2365 
2366 #define BUILTIN_TYPED_ARRAY_CALL_LAZY_INITIALIZE(Type, TYPE, bytesPerElement) \
2367     LazyInitialize##Type(env);
2368     BUILTIN_TYPED_ARRAY_TYPES(BUILTIN_TYPED_ARRAY_CALL_LAZY_INITIALIZE)
2369 #undef BUILTIN_TYPED_ARRAY_CALL_LAZY_INITIALIZE
2370 }
2371 
2372 #define BUILTIN_TYPED_ARRAY_DEFINE_INITIALIZE(Type, TYPE, bytesPerElement)                                      \
2373 void Builtins::Initialize##Type(const JSHandle<GlobalEnv> &env, const JSHandle<JSHClass> &arrFuncClass) const   \
2374 {                                                                                                               \
2375     [[maybe_unused]] EcmaHandleScope scope(thread_);                                                            \
2376     /* %TypedArray%.prototype (where %TypedArray% is one of Int8Array, Uint8Array, etc.) */                     \
2377     JSHandle<JSObject> arrFuncPrototype = factory_->NewJSObjectWithInit(arrFuncClass);                          \
2378     JSHandle<JSTaggedValue> arrFuncPrototypeValue(arrFuncPrototype);                                            \
2379     /* %TypedArray%.prototype_or_hclass */                                                                      \
2380     JSHandle<JSHClass> arrFuncInstanceHClass = factory_->NewEcmaHClass(                                         \
2381         panda::ecmascript::JSTypedArray::SIZE, JSType::JS_##TYPE, arrFuncPrototypeValue);                       \
2382     JSHandle<JSHClass> arrFuncInstanceHClassOnHeap = factory_->NewEcmaHClass(                                   \
2383         panda::ecmascript::JSTypedArray::SIZE, JSType::JS_##TYPE, arrFuncPrototypeValue);                       \
2384     arrFuncInstanceHClassOnHeap->SetIsOnHeap(true);                                                             \
2385     arrFuncInstanceHClass->SetHasConstructor(false);                                                            \
2386     /* %TypedArray% = new Function() */                                                                         \
2387     JSHandle<JSFunction> arrayFunction = factory_->NewSpecificTypedArrayFunction(                               \
2388         env, reinterpret_cast<void *>(BuiltinsTypedArray::Type##Constructor),                                   \
2389         BUILTINS_STUB_ID(Type##Constructor));                                                                   \
2390     InitializeCtor(env, arrFuncPrototype, arrayFunction, #Type, FunctionLength::THREE);                         \
2391                                                                                                                 \
2392     arrayFunction->SetProtoOrHClass(thread_, arrFuncInstanceHClass.GetTaggedValue());                           \
2393     SetConstant(arrFuncPrototype, "BYTES_PER_ELEMENT", JSTaggedValue(bytesPerElement));                         \
2394     SetConstant(JSHandle<JSObject>(arrayFunction), "BYTES_PER_ELEMENT", JSTaggedValue(bytesPerElement));        \
2395     /* %TypedArray%.protoofprototype (where %TypedArray% is one of Int8Array, Uint8Array, etc.) */              \
2396     JSTaggedValue protoOfPrototypeValue = arrFuncPrototype->GetJSHClass()->GetPrototype(thread_);               \
2397     env->Set##Type##Function(thread_, arrayFunction);                                                           \
2398     env->Set##Type##FunctionPrototype(thread_, arrFuncPrototypeValue);                                          \
2399     env->Set##Type##RootHclass(thread_, arrFuncInstanceHClass);                                                 \
2400     env->Set##Type##RootHclassOnHeap(thread_, arrFuncInstanceHClassOnHeap);                                     \
2401     /* Initializes HClass record of %TypedArray% */                                                             \
2402     thread_->SetInitialBuiltinHClass(BuiltinTypeId::TYPE,                                                       \
2403         arrayFunction->GetJSHClass(),                                                                           \
2404         *arrFuncInstanceHClass,                                                                                 \
2405         arrFuncPrototype->GetJSHClass(),                                                                        \
2406         protoOfPrototypeValue.IsHeapObject() ? protoOfPrototypeValue.GetTaggedObject()->GetClass() : nullptr,   \
2407         *arrFuncInstanceHClassOnHeap);                                                                          \
2408 }
2409 
2410 BUILTIN_TYPED_ARRAY_TYPES(BUILTIN_TYPED_ARRAY_DEFINE_INITIALIZE)
2411 #undef BUILTIN_TYPED_ARRAY_DEFINE_INITIALIZE
2412 
2413 #define BUILTIN_TYPED_ARRAY_DEFINE_LAZY_INITIALIZE(Type, TYPE, bytesPerElement)                                     \
2414 void Builtins::LazyInitialize##Type(const JSHandle<GlobalEnv> &env) const                                           \
2415 {                                                                                                                   \
2416     [[maybe_unused]] EcmaHandleScope scope(thread_);                                                                \
2417     JSHandle<JSObject> globalObject(thread_, env->GetGlobalObject());                                               \
2418     JSHandle<JSTaggedValue> key(factory_->NewFromUtf8ReadOnly(#Type));                                              \
2419     auto accessor = factory_->NewInternalAccessor(nullptr, reinterpret_cast<void *>(BuiltinsLazyCallback::Type));   \
2420     SetLazyAccessor(globalObject, key, accessor);                                                                   \
2421     env->Set##Type##Function(thread_, accessor);                                                                    \
2422     env->Set##Type##FunctionPrototype(thread_, accessor);                                                           \
2423     env->Set##Type##RootHclass(thread_, accessor);                                                                  \
2424     env->Set##Type##RootHclassOnHeap(thread_, accessor);                                                            \
2425 }
2426 
BUILTIN_TYPED_ARRAY_TYPES(BUILTIN_TYPED_ARRAY_DEFINE_LAZY_INITIALIZE)2427 BUILTIN_TYPED_ARRAY_TYPES(BUILTIN_TYPED_ARRAY_DEFINE_LAZY_INITIALIZE)
2428 #undef BUILTIN_TYPED_ARRAY_DEFINE_LAZY_INITIALIZE
2429 
2430 void Builtins::InitializeArrayBuffer(const JSHandle<GlobalEnv> &env, const JSHandle<JSHClass> &objFuncClass) const
2431 {
2432     [[maybe_unused]] EcmaHandleScope scope(thread_);
2433     // ArrayBuffer.prototype
2434     JSHandle<JSObject> arrayBufferFuncPrototype = factory_->NewJSObjectWithInit(objFuncClass);
2435     JSHandle<JSTaggedValue> arrayBufferFuncPrototypeValue(arrayBufferFuncPrototype);
2436 
2437     //  ArrayBuffer.prototype_or_hclass
2438     JSHandle<JSHClass> arrayBufferFuncInstanceHClass =
2439         factory_->NewEcmaHClass(JSArrayBuffer::SIZE, JSType::JS_ARRAY_BUFFER, arrayBufferFuncPrototypeValue);
2440 
2441     // ArrayBuffer = new Function()
2442     JSHandle<JSObject> arrayBufferFunction(NewBuiltinConstructor(
2443         env, arrayBufferFuncPrototype, ArrayBuffer::ArrayBufferConstructor, "ArrayBuffer", FunctionLength::ONE));
2444 
2445     JSFunction::SetFunctionPrototypeOrInstanceHClass(thread_,
2446                                                      JSHandle<JSFunction>(arrayBufferFunction),
2447                                                      arrayBufferFuncInstanceHClass.GetTaggedValue());
2448 
2449     // ArrayBuffer prototype method
2450     SetFunction(env, arrayBufferFuncPrototype, "slice", ArrayBuffer::Slice, FunctionLength::TWO);
2451 
2452     // ArrayBuffer method
2453     for (const base::BuiltinFunctionEntry& entry: ArrayBuffer::GetArrayBufferFunctions()) {
2454         SetFunction(env,
2455                     arrayBufferFunction,
2456                     entry.GetName(),
2457                     entry.GetEntrypoint(),
2458                     entry.GetLength(),
2459                     entry.GetBuiltinStubId());
2460     }
2461 
2462     // 24.1.3.3 get ArrayBuffer[@@species]
2463     JSHandle<JSTaggedValue> speciesSymbol = env->GetSpeciesSymbol();
2464     JSHandle<JSTaggedValue> speciesGetter =
2465         CreateGetter(env, ArrayBuffer::Species, "[Symbol.species]", FunctionLength::ZERO);
2466     SetGetter(JSHandle<JSObject>(arrayBufferFunction), speciesSymbol, speciesGetter);
2467 
2468     // 24.1.4.1 get ArrayBuffer.prototype.byteLength
2469     JSHandle<JSTaggedValue> lengthGetter =
2470         CreateGetter(env, ArrayBuffer::GetByteLength, "byteLength", FunctionLength::ZERO);
2471     JSHandle<JSTaggedValue> lengthKey(factory_->NewFromASCIIReadOnly("byteLength"));
2472     SetGetter(arrayBufferFuncPrototype, lengthKey, lengthGetter);
2473 
2474     // 24.1.4.4 ArrayBuffer.prototype[@@toStringTag]
2475     SetStringTagSymbol(env, arrayBufferFuncPrototype, "ArrayBuffer");
2476 
2477     env->SetArrayBufferFunction(thread_, arrayBufferFunction.GetTaggedValue());
2478 }
2479 
LazyInitializeArrayBuffer(const JSHandle<GlobalEnv> & env) const2480 void Builtins::LazyInitializeArrayBuffer(const JSHandle<GlobalEnv> &env) const
2481 {
2482     [[maybe_unused]] EcmaHandleScope scope(thread_);
2483     JSHandle<JSObject> globalObject(thread_, env->GetGlobalObject());
2484     JSHandle<JSTaggedValue> key(factory_->NewFromUtf8ReadOnly("ArrayBuffer"));
2485     auto accessor = factory_->NewInternalAccessor(nullptr,
2486         reinterpret_cast<void *>(BuiltinsLazyCallback::ArrayBuffer));
2487     SetLazyAccessor(globalObject, key, accessor);
2488     env->SetArrayBufferFunction(thread_, accessor);
2489 }
2490 
InitializeReflect(const JSHandle<GlobalEnv> & env,const JSHandle<JSTaggedValue> & objFuncPrototypeVal) const2491 void Builtins::InitializeReflect(const JSHandle<GlobalEnv> &env,
2492                                  const JSHandle<JSTaggedValue> &objFuncPrototypeVal) const
2493 {
2494     [[maybe_unused]] EcmaHandleScope scope(thread_);
2495     JSHandle<JSHClass> reflectHClass =
2496         factory_->NewEcmaHClass(JSObject::SIZE, JSType::JS_OBJECT, objFuncPrototypeVal);
2497     JSHandle<JSObject> reflectObject = factory_->NewJSObjectWithInit(reflectHClass);
2498 
2499     // Reflect functions
2500     for (const base::BuiltinFunctionEntry &entry: Reflect::GetReflectFunctions()) {
2501         SetFunction(env, reflectObject, entry.GetName(), entry.GetEntrypoint(),
2502                     entry.GetLength(), entry.GetBuiltinStubId());
2503     }
2504 
2505     JSHandle<JSTaggedValue> reflectString(factory_->NewFromASCIIReadOnly("Reflect"));
2506     JSHandle<JSObject> globalObject(thread_, env->GetGlobalObject());
2507     PropertyDescriptor reflectDesc(thread_, JSHandle<JSTaggedValue>::Cast(reflectObject), true, false, true);
2508     JSObject::DefineOwnProperty(thread_, globalObject, reflectString, reflectDesc);
2509 
2510     // @@ToStringTag
2511     SetStringTagSymbol(env, reflectObject, "Reflect");
2512 
2513     env->SetReflectFunction(thread_, reflectObject.GetTaggedValue());
2514 }
2515 
InitializeSharedArrayBuffer(const JSHandle<GlobalEnv> & env,const JSHandle<JSHClass> & objFuncClass) const2516 void Builtins::InitializeSharedArrayBuffer(const JSHandle<GlobalEnv> &env,
2517                                            const JSHandle<JSHClass> &objFuncClass) const
2518 {
2519     [[maybe_unused]] EcmaHandleScope scope(thread_);
2520     // SharedArrayBuffer.prototype
2521     JSHandle<JSObject> sharedArrayBufferFuncPrototype = factory_->NewJSObjectWithInit(objFuncClass);
2522     JSHandle<JSTaggedValue> sharedArrayBufferFuncPrototypeValue(sharedArrayBufferFuncPrototype);
2523 
2524     //  SharedArrayBuffer.prototype_or_hclass
2525     JSHandle<JSHClass> sharedArrayBufferFuncInstanceHClass =
2526         factory_->NewEcmaHClass(
2527             JSArrayBuffer::SIZE, JSType::JS_SHARED_ARRAY_BUFFER, sharedArrayBufferFuncPrototypeValue);
2528 
2529     // SharedArrayBuffer = new Function()
2530     JSHandle<JSObject> SharedArrayBufferFunction(NewBuiltinConstructor(env, sharedArrayBufferFuncPrototype,
2531         SharedArrayBuffer::SharedArrayBufferConstructor, "SharedArrayBuffer", FunctionLength::ONE));
2532 
2533     JSFunction::SetFunctionPrototypeOrInstanceHClass(thread_,
2534                                                      JSHandle<JSFunction>(SharedArrayBufferFunction),
2535                                                      sharedArrayBufferFuncInstanceHClass.GetTaggedValue());
2536 
2537     // SharedArrayBuffer prototype method
2538     SetFunction(env, sharedArrayBufferFuncPrototype, "slice", SharedArrayBuffer::Slice, FunctionLength::TWO);
2539 
2540     // SharedArrayBuffer method
2541     SetFunction(env, SharedArrayBufferFunction,
2542                 "IsSharedArrayBuffer", SharedArrayBuffer::IsSharedArrayBuffer, FunctionLength::ONE);
2543 
2544     // 25.2.3.2 get SharedArrayBuffer [ @@species ]
2545     JSHandle<JSTaggedValue> speciesSymbol = env->GetSpeciesSymbol();
2546     JSHandle<JSTaggedValue> speciesGetter =
2547         CreateGetter(env, SharedArrayBuffer::Species, "[Symbol.species]", FunctionLength::ZERO);
2548     SetGetter(JSHandle<JSObject>(SharedArrayBufferFunction), speciesSymbol, speciesGetter);
2549 
2550     // 25.2.4.1 get SharedArrayBuffer.prototype.byteLength
2551     JSHandle<JSTaggedValue> lengthGetter =
2552         CreateGetter(env, SharedArrayBuffer::GetByteLength, "byteLength", FunctionLength::ZERO);
2553     JSHandle<JSTaggedValue> lengthKey(factory_->NewFromASCIIReadOnly("byteLength"));
2554     SetGetter(sharedArrayBufferFuncPrototype, lengthKey, lengthGetter);
2555 
2556     // 25.2.4.4 SharedArrayBuffer.prototype [ @@toStringTag ]
2557     SetStringTagSymbol(env, sharedArrayBufferFuncPrototype, "SharedArrayBuffer");
2558 
2559     env->SetSharedArrayBufferFunction(thread_, SharedArrayBufferFunction.GetTaggedValue());
2560 }
2561 
LazyInitializeSharedArrayBuffer(const JSHandle<GlobalEnv> & env) const2562 void Builtins::LazyInitializeSharedArrayBuffer(const JSHandle<GlobalEnv> &env) const
2563 {
2564     [[maybe_unused]] EcmaHandleScope scope(thread_);
2565     JSHandle<JSObject> globalObject(thread_, env->GetGlobalObject());
2566     JSHandle<JSTaggedValue> key(factory_->NewFromUtf8ReadOnly("SharedArrayBuffer"));
2567     auto accessor =
2568         factory_->NewInternalAccessor(nullptr, reinterpret_cast<void *>(BuiltinsLazyCallback::SharedArrayBuffer));
2569     SetLazyAccessor(globalObject, key, accessor);
2570     env->SetSharedArrayBufferFunction(thread_, accessor);
2571 }
2572 
InitializePromise(const JSHandle<GlobalEnv> & env,const JSHandle<JSHClass> & promiseFuncClass)2573 void Builtins::InitializePromise(const JSHandle<GlobalEnv> &env, const JSHandle<JSHClass> &promiseFuncClass)
2574 {
2575     [[maybe_unused]] EcmaHandleScope scope(thread_);
2576     // Promise.prototype
2577     JSHandle<JSObject> promiseFuncPrototype = factory_->NewJSObjectWithInit(promiseFuncClass);
2578     JSHandle<JSTaggedValue> promiseFuncPrototypeValue(promiseFuncPrototype);
2579     // Promise.prototype_or_hclass
2580     JSHandle<JSHClass> promiseFuncInstanceHClass =
2581         factory_->NewEcmaHClass(JSPromise::SIZE, JSType::JS_PROMISE, promiseFuncPrototypeValue);
2582     // Promise() = new Function()
2583     JSHandle<JSObject> promiseFunction(
2584         NewBuiltinConstructor(env, promiseFuncPrototype, Promise::PromiseConstructor, "Promise", FunctionLength::ONE));
2585     JSFunction::SetFunctionPrototypeOrInstanceHClass(thread_,
2586                                                      JSHandle<JSFunction>(promiseFunction),
2587                                                      promiseFuncInstanceHClass.GetTaggedValue());
2588 
2589     // Promise method
2590     for (const base::BuiltinFunctionEntry &entry: Promise::GetPromiseFunctions()) {
2591         SetFunction(env, promiseFunction, entry.GetName(), entry.GetEntrypoint(),
2592                     entry.GetLength(), entry.GetBuiltinStubId());
2593     }
2594     // promise.prototype method
2595     for (const base::BuiltinFunctionEntry &entry: Promise::GetPromisePrototypeFunctions()) {
2596         SetFunction(env, promiseFuncPrototype, entry.GetName(), entry.GetEntrypoint(),
2597                     entry.GetLength(), entry.GetBuiltinStubId());
2598     }
2599     // Promise.prototype [ @@toStringTag ]
2600     SetStringTagSymbol(env, promiseFuncPrototype, "Promise");
2601 
2602     // Set Promise [@@species]
2603     JSHandle<JSTaggedValue> speciesSymbol(env->GetSpeciesSymbol());
2604     JSHandle<JSTaggedValue> speciesGetter =
2605         CreateGetter(env, Promise::GetSpecies, "[Symbol.species]", FunctionLength::ZERO);
2606     SetGetter(promiseFunction, speciesSymbol, speciesGetter);
2607 
2608     env->SetPromiseFunction(thread_, promiseFunction);
2609     InitializeForPromiseFuncClass(env);
2610 }
2611 
2612 
InitializeForPromiseFuncClass(const JSHandle<GlobalEnv> & env)2613 void Builtins::InitializeForPromiseFuncClass(const JSHandle<GlobalEnv> &env)
2614 {
2615     vm_ = thread_->GetEcmaVM();
2616     factory_ = vm_->GetFactory();
2617 
2618     JSHandle<JSHClass> promiseReactionFuncClass = factory_->NewEcmaHClass(
2619         JSPromiseReactionsFunction::SIZE, JSType::JS_PROMISE_REACTIONS_FUNCTION, env->GetFunctionPrototype());
2620     promiseReactionFuncClass->SetCallable(true);
2621     promiseReactionFuncClass->SetExtensible(true);
2622     env->SetPromiseReactionFunctionClass(thread_, promiseReactionFuncClass);
2623 
2624     JSHandle<JSHClass> promiseExecutorFuncClass = factory_->NewEcmaHClass(
2625         JSPromiseExecutorFunction::SIZE, JSType::JS_PROMISE_EXECUTOR_FUNCTION, env->GetFunctionPrototype());
2626     promiseExecutorFuncClass->SetCallable(true);
2627     promiseExecutorFuncClass->SetExtensible(true);
2628     env->SetPromiseExecutorFunctionClass(thread_, promiseExecutorFuncClass);
2629 
2630     JSHandle<JSHClass> asyncModuleFulfilledFuncClass = factory_->NewEcmaHClass(
2631         JSAsyncModuleFulfilledFunction::SIZE, JSType::JS_ASYNC_MODULE_FULFILLED_FUNCTION, env->GetFunctionPrototype());
2632     asyncModuleFulfilledFuncClass->SetCallable(true);
2633     asyncModuleFulfilledFuncClass->SetExtensible(true);
2634     env->SetAsyncModuleFulfilledFunctionClass(thread_, asyncModuleFulfilledFuncClass);
2635 
2636     JSHandle<JSHClass> asyncModuleRejectedFuncClass = factory_->NewEcmaHClass(
2637         JSAsyncModuleRejectedFunction::SIZE, JSType::JS_ASYNC_MODULE_REJECTED_FUNCTION, env->GetFunctionPrototype());
2638     asyncModuleRejectedFuncClass->SetCallable(true);
2639     asyncModuleRejectedFuncClass->SetExtensible(true);
2640     env->SetAsyncModuleRejectedFunctionClass(thread_, asyncModuleRejectedFuncClass);
2641 
2642     JSHandle<JSHClass> promiseAllResolveElementFunctionClass =
2643         factory_->NewEcmaHClass(JSPromiseAllResolveElementFunction::SIZE,
2644                                 JSType::JS_PROMISE_ALL_RESOLVE_ELEMENT_FUNCTION, env->GetFunctionPrototype());
2645     promiseAllResolveElementFunctionClass->SetCallable(true);
2646     promiseAllResolveElementFunctionClass->SetExtensible(true);
2647     env->SetPromiseAllResolveElementFunctionClass(thread_, promiseAllResolveElementFunctionClass);
2648 
2649     JSHandle<JSHClass> promiseAnyRejectElementFunctionClass =
2650         factory_->NewEcmaHClass(JSPromiseAnyRejectElementFunction::SIZE,
2651                                 JSType::JS_PROMISE_ANY_REJECT_ELEMENT_FUNCTION, env->GetFunctionPrototype());
2652     promiseAnyRejectElementFunctionClass->SetCallable(true);
2653     promiseAnyRejectElementFunctionClass->SetExtensible(true);
2654     env->SetPromiseAnyRejectElementFunctionClass(thread_, promiseAnyRejectElementFunctionClass);
2655 
2656     JSHandle<JSHClass> promiseAllSettledElementFunctionClass =
2657         factory_->NewEcmaHClass(JSPromiseAllSettledElementFunction::SIZE,
2658                                 JSType::JS_PROMISE_ALL_SETTLED_ELEMENT_FUNCTION, env->GetFunctionPrototype());
2659     promiseAllSettledElementFunctionClass->SetCallable(true);
2660     promiseAllSettledElementFunctionClass->SetExtensible(true);
2661     env->SetPromiseAllSettledElementFunctionClass(thread_, promiseAllSettledElementFunctionClass);
2662 
2663     JSHandle<JSHClass> promiseFinallyFunctionClass =
2664         factory_->NewEcmaHClass(JSPromiseFinallyFunction::SIZE,
2665                                 JSType::JS_PROMISE_FINALLY_FUNCTION, env->GetFunctionPrototype());
2666     promiseFinallyFunctionClass->SetCallable(true);
2667     promiseFinallyFunctionClass->SetExtensible(true);
2668     env->SetPromiseFinallyFunctionClass(thread_, promiseFinallyFunctionClass);
2669 
2670     JSHandle<JSHClass> promiseValueThunkOrThrowerFunctionClass =
2671         factory_->NewEcmaHClass(JSPromiseValueThunkOrThrowerFunction::SIZE,
2672                                 JSType::JS_PROMISE_VALUE_THUNK_OR_THROWER_FUNCTION, env->GetFunctionPrototype());
2673     promiseValueThunkOrThrowerFunctionClass->SetCallable(true);
2674     promiseValueThunkOrThrowerFunctionClass->SetExtensible(true);
2675     env->SetPromiseValueThunkOrThrowerFunctionClass(thread_, promiseValueThunkOrThrowerFunctionClass);
2676 }
2677 
InitializePromiseJob(const JSHandle<GlobalEnv> & env)2678 void Builtins::InitializePromiseJob(const JSHandle<GlobalEnv> &env)
2679 {
2680     JSHandle<JSTaggedValue> keyString(thread_->GlobalConstants()->GetHandledEmptyString());
2681     auto func = NewFunction(env, keyString, BuiltinsPromiseJob::PromiseReactionJob, FunctionLength::TWO);
2682     env->SetPromiseReactionJob(thread_, func);
2683     func = NewFunction(env, keyString, BuiltinsPromiseJob::PromiseResolveThenableJob, FunctionLength::THREE);
2684     env->SetPromiseResolveThenableJob(thread_, func);
2685     func = NewFunction(env, keyString, BuiltinsPromiseJob::DynamicImportJob, FunctionLength::FOUR);
2686     env->SetDynamicImportJob(thread_, func);
2687 }
2688 
InitializeDataView(const JSHandle<GlobalEnv> & env,JSHandle<JSTaggedValue> objFuncPrototypeVal) const2689 void Builtins::InitializeDataView(const JSHandle<GlobalEnv> &env, JSHandle<JSTaggedValue> objFuncPrototypeVal) const
2690 {
2691     [[maybe_unused]] EcmaHandleScope scope(thread_);
2692     // DataView.prototype
2693     JSHandle<JSHClass> dataViewFuncPrototypeHClass = factory_->NewEcmaHClass(
2694         JSObject::SIZE, DataView::GetNumPrototypeInlinedProperties(), JSType::JS_OBJECT, objFuncPrototypeVal);
2695     JSHandle<JSObject> dataViewFuncPrototype = factory_->NewJSObjectWithInit(dataViewFuncPrototypeHClass);
2696     JSHandle<JSTaggedValue> dataViewFuncPrototypeValue(dataViewFuncPrototype);
2697 
2698     //  DataView.prototype_or_hclass
2699     JSHandle<JSHClass> dataViewFuncInstanceHClass =
2700         factory_->NewEcmaHClass(JSDataView::SIZE, JSType::JS_DATA_VIEW, dataViewFuncPrototypeValue);
2701 
2702     // DataView = new Function()
2703     JSHandle<JSObject> dataViewFunction(NewBuiltinConstructor(env, dataViewFuncPrototype, DataView::DataViewConstructor,
2704                                                               "DataView", FunctionLength::ONE));
2705 
2706     JSHandle<JSFunction>(dataViewFunction)->SetProtoOrHClass(thread_, dataViewFuncInstanceHClass.GetTaggedValue());
2707     // DataView.prototype method
2708     for (const base::BuiltinFunctionEntry &entry: DataView::GetDataViewPrototypeFunctions()) {
2709         SetFunction(env,  dataViewFuncPrototype, entry.GetName(), entry.GetEntrypoint(),
2710                     entry.GetLength(), entry.GetBuiltinStubId());
2711     }
2712 
2713     // 24.2.4.1 get DataView.prototype.buffer
2714     JSHandle<JSTaggedValue> bufferGetter = CreateGetter(env, DataView::GetBuffer, "buffer", FunctionLength::ZERO);
2715     JSHandle<JSTaggedValue> bufferKey(factory_->NewFromASCIIReadOnly("buffer"));
2716     SetGetter(dataViewFuncPrototype, bufferKey, bufferGetter);
2717 
2718     // 24.2.4.2 get DataView.prototype.byteLength
2719     JSHandle<JSTaggedValue> lengthGetter =
2720         CreateGetter(env, DataView::GetByteLength, "byteLength", FunctionLength::ZERO);
2721     JSHandle<JSTaggedValue> lengthKey(factory_->NewFromASCIIReadOnly("byteLength"));
2722     SetGetter(dataViewFuncPrototype, lengthKey, lengthGetter);
2723 
2724     // 24.2.4.3 get DataView.prototype.byteOffset
2725     JSHandle<JSTaggedValue> offsetGetter = CreateGetter(env, DataView::GetOffset, "byteOffset", FunctionLength::ZERO);
2726     JSHandle<JSTaggedValue> offsetKey(factory_->NewFromASCIIReadOnly("byteOffset"));
2727     SetGetter(dataViewFuncPrototype, offsetKey, offsetGetter);
2728 
2729     // 24.2.4.21 DataView.prototype[ @@toStringTag ]
2730     SetStringTagSymbol(env, dataViewFuncPrototype, "DataView");
2731 
2732     env->SetDataViewFunction(thread_, dataViewFunction.GetTaggedValue());
2733     env->SetDataViewPrototype(thread_, dataViewFuncPrototype.GetTaggedValue());
2734     thread_->SetInitialBuiltinHClass(BuiltinTypeId::DATA_VIEW,
2735         dataViewFunction->GetJSHClass(),
2736         *dataViewFuncInstanceHClass,
2737         dataViewFuncPrototype->GetJSHClass());
2738 }
2739 
LazyInitializeDataView(const JSHandle<GlobalEnv> & env) const2740 void Builtins::LazyInitializeDataView(const JSHandle<GlobalEnv> &env) const
2741 {
2742     [[maybe_unused]] EcmaHandleScope scope(thread_);
2743     JSHandle<JSObject> globalObject(thread_, env->GetGlobalObject());
2744     JSHandle<JSTaggedValue> key(factory_->NewFromUtf8ReadOnly("DataView"));
2745     auto accessor = factory_->NewInternalAccessor(nullptr, reinterpret_cast<void *>(BuiltinsLazyCallback::DataView));
2746     SetLazyAccessor(globalObject, key, accessor);
2747     env->SetDataViewFunction(thread_, accessor);
2748     env->SetDataViewPrototype(thread_, accessor);
2749 }
2750 
NewBuiltinConstructor(const JSHandle<GlobalEnv> & env,const JSHandle<JSObject> & prototype,EcmaEntrypoint ctorFunc,std::string_view name,int length,kungfu::BuiltinsStubCSigns::ID builtinId,JSHandle<JSHClass> hclass) const2751 JSHandle<JSFunction> Builtins::NewBuiltinConstructor(const JSHandle<GlobalEnv> &env,
2752                                                      const JSHandle<JSObject> &prototype, EcmaEntrypoint ctorFunc,
2753                                                      std::string_view name, int length,
2754                                                      kungfu::BuiltinsStubCSigns::ID builtinId,
2755                                                      JSHandle<JSHClass> hclass) const
2756 {
2757     JSHandle<Method> target = factory_->NewMethodForNativeFunction(reinterpret_cast<void *>(ctorFunc),
2758                                                                    FunctionKind::BUILTIN_CONSTRUCTOR, builtinId);
2759     JSHandle<JSFunction> ctor;
2760     if (!hclass.IsEmpty()) {
2761         ctor = factory_->NewJSBuiltinFunctionByHClass(env, target, hclass);
2762     } else {
2763         ctor = factory_->NewJSBuiltinFunction(env, target);
2764     }
2765     InitializeCtor(env, prototype, ctor, name, length);
2766     return ctor;
2767 }
2768 
NewBuiltinCjsCtor(const JSHandle<GlobalEnv> & env,const JSHandle<JSObject> & prototype,EcmaEntrypoint ctorFunc,std::string_view name,int length) const2769 JSHandle<JSFunction> Builtins::NewBuiltinCjsCtor(const JSHandle<GlobalEnv> &env,
2770                                                  const JSHandle<JSObject> &prototype, EcmaEntrypoint ctorFunc,
2771                                                  std::string_view name, int length) const
2772 {
2773     JSHandle<JSFunction> ctor =
2774         factory_->NewJSBuiltinFunction(env, reinterpret_cast<void *>(ctorFunc), FunctionKind::BUILTIN_CONSTRUCTOR);
2775 
2776     const GlobalEnvConstants *globalConst = thread_->GlobalConstants();
2777     JSFunction::SetFunctionLength(thread_, ctor, JSTaggedValue(length));
2778     JSHandle<JSTaggedValue> nameString(factory_->NewFromUtf8ReadOnly(name));
2779     JSFunction::SetFunctionName(thread_, JSHandle<JSFunctionBase>(ctor), nameString,
2780                                 JSHandle<JSTaggedValue>(thread_, JSTaggedValue::Undefined()));
2781     JSHandle<JSTaggedValue> constructorKey = globalConst->GetHandledConstructorString();
2782     PropertyDescriptor descriptor(thread_, JSHandle<JSTaggedValue>::Cast(ctor), true, false, true);
2783     JSObject::DefineOwnProperty(thread_, prototype, constructorKey, descriptor);
2784 
2785     return ctor;
2786 }
2787 
RegisterBuiltinToGlobalEnv(const JSHandle<GlobalEnv> & env,kungfu::BuiltinsStubCSigns::ID builtinId,JSHandle<JSFunction> function) const2788 void Builtins::RegisterBuiltinToGlobalEnv(const JSHandle<GlobalEnv> &env, kungfu::BuiltinsStubCSigns::ID builtinId,
2789                                           JSHandle<JSFunction> function) const
2790 {
2791     if (IS_TYPED_BUILTINS_ID(builtinId) || IS_TYPED_INLINE_BUILTINS_ID(builtinId)) {
2792         env->SetBuiltinFunction(thread_, builtinId, function);
2793     }
2794 }
2795 
NewFunction(const JSHandle<GlobalEnv> & env,const JSHandle<JSTaggedValue> & key,EcmaEntrypoint func,int length,kungfu::BuiltinsStubCSigns::ID builtinId) const2796 JSHandle<JSFunction> Builtins::NewFunction(const JSHandle<GlobalEnv> &env, const JSHandle<JSTaggedValue> &key,
2797                                            EcmaEntrypoint func, int length,
2798                                            kungfu::BuiltinsStubCSigns::ID builtinId) const
2799 {
2800     MemSpaceType methodSpaceType = MemSpaceType::SHARED_NON_MOVABLE;
2801     JSHandle<JSFunction> function = factory_->NewJSBuiltinFunction(env, reinterpret_cast<void *>(func),
2802         FunctionKind::NORMAL_FUNCTION, builtinId, methodSpaceType);
2803     JSFunction::SetFunctionLength(thread_, function, JSTaggedValue(length));
2804     JSHandle<JSFunctionBase> baseFunction(function);
2805     auto globalConst = const_cast<GlobalEnvConstants *>(thread_->GlobalConstants());
2806     JSFunction::SetFunctionName(thread_, baseFunction, key, globalConst->GetHandledUndefined());
2807     RegisterBuiltinToGlobalEnv(env, builtinId, function);
2808     return function;
2809 }
2810 
SetFunction(const JSHandle<GlobalEnv> & env,const JSHandle<JSObject> & obj,std::string_view key,EcmaEntrypoint func,int length,kungfu::BuiltinsStubCSigns::ID builtinId) const2811 void Builtins::SetFunction(const JSHandle<GlobalEnv> &env, const JSHandle<JSObject> &obj, std::string_view key,
2812                            EcmaEntrypoint func, int length, kungfu::BuiltinsStubCSigns::ID builtinId) const
2813 {
2814     JSHandle<JSTaggedValue> keyString(factory_->NewFromUtf8ReadOnly(key));
2815     SetFunction(env, obj, keyString, func, length, builtinId);
2816 }
2817 
SetFunction(const JSHandle<GlobalEnv> & env,const JSHandle<JSObject> & obj,const JSHandle<JSTaggedValue> & key,EcmaEntrypoint func,int length,kungfu::BuiltinsStubCSigns::ID builtinId) const2818 void Builtins::SetFunction(const JSHandle<GlobalEnv> &env, const JSHandle<JSObject> &obj,
2819                            const JSHandle<JSTaggedValue> &key, EcmaEntrypoint func, int length,
2820                            kungfu::BuiltinsStubCSigns::ID builtinId) const
2821 {
2822     JSHandle<JSFunction> function(NewFunction(env, key, func, length, builtinId));
2823     PropertyDescriptor descriptor(thread_, JSHandle<JSTaggedValue>(function), true, false, true);
2824     JSObject::DefineOwnProperty(thread_, obj, key, descriptor);
2825 }
2826 
SetAndReturnFunction(const JSHandle<GlobalEnv> & env,const JSHandle<JSObject> & obj,const char * key,EcmaEntrypoint func,int length,kungfu::BuiltinsStubCSigns::ID builtinId) const2827 JSHandle<JSFunction> Builtins::SetAndReturnFunction(const JSHandle<GlobalEnv> &env, const JSHandle<JSObject> &obj,
2828                                                     const char *key, EcmaEntrypoint func, int length,
2829                                                     kungfu::BuiltinsStubCSigns::ID builtinId) const
2830 {
2831     JSHandle<JSTaggedValue> keyString(factory_->NewFromUtf8ReadOnly(key));
2832     return SetAndReturnFunction(env, obj, keyString, func, length, builtinId);
2833 }
2834 
SetAndReturnFunction(const JSHandle<GlobalEnv> & env,const JSHandle<JSObject> & obj,const JSHandle<JSTaggedValue> & key,EcmaEntrypoint func,int length,kungfu::BuiltinsStubCSigns::ID builtinId) const2835 JSHandle<JSFunction> Builtins::SetAndReturnFunction(const JSHandle<GlobalEnv> &env, const JSHandle<JSObject> &obj,
2836                                                     const JSHandle<JSTaggedValue> &key, EcmaEntrypoint func, int length,
2837                                                     kungfu::BuiltinsStubCSigns::ID builtinId) const
2838 {
2839     JSHandle<JSFunction> function(NewFunction(env, key, func, length, builtinId));
2840     PropertyDescriptor descriptor(thread_, JSHandle<JSTaggedValue>(function), true, false, true);
2841     JSObject::DefineOwnProperty(thread_, obj, key, descriptor);
2842     return function;
2843 }
2844 
SetFrozenFunction(const JSHandle<GlobalEnv> & env,const JSHandle<JSObject> & obj,std::string_view key,EcmaEntrypoint func,int length) const2845 void Builtins::SetFrozenFunction(const JSHandle<GlobalEnv> &env, const JSHandle<JSObject> &obj, std::string_view key,
2846                                  EcmaEntrypoint func, int length) const
2847 {
2848     JSHandle<JSTaggedValue> keyString(factory_->NewFromUtf8ReadOnly(key));
2849     JSHandle<JSFunction> function = NewFunction(env, keyString, func, length);
2850     PropertyDescriptor descriptor(thread_, JSHandle<JSTaggedValue>(function), false, false, false);
2851     JSObject::DefineOwnProperty(thread_, obj, keyString, descriptor);
2852 }
2853 
2854 template<int flag>
SetFunctionAtSymbol(const JSHandle<GlobalEnv> & env,const JSHandle<JSObject> & obj,const JSHandle<JSTaggedValue> & symbol,std::string_view name,EcmaEntrypoint func,int length) const2855 void Builtins::SetFunctionAtSymbol(const JSHandle<GlobalEnv> &env, const JSHandle<JSObject> &obj,
2856                                    const JSHandle<JSTaggedValue> &symbol, std::string_view name,
2857                                    EcmaEntrypoint func, int length) const
2858 {
2859     JSHandle<JSFunction> function = factory_->NewJSBuiltinFunction(env, reinterpret_cast<void *>(func));
2860     JSFunction::SetFunctionLength(thread_, function, JSTaggedValue(length));
2861     JSHandle<JSTaggedValue> nameString(factory_->NewFromUtf8ReadOnly(name));
2862     JSHandle<JSFunctionBase> baseFunction(function);
2863     JSHandle<JSTaggedValue> handleUndefine(thread_, JSTaggedValue::Undefined());
2864     JSFunction::SetFunctionName(thread_, baseFunction, nameString, handleUndefine);
2865     // NOLINTNEXTLINE(readability-braces-around-statements, bugprone-suspicious-semicolon)
2866     if constexpr (flag == JSSymbol::SYMBOL_TO_PRIMITIVE_TYPE) {
2867         PropertyDescriptor descriptor(thread_, JSHandle<JSTaggedValue>::Cast(function), false, false, true);
2868         JSObject::DefineOwnProperty(thread_, obj, symbol, descriptor);
2869         return;
2870     } else if constexpr (flag == JSSymbol::SYMBOL_HAS_INSTANCE_TYPE) {  // NOLINTE(readability-braces-around-statements)
2871         // ecma 19.2.3.6 Function.prototype[@@hasInstance] has the attributes
2872         // { [[Writable]]: false, [[Enumerable]]: false, [[Configurable]]: false }.
2873         PropertyDescriptor descriptor(thread_, JSHandle<JSTaggedValue>::Cast(function), false, false, false);
2874         JSObject::DefineOwnProperty(thread_, obj, symbol, descriptor);
2875         env->SetHasInstanceFunction(thread_, function);
2876         return;
2877     }
2878     PropertyDescriptor descriptor(thread_, JSHandle<JSTaggedValue>::Cast(function), true, false, true);
2879     JSObject::DefineOwnProperty(thread_, obj, symbol, descriptor);
2880 }
2881 
2882 template<int flag>
SetAndReturnFunctionAtSymbol(const JSHandle<GlobalEnv> & env,const JSHandle<JSObject> & obj,const JSHandle<JSTaggedValue> & symbol,std::string_view name,EcmaEntrypoint func,int length,kungfu::BuiltinsStubCSigns::ID builtinId) const2883 JSHandle<JSTaggedValue> Builtins::SetAndReturnFunctionAtSymbol(const JSHandle<GlobalEnv> &env,
2884                                                                const JSHandle<JSObject> &obj,
2885                                                                const JSHandle<JSTaggedValue> &symbol,
2886                                                                std::string_view name,
2887                                                                EcmaEntrypoint func,
2888                                                                int length,
2889                                                                kungfu::BuiltinsStubCSigns::ID builtinId) const
2890 {
2891     JSHandle<JSFunction> function = factory_->NewJSBuiltinFunction(env, reinterpret_cast<void *>(func),
2892         FunctionKind::NORMAL_FUNCTION, builtinId);
2893     JSFunction::SetFunctionLength(thread_, function, JSTaggedValue(length));
2894     JSHandle<JSTaggedValue> nameString(factory_->NewFromUtf8ReadOnly(name));
2895     JSHandle<JSFunctionBase> baseFunction(function);
2896     JSHandle<JSTaggedValue> handleUndefine(thread_, JSTaggedValue::Undefined());
2897     JSFunction::SetFunctionName(thread_, baseFunction, nameString, handleUndefine);
2898     RegisterBuiltinToGlobalEnv(env, builtinId, function);
2899     // NOLINTNEXTLINE(readability-braces-around-statements, bugprone-suspicious-semicolon)
2900     if constexpr (flag == JSSymbol::SYMBOL_TO_PRIMITIVE_TYPE) {
2901         PropertyDescriptor descriptor(thread_, JSHandle<JSTaggedValue>::Cast(function), false, false, true);
2902         JSObject::DefineOwnProperty(thread_, obj, symbol, descriptor);
2903         return JSHandle<JSTaggedValue>(function);
2904     } else if constexpr (flag == JSSymbol::SYMBOL_HAS_INSTANCE_TYPE) {  // NOLINTE(readability-braces-around-statements)
2905         // ecma 19.2.3.6 Function.prototype[@@hasInstance] has the attributes
2906         // { [[Writable]]: false, [[Enumerable]]: false, [[Configurable]]: false }.
2907         PropertyDescriptor descriptor(thread_, JSHandle<JSTaggedValue>::Cast(function), false, false, false);
2908         JSObject::DefineOwnProperty(thread_, obj, symbol, descriptor);
2909         env->SetHasInstanceFunction(thread_, function);
2910         return JSHandle<JSTaggedValue>(function);
2911     }
2912     PropertyDescriptor descriptor(thread_, JSHandle<JSTaggedValue>::Cast(function), true, false, true);
2913     JSObject::DefineOwnProperty(thread_, obj, symbol, descriptor);
2914     return JSHandle<JSTaggedValue>(function);
2915 }
2916 
SetStringTagSymbol(const JSHandle<GlobalEnv> & env,const JSHandle<JSObject> & obj,std::string_view key) const2917 void Builtins::SetStringTagSymbol(const JSHandle<GlobalEnv> &env, const JSHandle<JSObject> &obj,
2918                                   std::string_view key) const
2919 {
2920     JSHandle<JSTaggedValue> tag(factory_->NewFromUtf8ReadOnly(key));
2921     JSHandle<JSTaggedValue> symbol = env->GetToStringTagSymbol();
2922     PropertyDescriptor desc(thread_, tag, false, false, true);
2923     JSObject::DefineOwnProperty(thread_, obj, symbol, desc);
2924 }
2925 
CreateGetter(const JSHandle<GlobalEnv> & env,EcmaEntrypoint func,std::string_view name,int length,kungfu::BuiltinsStubCSigns::ID builtinId) const2926 JSHandle<JSTaggedValue> Builtins::CreateGetter(const JSHandle<GlobalEnv> &env, EcmaEntrypoint func,
2927                                                std::string_view name, int length,
2928                                                kungfu::BuiltinsStubCSigns::ID builtinId) const
2929 {
2930     JSHandle<JSTaggedValue> funcName(factory_->NewFromUtf8ReadOnly(name));
2931     return CreateGetter(env, func, funcName, length, builtinId);
2932 }
2933 
CreateGetter(const JSHandle<GlobalEnv> & env,EcmaEntrypoint func,JSHandle<JSTaggedValue> key,int length,kungfu::BuiltinsStubCSigns::ID builtinId) const2934 JSHandle<JSTaggedValue> Builtins::CreateGetter(const JSHandle<GlobalEnv> &env, EcmaEntrypoint func,
2935                                                JSHandle<JSTaggedValue> key, int length,
2936                                                kungfu::BuiltinsStubCSigns::ID builtinId) const
2937 {
2938     JSHandle<JSFunction> function = factory_->NewJSBuiltinFunction(env, reinterpret_cast<void *>(func),
2939         FunctionKind::GETTER_FUNCTION, builtinId);
2940     JSFunction::SetFunctionLength(thread_, function, JSTaggedValue(length));
2941     JSHandle<JSTaggedValue> prefix = thread_->GlobalConstants()->GetHandledGetString();
2942     JSFunction::SetFunctionName(thread_, JSHandle<JSFunctionBase>(function), key, prefix);
2943     RegisterBuiltinToGlobalEnv(env, builtinId, function);
2944     return JSHandle<JSTaggedValue>(function);
2945 }
2946 
CreateSetter(const JSHandle<GlobalEnv> & env,EcmaEntrypoint func,std::string_view name,int length) const2947 JSHandle<JSTaggedValue> Builtins::CreateSetter(const JSHandle<GlobalEnv> &env, EcmaEntrypoint func,
2948                                                std::string_view name, int length) const
2949 {
2950     JSHandle<JSTaggedValue> funcName(factory_->NewFromUtf8ReadOnly(name));
2951     return CreateSetter(env, func, funcName, length);
2952 }
2953 
CreateSetter(const JSHandle<GlobalEnv> & env,EcmaEntrypoint func,JSHandle<JSTaggedValue> key,int length) const2954 JSHandle<JSTaggedValue> Builtins::CreateSetter(const JSHandle<GlobalEnv> &env, EcmaEntrypoint func,
2955                                                JSHandle<JSTaggedValue> key, int length) const
2956 {
2957     JSHandle<JSFunction> function = factory_->NewJSBuiltinFunction(env, reinterpret_cast<void *>(func));
2958     JSFunction::SetFunctionLength(thread_, function, JSTaggedValue(length));
2959     JSHandle<JSTaggedValue> prefix = thread_->GlobalConstants()->GetHandledSetString();
2960     JSFunction::SetFunctionName(thread_, JSHandle<JSFunctionBase>(function), key, prefix);
2961     return JSHandle<JSTaggedValue>(function);
2962 }
2963 
SetConstant(const JSHandle<JSObject> & obj,std::string_view key,JSTaggedValue value) const2964 void Builtins::SetConstant(const JSHandle<JSObject> &obj, std::string_view key, JSTaggedValue value) const
2965 {
2966     JSHandle<JSTaggedValue> keyString(factory_->NewFromUtf8ReadOnly(key));
2967     PropertyDescriptor descriptor(thread_, JSHandle<JSTaggedValue>(thread_, value), false, false, false);
2968     JSObject::DefineOwnProperty(thread_, obj, keyString, descriptor);
2969 }
2970 
SetConstantObject(const JSHandle<JSObject> & obj,std::string_view key,JSHandle<JSTaggedValue> & value) const2971 void Builtins::SetConstantObject(const JSHandle<JSObject> &obj, std::string_view key,
2972                                  JSHandle<JSTaggedValue> &value) const
2973 {
2974     JSHandle<JSTaggedValue> keyString(factory_->NewFromUtf8ReadOnly(key));
2975     PropertyDescriptor descriptor(thread_, value, false, false, false);
2976     JSObject::DefineOwnProperty(thread_, obj, keyString, descriptor);
2977 }
2978 
SetNonConstantObject(const JSHandle<JSObject> & obj,std::string_view key,JSHandle<JSTaggedValue> & value) const2979 void Builtins::SetNonConstantObject(const JSHandle<JSObject> &obj, std::string_view key,
2980                                     JSHandle<JSTaggedValue> &value) const
2981 {
2982     JSHandle<JSTaggedValue> keyString(factory_->NewFromUtf8ReadOnly(key));
2983     PropertyDescriptor descriptor(thread_, value, true, true, true);
2984     JSObject::DefineOwnProperty(thread_, obj, keyString, descriptor);
2985 }
2986 
SetGlobalThis(const JSHandle<JSObject> & obj,std::string_view key,const JSHandle<JSTaggedValue> & globalValue)2987 void Builtins::SetGlobalThis(const JSHandle<JSObject> &obj, std::string_view key,
2988                              const JSHandle<JSTaggedValue> &globalValue)
2989 {
2990     JSHandle<JSTaggedValue> keyString(factory_->NewFromUtf8ReadOnly(key));
2991     PropertyDescriptor descriptor(thread_, globalValue, true, false, true);
2992     JSObject::DefineOwnProperty(thread_, obj, keyString, descriptor);
2993 }
2994 
SetAttribute(const JSHandle<JSObject> & obj,std::string_view key,std::string_view value) const2995 void Builtins::SetAttribute(const JSHandle<JSObject> &obj, std::string_view key, std::string_view value) const
2996 {
2997     JSHandle<JSTaggedValue> keyString(factory_->NewFromUtf8ReadOnly(key));
2998     PropertyDescriptor descriptor(thread_, JSHandle<JSTaggedValue>(factory_->NewFromUtf8ReadOnly(value)),
2999                                                                    true, false, true);
3000     JSObject::DefineOwnProperty(thread_, obj, keyString, descriptor);
3001 }
3002 
SetNoneAttributeProperty(const JSHandle<JSObject> & obj,std::string_view key,const JSHandle<JSTaggedValue> & value) const3003 void Builtins::SetNoneAttributeProperty(const JSHandle<JSObject> &obj, std::string_view key,
3004                                         const JSHandle<JSTaggedValue> &value) const
3005 {
3006     JSHandle<JSTaggedValue> keyString(factory_->NewFromUtf8ReadOnly(key));
3007     PropertyDescriptor des(thread_, value, false, false, false);
3008     JSObject::DefineOwnProperty(thread_, obj, keyString, des);
3009 }
3010 
SetFuncToObjAndGlobal(const JSHandle<GlobalEnv> & env,const JSHandle<JSObject> & globalObject,const JSHandle<JSObject> & obj,std::string_view key,EcmaEntrypoint func,int length,kungfu::BuiltinsStubCSigns::ID builtinId)3011 void Builtins::SetFuncToObjAndGlobal(const JSHandle<GlobalEnv> &env, const JSHandle<JSObject> &globalObject,
3012                                      const JSHandle<JSObject> &obj, std::string_view key,
3013                                      EcmaEntrypoint func, int length, kungfu::BuiltinsStubCSigns::ID builtinId)
3014 {
3015     JSHandle<JSFunction> function = factory_->NewJSBuiltinFunction(env, reinterpret_cast<void *>(func),
3016         FunctionKind::NORMAL_FUNCTION, builtinId);
3017     JSFunction::SetFunctionLength(thread_, function, JSTaggedValue(length));
3018     JSHandle<JSTaggedValue> keyString(factory_->NewFromUtf8ReadOnly(key));
3019     JSHandle<JSFunctionBase> baseFunction(function);
3020     JSHandle<JSTaggedValue> handleUndefine(thread_, JSTaggedValue::Undefined());
3021     JSFunction::SetFunctionName(thread_, baseFunction, keyString, handleUndefine);
3022     RegisterBuiltinToGlobalEnv(env, builtinId, function);
3023     PropertyDescriptor descriptor(thread_, JSHandle<JSTaggedValue>::Cast(function), true, false, true);
3024     JSObject::DefineOwnProperty(thread_, obj, keyString, descriptor);
3025     JSObject::DefineOwnProperty(thread_, globalObject, keyString, descriptor);
3026 }
3027 
InitializeGeneratorFunction(const JSHandle<GlobalEnv> & env,const JSHandle<JSHClass> & objFuncClass) const3028 void Builtins::InitializeGeneratorFunction(const JSHandle<GlobalEnv> &env,
3029                                            const JSHandle<JSHClass> &objFuncClass) const
3030 {
3031     [[maybe_unused]] EcmaHandleScope scope(thread_);
3032     const GlobalEnvConstants *globalConst = thread_->GlobalConstants();
3033     JSHandle<JSObject> generatorFuncPrototype = factory_->NewJSObjectWithInit(objFuncClass);
3034     JSHandle<JSTaggedValue> generatorFuncPrototypeValue(generatorFuncPrototype);
3035 
3036     // 26.3.3.1 GeneratorFunction.prototype.constructor
3037     // GeneratorFunction.prototype_or_hclass
3038     JSHandle<JSHClass> generatorFuncInstanceHClass =
3039         factory_->NewEcmaHClass(JSFunction::SIZE, JSType::JS_GENERATOR_FUNCTION, generatorFuncPrototypeValue);
3040     generatorFuncInstanceHClass->SetCallable(true);
3041     generatorFuncInstanceHClass->SetExtensible(true);
3042     // GeneratorFunction = new GeneratorFunction()
3043     JSHandle<JSFunction> generatorFunction =
3044         NewBuiltinConstructor(env, generatorFuncPrototype, GeneratorObject::GeneratorFunctionConstructor,
3045                               "GeneratorFunction", FunctionLength::ONE);
3046     JSObject::SetPrototype(thread_, JSHandle<JSObject>::Cast(generatorFunction), env->GetFunctionFunction());
3047     JSHandle<JSTaggedValue> constructorKey = globalConst->GetHandledConstructorString();
3048     PropertyDescriptor generatorDesc(thread_, JSHandle<JSTaggedValue>::Cast(generatorFunction), false, false, true);
3049     JSObject::DefineOwnProperty(thread_, generatorFuncPrototype, constructorKey, generatorDesc);
3050     generatorFunction->SetProtoOrHClass(thread_, generatorFuncInstanceHClass.GetTaggedValue());
3051     env->SetGeneratorFunctionFunction(thread_, generatorFunction);
3052 
3053     // 26.3.3.2 GeneratorFunction.prototype.prototype -> Generator prototype object.
3054     PropertyDescriptor descriptor(thread_, env->GetGeneratorPrototype(), false, false, true);
3055     JSObject::DefineOwnProperty(thread_, generatorFuncPrototype, globalConst->GetHandledPrototypeString(), descriptor);
3056 
3057     // 26.3.3.3 GeneratorFunction.prototype[@@toStringTag]
3058     SetStringTagSymbol(env, generatorFuncPrototype, "GeneratorFunction");
3059 
3060     // GeneratorFunction prototype __proto__ -> Function.
3061     JSObject::SetPrototype(thread_, generatorFuncPrototype, env->GetFunctionPrototype());
3062 
3063     // 26.5.1.1 Generator.prototype.constructor -> %GeneratorFunction.prototype%.
3064     PropertyDescriptor generatorObjDesc(thread_, generatorFuncPrototypeValue, false, false, true);
3065     JSObject::DefineOwnProperty(thread_, JSHandle<JSObject>(env->GetGeneratorPrototype()),
3066                                 globalConst->GetHandledConstructorString(), generatorObjDesc);
3067 
3068     // Generator instances prototype -> GeneratorFunction.prototype.prototype
3069     PropertyDescriptor generatorObjProtoDesc(thread_, generatorFuncPrototypeValue, true, false, false);
3070     JSObject::DefineOwnProperty(thread_, JSHandle<JSObject>(env->GetInitialGenerator()),
3071                                 globalConst->GetHandledPrototypeString(), generatorObjProtoDesc);
3072 
3073     env->SetGeneratorFunctionPrototype(thread_, generatorFuncPrototype);
3074 }
3075 
InitializeAsyncGeneratorFunction(const JSHandle<GlobalEnv> & env,const JSHandle<JSHClass> & objFuncClass) const3076 void Builtins::InitializeAsyncGeneratorFunction(const JSHandle<GlobalEnv> &env,
3077                                                 const JSHandle<JSHClass> &objFuncClass) const
3078 {
3079     [[maybe_unused]] EcmaHandleScope scope(thread_);
3080     const GlobalEnvConstants *globalConst = thread_->GlobalConstants();
3081     JSHandle<JSObject> asyncGeneratorFuncPrototype = factory_->NewJSObjectWithInit(objFuncClass);
3082     JSHandle<JSTaggedValue> asyncGeneratorFuncPrototypeValue(asyncGeneratorFuncPrototype);
3083      // 27.4.3.1 AsyncGeneratorFunction.prototype.constructor
3084     JSHandle<JSHClass> asyncGeneratorFuncInstanceHClass =
3085         factory_->NewEcmaHClass(JSFunction::SIZE, JSType::JS_ASYNC_GENERATOR_FUNCTION,
3086                                 asyncGeneratorFuncPrototypeValue);
3087     asyncGeneratorFuncInstanceHClass->SetCallable(true);
3088     asyncGeneratorFuncInstanceHClass->SetExtensible(true);
3089     JSHandle<JSFunction> asyncGeneratorFunction =
3090         NewBuiltinConstructor(env, asyncGeneratorFuncPrototype,
3091                               AsyncGeneratorObject::AsyncGeneratorFunctionConstructor, "AsyncGeneratorFunction",
3092                               FunctionLength::ONE);
3093     JSObject::SetPrototype(thread_, JSHandle<JSObject>::Cast(asyncGeneratorFunction), env->GetFunctionFunction());
3094     JSHandle<JSTaggedValue> constructorKey = globalConst->GetHandledConstructorString();
3095     PropertyDescriptor asyncGeneratorDesc(thread_, JSHandle<JSTaggedValue>::Cast(asyncGeneratorFunction),
3096                                           false, false, true);
3097     JSObject::DefineOwnProperty(thread_, asyncGeneratorFuncPrototype, constructorKey, asyncGeneratorDesc);
3098     asyncGeneratorFunction->SetProtoOrHClass(thread_, asyncGeneratorFuncInstanceHClass.GetTaggedValue());
3099     env->SetAsyncGeneratorFunctionFunction(thread_, asyncGeneratorFunction);
3100 
3101     // 27.4.3.2 AsyncGeneratorFunction.prototype.prototype
3102     PropertyDescriptor descriptor(thread_, env->GetAsyncGeneratorPrototype(), false, false, true);
3103     JSObject::DefineOwnProperty(thread_, asyncGeneratorFuncPrototype, globalConst->GetHandledPrototypeString(),
3104                                 descriptor);
3105 
3106     // 27.4.3.3 AsyncGeneratorFunction.prototype [ @@toStringTag ]
3107     SetStringTagSymbol(env, asyncGeneratorFuncPrototype, "AsyncGeneratorFunction");
3108     // AsyncGeneratorFunction prototype __proto__ -> Function.
3109     JSObject::SetPrototype(thread_, asyncGeneratorFuncPrototype, env->GetFunctionPrototype());
3110 
3111     PropertyDescriptor asyncGeneratorObjDesc(thread_, asyncGeneratorFuncPrototypeValue, false, false, true);
3112     JSObject::DefineOwnProperty(thread_, JSHandle<JSObject>(env->GetInitialAsyncGenerator()),
3113                                 globalConst->GetHandledConstructorString(), asyncGeneratorObjDesc);
3114 
3115     PropertyDescriptor asyncGeneratorObjProtoDesc(thread_, asyncGeneratorFuncPrototypeValue, true, false, false);
3116     JSObject::DefineOwnProperty(thread_, JSHandle<JSObject>(env->GetInitialAsyncGenerator()),
3117                                 globalConst->GetHandledPrototypeString(), asyncGeneratorObjProtoDesc);
3118 
3119     env->SetAsyncGeneratorFunctionPrototype(thread_, asyncGeneratorFuncPrototype);
3120 }
3121 
InitializeGenerator(const JSHandle<GlobalEnv> & env,const JSHandle<JSHClass> & objFuncClass) const3122 void Builtins::InitializeGenerator(const JSHandle<GlobalEnv> &env, const JSHandle<JSHClass> &objFuncClass) const
3123 {
3124     [[maybe_unused]] EcmaHandleScope scope(thread_);
3125     JSHandle<JSObject> generatorPrototype = factory_->NewJSObjectWithInit(objFuncClass);
3126 
3127     // GeneratorObject.prototype method
3128     // Generator.prototype.constructor(value)
3129     SetFunction(env, generatorPrototype, "constructor",
3130                 GeneratorObject::GeneratorFunctionConstructor, FunctionLength::ONE);
3131     // 26.5.1.2 Generator.prototype.next(value)
3132     SetFunction(env, generatorPrototype, "next", GeneratorObject::GeneratorPrototypeNext, FunctionLength::ONE);
3133     // 26.5.1.3 Generator.prototype.return(value)
3134     SetFunction(env, generatorPrototype, "return", GeneratorObject::GeneratorPrototypeReturn, FunctionLength::ONE);
3135     // 26.5.1.4 Generator.prototype.throw(exception)
3136     SetFunction(env, generatorPrototype, "throw", GeneratorObject::GeneratorPrototypeThrow, FunctionLength::ONE);
3137 
3138     // 26.5.1.5 Generator.prototype[@@toStringTag]
3139     SetStringTagSymbol(env, generatorPrototype, "Generator");
3140 
3141     env->SetGeneratorPrototype(thread_, generatorPrototype);
3142     JSObject::SetPrototype(thread_, generatorPrototype, env->GetIteratorPrototype());
3143 
3144     // Generator {}
3145     JSHandle<JSObject> initialGeneratorFuncPrototype = factory_->NewJSObjectWithInit(objFuncClass);
3146     JSObject::SetPrototype(thread_, initialGeneratorFuncPrototype, JSHandle<JSTaggedValue>(generatorPrototype));
3147     env->SetInitialGenerator(thread_, initialGeneratorFuncPrototype);
3148 }
3149 
InitializeAsyncGenerator(const JSHandle<GlobalEnv> & env,const JSHandle<JSHClass> & objFuncClass) const3150 void Builtins::InitializeAsyncGenerator(const JSHandle<GlobalEnv> &env,
3151                                         const JSHandle<JSHClass> &objFuncClass) const
3152 {
3153     [[maybe_unused]] EcmaHandleScope scope(thread_);
3154 
3155     const GlobalEnvConstants *globalConst = thread_->GlobalConstants();
3156     JSHandle<JSObject> asyncGeneratorFuncPrototype = factory_->NewJSObjectWithInit(objFuncClass);
3157 
3158     // GeneratorObject.prototype method
3159     // 27.6.1.2 AsyncGenerator.prototype.next ( value )
3160     SetFunction(env, asyncGeneratorFuncPrototype, "next", AsyncGeneratorObject::AsyncGeneratorPrototypeNext,
3161                 FunctionLength::ONE);
3162     // 27.6.1.3 AsyncGenerator.prototype.return ( value )
3163     SetFunction(env, asyncGeneratorFuncPrototype, "return", AsyncGeneratorObject::AsyncGeneratorPrototypeReturn,
3164                 FunctionLength::ONE);
3165     // 27.6.1.4 AsyncGenerator.prototype.throw ( exception )
3166     SetFunction(env, asyncGeneratorFuncPrototype, "throw", AsyncGeneratorObject::AsyncGeneratorPrototypeThrow,
3167                 FunctionLength::ONE);
3168 
3169     // 27.6.1.5 AsyncGenerator.prototype [ @@toStringTag ]
3170     SetStringTagSymbol(env, asyncGeneratorFuncPrototype, "AsyncGenerator");
3171 
3172     PropertyDescriptor descriptor(thread_, env->GetAsyncIteratorPrototype(), true, false, false);
3173     JSObject::DefineOwnProperty(thread_, asyncGeneratorFuncPrototype,
3174                                 globalConst->GetHandledPrototypeString(), descriptor);
3175     env->SetAsyncGeneratorPrototype(thread_, asyncGeneratorFuncPrototype);
3176     JSObject::SetPrototype(thread_, asyncGeneratorFuncPrototype, env->GetAsyncIteratorPrototype());
3177 
3178     JSHandle<JSObject> initialAsyncGeneratorFuncPrototype = factory_->NewJSObjectWithInit(objFuncClass);
3179     JSObject::SetPrototype(thread_, initialAsyncGeneratorFuncPrototype,
3180                            JSHandle<JSTaggedValue>(asyncGeneratorFuncPrototype));
3181     env->SetInitialAsyncGenerator(thread_, initialAsyncGeneratorFuncPrototype);
3182 }
3183 
SetArgumentsSharedAccessor(const JSHandle<GlobalEnv> & env)3184 void Builtins::SetArgumentsSharedAccessor(const JSHandle<GlobalEnv> &env)
3185 {
3186     JSHandle<JSTaggedValue> throwFunction = env->GetThrowTypeError();
3187 
3188     JSHandle<AccessorData> accessor = factory_->NewAccessorData();
3189     accessor->SetGetter(thread_, throwFunction);
3190     accessor->SetSetter(thread_, throwFunction);
3191     env->SetArgumentsCallerAccessor(thread_, accessor);
3192 
3193     accessor = factory_->NewAccessorData();
3194     accessor->SetGetter(thread_, throwFunction);
3195     accessor->SetSetter(thread_, throwFunction);
3196     env->SetArgumentsCalleeAccessor(thread_, accessor);
3197 }
3198 
SetAccessor(const JSHandle<JSObject> & obj,const JSHandle<JSTaggedValue> & key,const JSHandle<JSTaggedValue> & getter,const JSHandle<JSTaggedValue> & setter) const3199 void Builtins::SetAccessor(const JSHandle<JSObject> &obj, const JSHandle<JSTaggedValue> &key,
3200                            const JSHandle<JSTaggedValue> &getter, const JSHandle<JSTaggedValue> &setter) const
3201 {
3202     JSHandle<AccessorData> accessor = factory_->NewAccessorData();
3203     accessor->SetGetter(thread_, getter);
3204     accessor->SetSetter(thread_, setter);
3205     PropertyAttributes attr = PropertyAttributes::DefaultAccessor(false, false, true);
3206     JSObject::AddAccessor(thread_, JSHandle<JSTaggedValue>::Cast(obj), key, accessor, attr);
3207 }
3208 
SetGetter(const JSHandle<JSObject> & obj,const JSHandle<JSTaggedValue> & key,const JSHandle<JSTaggedValue> & getter) const3209 void Builtins::SetGetter(const JSHandle<JSObject> &obj, const JSHandle<JSTaggedValue> &key,
3210                          const JSHandle<JSTaggedValue> &getter) const
3211 {
3212     JSHandle<AccessorData> accessor = factory_->NewAccessorData();
3213     accessor->SetGetter(thread_, getter);
3214     PropertyAttributes attr = PropertyAttributes::DefaultAccessor(false, false, true);
3215     JSObject::AddAccessor(thread_, JSHandle<JSTaggedValue>::Cast(obj), key, accessor, attr);
3216 }
3217 
3218 #ifdef ARK_SUPPORT_INTL
NewIntlConstructor(const JSHandle<GlobalEnv> & env,const JSHandle<JSObject> & prototype,EcmaEntrypoint ctorFunc,std::string_view name,int length)3219 JSHandle<JSFunction> Builtins::NewIntlConstructor(const JSHandle<GlobalEnv> &env, const JSHandle<JSObject> &prototype,
3220                                                   EcmaEntrypoint ctorFunc, std::string_view name, int length)
3221 {
3222     JSHandle<JSFunction> ctor =
3223         factory_->NewJSBuiltinFunction(env, reinterpret_cast<void *>(ctorFunc), FunctionKind::BUILTIN_CONSTRUCTOR);
3224     InitializeIntlCtor(env, prototype, ctor, name, length);
3225     return ctor;
3226 }
3227 
3228 #define INTL_LAZY_INITIALIZE(type)                                               \
3229     void Builtins::LazyInitialize##type(const JSHandle<GlobalEnv> &env) const    \
3230     {                                                                            \
3231         [[maybe_unused]] EcmaHandleScope scope(thread_);                         \
3232         JSHandle<JSObject> intlObject(env->GetIntlFunction());                   \
3233         JSHandle<JSTaggedValue> key(factory_->NewFromUtf8ReadOnly(#type));       \
3234         auto accessor = factory_->NewInternalAccessor(nullptr,                   \
3235             reinterpret_cast<void *>(BuiltinsLazyCallback::type));               \
3236         SetLazyAccessor(intlObject, key, accessor);                              \
3237         env->Set##type##Function(thread_, accessor);                             \
3238     }
3239 
ITERATE_INTL(INTL_LAZY_INITIALIZE)3240 ITERATE_INTL(INTL_LAZY_INITIALIZE)
3241 #undef INTL_LAZY_INITIALIZE
3242 
3243 void Builtins::InitializeIntlCtor(const JSHandle<GlobalEnv> &env, const JSHandle<JSObject> &prototype,
3244                                   const JSHandle<JSFunction> &ctor, std::string_view name, int length)
3245 {
3246     const GlobalEnvConstants *globalConst = thread_->GlobalConstants();
3247     JSFunction::SetFunctionLength(thread_, ctor, JSTaggedValue(length));
3248     JSHandle<JSTaggedValue> nameString(factory_->NewFromUtf8ReadOnly(name));
3249     JSFunction::SetFunctionName(thread_, JSHandle<JSFunctionBase>(ctor), nameString,
3250                                 JSHandle<JSTaggedValue>(thread_, JSTaggedValue::Undefined()));
3251     JSHandle<JSTaggedValue> constructorKey = globalConst->GetHandledConstructorString();
3252     PropertyDescriptor descriptor1(thread_, JSHandle<JSTaggedValue>::Cast(ctor), true, false, true);
3253     JSObject::DefineOwnProperty(thread_, prototype, constructorKey, descriptor1);
3254 
3255     // set "prototype" in constructor.
3256     JSFunction::SetFunctionPrototypeOrInstanceHClass(thread_, ctor, prototype.GetTaggedValue());
3257 
3258     if (!JSTaggedValue::SameValue(thread_, nameString, thread_->GlobalConstants()->GetHandledAsyncFunctionString())) {
3259         JSHandle<JSObject> intlObject(thread_, env->GetIntlFunction().GetTaggedValue());
3260         PropertyDescriptor descriptor2(thread_, JSHandle<JSTaggedValue>::Cast(ctor), true, false, true);
3261         JSObject::DefineOwnProperty(thread_, intlObject, nameString, descriptor2);
3262     }
3263 }
3264 
InitializeIntl(const JSHandle<GlobalEnv> & env,const JSHandle<JSTaggedValue> & objFuncPrototypeValue)3265 void Builtins::InitializeIntl(const JSHandle<GlobalEnv> &env, const JSHandle<JSTaggedValue> &objFuncPrototypeValue)
3266 {
3267     [[maybe_unused]] EcmaHandleScope scope(thread_);
3268     JSHandle<JSHClass> intlHClass = factory_->NewEcmaHClass(JSIntl::SIZE, JSType::JS_INTL, objFuncPrototypeValue);
3269     JSHandle<JSObject> intlObject = factory_->NewJSObjectWithInit(intlHClass);
3270 
3271     JSHandle<JSTaggedValue> initIntlSymbol(factory_->NewPublicSymbolWithChar("Symbol.IntlLegacyConstructedSymbol"));
3272     SetNoneAttributeProperty(intlObject, "fallbackSymbol", initIntlSymbol);
3273 
3274     SetFunction(env, intlObject, "getCanonicalLocales", Intl::GetCanonicalLocales, FunctionLength::ONE);
3275 
3276     // initial value of the "Intl" property of the global object.
3277     JSHandle<JSTaggedValue> intlString(factory_->NewFromASCIIReadOnly("Intl"));
3278     JSHandle<JSObject> globalObject(thread_, env->GetGlobalObject());
3279     PropertyDescriptor intlDesc(thread_, JSHandle<JSTaggedValue>::Cast(intlObject), true, false, true);
3280     JSObject::DefineOwnProperty(thread_, globalObject, intlString, intlDesc);
3281 
3282     SetStringTagSymbol(env, intlObject, "Intl");
3283 
3284     env->SetIntlFunction(thread_, intlObject);
3285 }
3286 
InitializeDateTimeFormat(const JSHandle<GlobalEnv> & env)3287 void Builtins::InitializeDateTimeFormat(const JSHandle<GlobalEnv> &env)
3288 {
3289     [[maybe_unused]] EcmaHandleScope scope(thread_);
3290     // DateTimeFormat.prototype
3291     JSHandle<JSFunction> objFun(env->GetObjectFunction());
3292     JSHandle<JSObject> dtfPrototype = factory_->NewJSObjectByConstructor(env, objFun);
3293     JSHandle<JSTaggedValue> dtfPrototypeValue(dtfPrototype);
3294 
3295     // DateTimeFormat.prototype_or_hclass
3296     JSHandle<JSHClass> dtfFuncInstanceHClass =
3297         factory_->NewEcmaHClass(JSDateTimeFormat::SIZE, JSType::JS_DATE_TIME_FORMAT, dtfPrototypeValue);
3298 
3299     // DateTimeFormat = new Function()
3300     // 13.4.1 Intl.DateTimeFormat.prototype.constructor
3301     JSHandle<JSObject> dtfFunction(NewIntlConstructor(env, dtfPrototype, DateTimeFormat::DateTimeFormatConstructor,
3302                                                       "DateTimeFormat", FunctionLength::ZERO));
3303     JSFunction::SetFunctionPrototypeOrInstanceHClass(thread_,
3304                                                      JSHandle<JSFunction>(dtfFunction),
3305                                                      JSTaggedValue(*dtfFuncInstanceHClass));
3306 
3307     // 13.3.2 Intl.DateTimeFormat.supportedLocalesOf ( locales [ , options ] )
3308     SetFunction(env, dtfFunction, "supportedLocalesOf", DateTimeFormat::SupportedLocalesOf, FunctionLength::ONE);
3309 
3310     // DateTimeFormat.prototype method
3311     // 13.4.2 Intl.DateTimeFormat.prototype [ @@toStringTag ]
3312     SetStringTagSymbol(env, dtfPrototype, "Intl.DateTimeFormat");
3313     env->SetDateTimeFormatFunction(thread_, dtfFunction);
3314 
3315     // 13.4.3 get Intl.DateTimeFormat.prototype.format
3316     JSHandle<JSTaggedValue> formatGetter = CreateGetter(env, DateTimeFormat::Format, "format", FunctionLength::ZERO);
3317     JSHandle<JSTaggedValue> formatSetter(thread_, JSTaggedValue::Undefined());
3318     SetAccessor(dtfPrototype, thread_->GlobalConstants()->GetHandledFormatString(), formatGetter, formatSetter);
3319 
3320     // 13.4.4 Intl.DateTimeFormat.prototype.formatToParts ( date )
3321     SetFunction(env, dtfPrototype, "formatToParts", DateTimeFormat::FormatToParts, FunctionLength::ONE);
3322 
3323     // 13.4.5 Intl.DateTimeFormat.prototype.resolvedOptions ()
3324     SetFunction(env, dtfPrototype, "resolvedOptions", DateTimeFormat::ResolvedOptions, FunctionLength::ZERO);
3325 
3326     SetFunction(env, dtfPrototype, "formatRange", DateTimeFormat::FormatRange, FunctionLength::TWO);
3327 
3328     SetFunction(env, dtfPrototype, "formatRangeToParts", DateTimeFormat::FormatRangeToParts, FunctionLength::TWO);
3329 }
3330 
InitializeRelativeTimeFormat(const JSHandle<GlobalEnv> & env)3331 void Builtins::InitializeRelativeTimeFormat(const JSHandle<GlobalEnv> &env)
3332 {
3333     [[maybe_unused]] EcmaHandleScope scope(thread_);
3334     // RelativeTimeFormat.prototype
3335     JSHandle<JSFunction> objFun(env->GetObjectFunction());
3336     JSHandle<JSObject> rtfPrototype = factory_->NewJSObjectByConstructor(env, objFun);
3337     JSHandle<JSTaggedValue> rtfPrototypeValue(rtfPrototype);
3338 
3339     // RelativeTimeFormat.prototype_or_hclass
3340     JSHandle<JSHClass> rtfFuncInstanceHClass =
3341         factory_->NewEcmaHClass(JSRelativeTimeFormat::SIZE, JSType::JS_RELATIVE_TIME_FORMAT, rtfPrototypeValue);
3342 
3343     // RelativeTimeFormat = new Function()
3344     // 14.2.1 Intl.RelativeTimeFormat.prototype.constructor
3345     JSHandle<JSObject> rtfFunction(NewIntlConstructor(env, rtfPrototype,
3346                                                       RelativeTimeFormat::RelativeTimeFormatConstructor,
3347                                                       "RelativeTimeFormat", FunctionLength::ZERO));
3348     JSFunction::SetFunctionPrototypeOrInstanceHClass(thread_,
3349                                                      JSHandle<JSFunction>(rtfFunction),
3350                                                      JSTaggedValue(*rtfFuncInstanceHClass));
3351 
3352     // 14.3.2 Intl.RelativeTimeFormat.supportedLocalesOf ( locales [ , options ] )
3353     SetFunction(env, rtfFunction, "supportedLocalesOf", RelativeTimeFormat::SupportedLocalesOf, FunctionLength::ONE);
3354 
3355     // RelativeTimeFormat.prototype method
3356     // 14.4.2 Intl.RelativeTimeFormat.prototype [ @@toStringTag ]
3357     SetStringTagSymbol(env, rtfPrototype, "Intl.RelativeTimeFormat");
3358     env->SetRelativeTimeFormatFunction(thread_, rtfFunction);
3359 
3360     // 14.4.3 get Intl.RelativeTimeFormat.prototype.format
3361     SetFunction(env, rtfPrototype, "format", RelativeTimeFormat::Format, FunctionLength::TWO);
3362 
3363     // 14.4.4  Intl.RelativeTimeFormat.prototype.formatToParts( value, unit )
3364     SetFunction(env, rtfPrototype, "formatToParts", RelativeTimeFormat::FormatToParts, FunctionLength::TWO);
3365 
3366     // 14.4.5 Intl.RelativeTimeFormat.prototype.resolvedOptions ()
3367     SetFunction(env, rtfPrototype, "resolvedOptions", RelativeTimeFormat::ResolvedOptions, FunctionLength::ZERO);
3368 }
3369 
InitializeNumberFormat(const JSHandle<GlobalEnv> & env)3370 void Builtins::InitializeNumberFormat(const JSHandle<GlobalEnv> &env)
3371 {
3372     [[maybe_unused]] EcmaHandleScope scope(thread_);
3373     // NumberFormat.prototype
3374     JSHandle<JSFunction> objFun(env->GetObjectFunction());
3375     JSHandle<JSObject> nfPrototype = factory_->NewJSObjectByConstructor(env, objFun);
3376     JSHandle<JSTaggedValue> nfPrototypeValue(nfPrototype);
3377 
3378     // NumberFormat.prototype_or_hclass
3379     JSHandle<JSHClass> nfFuncInstanceHClass =
3380         factory_->NewEcmaHClass(JSNumberFormat::SIZE, JSType::JS_NUMBER_FORMAT, nfPrototypeValue);
3381 
3382     // NumberFormat = new Function()
3383     // 12.4.1 Intl.NumberFormat.prototype.constructor
3384     JSHandle<JSObject> nfFunction(NewIntlConstructor(env, nfPrototype, NumberFormat::NumberFormatConstructor,
3385                                                      "NumberFormat", FunctionLength::ZERO));
3386     JSFunction::SetFunctionPrototypeOrInstanceHClass(thread_,
3387                                                      JSHandle<JSFunction>(nfFunction),
3388                                                      JSTaggedValue(*nfFuncInstanceHClass));
3389 
3390     // 12.3.2 Intl.NumberFormat.supportedLocalesOf ( locales [ , options ] )
3391     SetFunction(env, nfFunction, "supportedLocalesOf", NumberFormat::SupportedLocalesOf, FunctionLength::ONE);
3392 
3393     // NumberFormat.prototype method
3394     // 12.4.2 Intl.NumberFormat.prototype [ @@toStringTag ]
3395     SetStringTagSymbol(env, nfPrototype, "Intl.NumberFormat");
3396     env->SetNumberFormatFunction(thread_, nfFunction);
3397 
3398     // 12.4.3 get Intl.NumberFormat.prototype.format
3399     JSHandle<JSTaggedValue> formatGetter = CreateGetter(env, NumberFormat::Format, "format", FunctionLength::ZERO);
3400     JSHandle<JSTaggedValue> formatSetter(thread_, JSTaggedValue::Undefined());
3401     SetAccessor(nfPrototype, thread_->GlobalConstants()->GetHandledFormatString(), formatGetter, formatSetter);
3402 
3403     // 12.4.4 Intl.NumberFormat.prototype.formatToParts ( date )
3404     SetFunction(env, nfPrototype, "formatToParts", NumberFormat::FormatToParts, FunctionLength::ONE);
3405 
3406     // 12.4.5 Intl.NumberFormat.prototype.resolvedOptions ()
3407     SetFunction(env, nfPrototype, "resolvedOptions", NumberFormat::ResolvedOptions, FunctionLength::ZERO);
3408 }
3409 
InitializeLocale(const JSHandle<GlobalEnv> & env)3410 void Builtins::InitializeLocale(const JSHandle<GlobalEnv> &env)
3411 {
3412     [[maybe_unused]] EcmaHandleScope scope(thread_);
3413     // Locale.prototype
3414     JSHandle<JSFunction> objFun(env->GetObjectFunction());
3415     JSHandle<JSObject> localePrototype = factory_->NewJSObjectByConstructor(env, objFun);
3416     JSHandle<JSTaggedValue> localePrototypeValue(localePrototype);
3417 
3418     // Locale.prototype_or_hclass
3419     JSHandle<JSHClass> localeFuncInstanceHClass =
3420         factory_->NewEcmaHClass(JSLocale::SIZE, JSType::JS_LOCALE, localePrototypeValue);
3421 
3422     // Locale = new Function()
3423     JSHandle<JSObject> localeFunction(
3424         NewIntlConstructor(env, localePrototype, Locale::LocaleConstructor, "Locale", FunctionLength::ONE));
3425     JSFunction::SetFunctionPrototypeOrInstanceHClass(thread_,
3426                                                      JSHandle<JSFunction>(localeFunction),
3427                                                      JSTaggedValue(*localeFuncInstanceHClass));
3428 
3429     // Locale.prototype method
3430     SetFunction(env, localePrototype, "maximize", Locale::Maximize, FunctionLength::ZERO);
3431     SetFunction(env, localePrototype, "minimize", Locale::Minimize, FunctionLength::ZERO);
3432     SetFunction(env, localePrototype, "toString", Locale::ToString, FunctionLength::ZERO);
3433 
3434     JSHandle<JSTaggedValue> baseNameGetter = CreateGetter(env, Locale::GetBaseName, "baseName", FunctionLength::ZERO);
3435     SetGetter(localePrototype, thread_->GlobalConstants()->GetHandledBaseNameString(), baseNameGetter);
3436 
3437     JSHandle<JSTaggedValue> calendarGetter = CreateGetter(env, Locale::GetCalendar, "calendar", FunctionLength::ZERO);
3438     SetGetter(localePrototype, thread_->GlobalConstants()->GetHandledCalendarString(), calendarGetter);
3439 
3440     JSHandle<JSTaggedValue> caseFirstGetter =
3441         CreateGetter(env, Locale::GetCaseFirst, "caseFirst", FunctionLength::ZERO);
3442     SetGetter(localePrototype, thread_->GlobalConstants()->GetHandledCaseFirstString(), caseFirstGetter);
3443 
3444     JSHandle<JSTaggedValue> collationGetter =
3445         CreateGetter(env, Locale::GetCollation, "collation", FunctionLength::ZERO);
3446     SetGetter(localePrototype, thread_->GlobalConstants()->GetHandledCollationString(), collationGetter);
3447 
3448     JSHandle<JSTaggedValue> hourCycleGetter =
3449         CreateGetter(env, Locale::GetHourCycle, "hourCycle", FunctionLength::ZERO);
3450     SetGetter(localePrototype, thread_->GlobalConstants()->GetHandledHourCycleString(), hourCycleGetter);
3451 
3452     JSHandle<JSTaggedValue> numericGetter = CreateGetter(env, Locale::GetNumeric, "numeric", FunctionLength::ZERO);
3453     SetGetter(localePrototype, thread_->GlobalConstants()->GetHandledNumericString(), numericGetter);
3454 
3455     JSHandle<JSTaggedValue> numberingSystemGetter =
3456         CreateGetter(env, Locale::GetNumberingSystem, "numberingSystem", FunctionLength::ZERO);
3457     SetGetter(localePrototype, thread_->GlobalConstants()->GetHandledNumberingSystemString(), numberingSystemGetter);
3458 
3459     JSHandle<JSTaggedValue> languageGetter = CreateGetter(env, Locale::GetLanguage, "language", FunctionLength::ZERO);
3460     SetGetter(localePrototype, thread_->GlobalConstants()->GetHandledLanguageString(), languageGetter);
3461 
3462     JSHandle<JSTaggedValue> scriptGetter = CreateGetter(env, Locale::GetScript, "script", FunctionLength::ZERO);
3463     SetGetter(localePrototype, thread_->GlobalConstants()->GetHandledScriptString(), scriptGetter);
3464 
3465     JSHandle<JSTaggedValue> regionGetter = CreateGetter(env, Locale::GetRegion, "region", FunctionLength::ZERO);
3466     SetGetter(localePrototype, thread_->GlobalConstants()->GetHandledRegionString(), regionGetter);
3467 
3468     // 10.3.2 Intl.Locale.prototype[ @@toStringTag ]
3469     SetStringTagSymbol(env, localePrototype, "Intl.Locale");
3470     env->SetLocaleFunction(thread_, localeFunction);
3471 }
3472 
InitializeCollator(const JSHandle<GlobalEnv> & env)3473 void Builtins::InitializeCollator(const JSHandle<GlobalEnv> &env)
3474 {
3475     [[maybe_unused]] EcmaHandleScope scope(thread_);
3476     // Collator.prototype
3477     JSHandle<JSFunction> objFun(env->GetObjectFunction());
3478     JSHandle<JSObject> collatorPrototype = factory_->NewJSObjectByConstructor(env, objFun);
3479     JSHandle<JSTaggedValue> collatorPrototypeValue(collatorPrototype);
3480 
3481     // Collator.prototype_or_hclass
3482     JSHandle<JSHClass> collatorFuncInstanceHClass =
3483         factory_->NewEcmaHClass(JSCollator::SIZE, JSType::JS_COLLATOR, collatorPrototypeValue);
3484 
3485     // Collator = new Function()
3486     // 11.1.2 Intl.Collator.prototype.constructor
3487     JSHandle<JSObject> collatorFunction(
3488         NewIntlConstructor(env, collatorPrototype, Collator::CollatorConstructor, "Collator", FunctionLength::ZERO));
3489     JSFunction::SetFunctionPrototypeOrInstanceHClass(thread_,
3490                                                      JSHandle<JSFunction>(collatorFunction),
3491                                                      JSTaggedValue(*collatorFuncInstanceHClass));
3492 
3493     // 11.2.2 Intl.Collator.supportedLocalesOf ( locales [ , options ] )
3494     SetFunction(env, collatorFunction, "supportedLocalesOf", Collator::SupportedLocalesOf, FunctionLength::ONE);
3495 
3496     // Collator.prototype method
3497     // 11.3.2 Intl.Collator.prototype [ @@toStringTag ]
3498     SetStringTagSymbol(env, collatorPrototype, "Intl.Collator");
3499     env->SetCollatorFunction(thread_, collatorFunction);
3500 
3501     // 11.3.3 get Intl.Collator.prototype.compare
3502     JSHandle<JSTaggedValue> compareGetter = CreateGetter(env, Collator::Compare, "compare", FunctionLength::ZERO);
3503     JSHandle<JSTaggedValue> compareSetter(thread_, JSTaggedValue::Undefined());
3504     SetAccessor(collatorPrototype, thread_->GlobalConstants()->GetHandledCompareString(), compareGetter, compareSetter);
3505 
3506     // 11.3.4 Intl.Collator.prototype.resolvedOptions ()
3507     SetFunction(env, collatorPrototype, "resolvedOptions", Collator::ResolvedOptions, FunctionLength::ZERO,
3508                 BUILTINS_STUB_ID(CollatorResolvedOptions));
3509 }
3510 
InitializePluralRules(const JSHandle<GlobalEnv> & env)3511 void Builtins::InitializePluralRules(const JSHandle<GlobalEnv> &env)
3512 {
3513     [[maybe_unused]] EcmaHandleScope scope(thread_);
3514     // PluralRules.prototype
3515     JSHandle<JSFunction> objFun(env->GetObjectFunction());
3516     JSHandle<JSObject> prPrototype = factory_->NewJSObjectByConstructor(env, objFun);
3517     JSHandle<JSTaggedValue> prPrototypeValue(prPrototype);
3518 
3519     // PluralRules.prototype_or_hclass
3520     JSHandle<JSHClass> prFuncInstanceHClass =
3521         factory_->NewEcmaHClass(JSPluralRules::SIZE, JSType::JS_PLURAL_RULES, prPrototypeValue);
3522 
3523     // PluralRules = new Function()
3524     // 15.2.1 Intl.PluralRules.prototype.constructor
3525     JSHandle<JSObject> prFunction(
3526         NewIntlConstructor(env, prPrototype, PluralRules::PluralRulesConstructor, "PluralRules", FunctionLength::ZERO));
3527     JSFunction::SetFunctionPrototypeOrInstanceHClass(thread_,
3528                                                      JSHandle<JSFunction>(prFunction),
3529                                                      JSTaggedValue(*prFuncInstanceHClass));
3530 
3531     // 15.3.2 Intl.PluralRules.supportedLocalesOf ( locales [ , options ] )
3532     SetFunction(env, prFunction, "supportedLocalesOf", PluralRules::SupportedLocalesOf, FunctionLength::ONE);
3533 
3534     // PluralRules.prototype method
3535     // 15.4.2 Intl.PluralRules.prototype [ @@toStringTag ]
3536     SetStringTagSymbol(env, prPrototype, "Intl.PluralRules");
3537     env->SetPluralRulesFunction(thread_, prFunction);
3538 
3539     // 15.4.3 get Intl.PluralRules.prototype.select
3540     SetFunction(env, prPrototype, "select", PluralRules::Select, FunctionLength::ONE);
3541 
3542     // 15.4.5 Intl.PluralRules.prototype.resolvedOptions ()
3543     SetFunction(env, prPrototype, "resolvedOptions", PluralRules::ResolvedOptions, FunctionLength::ZERO);
3544 }
3545 
InitializeDisplayNames(const JSHandle<GlobalEnv> & env)3546 void Builtins::InitializeDisplayNames(const JSHandle<GlobalEnv> &env)
3547 {
3548     [[maybe_unused]] EcmaHandleScope scope(thread_);
3549     // DisplayNames.prototype
3550     JSHandle<JSFunction> objFun(env->GetObjectFunction());
3551     JSHandle<JSObject> dnPrototype = factory_->NewJSObjectByConstructor(env, objFun);
3552     JSHandle<JSTaggedValue> dnPrototypeValue(dnPrototype);
3553 
3554     // DisplayNames.prototype_or_hclass
3555     JSHandle<JSHClass> dnFuncInstanceHClass =
3556         factory_->NewEcmaHClass(JSDisplayNames::SIZE, JSType::JS_DISPLAYNAMES, dnPrototypeValue);
3557 
3558     // DisplayNames = new Function()
3559     // 12.4.1 Intl.DisplayNames.prototype.constructor
3560     JSHandle<JSObject> dnFunction(NewIntlConstructor(env, dnPrototype, DisplayNames::DisplayNamesConstructor,
3561                                                      "DisplayNames", FunctionLength::TWO));
3562     JSFunction::SetFunctionPrototypeOrInstanceHClass(thread_,
3563                                                      JSHandle<JSFunction>(dnFunction),
3564                                                      JSTaggedValue(*dnFuncInstanceHClass));
3565 
3566     // 12.3.2 Intl.DisplayNames.supportedLocalesOf ( locales [ , options ] )
3567     SetFunction(env, dnFunction, "supportedLocalesOf", DisplayNames::SupportedLocalesOf, FunctionLength::ONE);
3568 
3569     // DisplayNames.prototype method
3570     // 12.4.2 Intl.DisplayNames.prototype[ @@toStringTag ]
3571     SetStringTagSymbol(env, dnPrototype, "Intl.DisplayNames");
3572     env->SetDisplayNamesFunction(thread_, dnFunction);
3573 
3574     // 12.4.3 get Intl.DisplayNames.prototype.of
3575     SetFunction(env, dnPrototype, "of", DisplayNames::Of, FunctionLength::ONE);
3576 
3577     // 12.4.4 Intl.DisplayNames.prototype.resolvedOptions ()
3578     SetFunction(env, dnPrototype, "resolvedOptions", DisplayNames::ResolvedOptions, FunctionLength::ZERO);
3579 }
3580 
InitializeListFormat(const JSHandle<GlobalEnv> & env)3581 void Builtins::InitializeListFormat(const JSHandle<GlobalEnv> &env)
3582 {
3583     [[maybe_unused]] EcmaHandleScope scope(thread_);
3584     // JSListFormat.prototype
3585     JSHandle<JSFunction> objFun(env->GetObjectFunction());
3586     JSHandle<JSObject> lfPrototype = factory_->NewJSObjectByConstructor(env, objFun);
3587     JSHandle<JSTaggedValue> lfPrototypeValue(lfPrototype);
3588 
3589     // JSListFormat.prototype_or_hclass
3590     JSHandle<JSHClass> lfFuncInstanceHClass =
3591         factory_->NewEcmaHClass(JSListFormat::SIZE, JSType::JS_LIST_FORMAT, lfPrototypeValue);
3592 
3593     // JSListFormat = new Function()
3594     // 13.4.1 Intl.ListFormat.prototype.constructor
3595     JSHandle<JSObject> lfFunction(NewIntlConstructor(env, lfPrototype, ListFormat::ListFormatConstructor,
3596                                                      "ListFormat", FunctionLength::ZERO));
3597     JSFunction::SetFunctionPrototypeOrInstanceHClass(thread_,
3598                                                      JSHandle<JSFunction>(lfFunction),
3599                                                      JSTaggedValue(*lfFuncInstanceHClass));
3600 
3601     // 13.3.2 Intl.ListFormat.supportedLocalesOf ( locales [ , options ] )
3602     SetFunction(env, lfFunction, "supportedLocalesOf", ListFormat::SupportedLocalesOf, FunctionLength::ONE);
3603 
3604     // ListFormat.prototype method
3605     // 13.4.2 Intl.ListFormat.prototype [ @@toStringTag ]
3606     SetStringTagSymbol(env, lfPrototype, "Intl.ListFormat");
3607     env->SetListFormatFunction(thread_, lfFunction);
3608 
3609     // 13.4.3 get Intl.ListFormat.prototype.format( list )
3610     SetFunction(env, lfPrototype, "format", ListFormat::Format, FunctionLength::ONE);
3611 
3612     // 13.4.4 Intl.ListFormat.prototype.formatToParts( list )
3613     SetFunction(env, lfPrototype, "formatToParts", ListFormat::FormatToParts, FunctionLength::ONE);
3614 
3615     // 13.4.5 Intl.ListFormat.prototype.resolvedOptions()
3616     SetFunction(env, lfPrototype, "resolvedOptions", ListFormat::ResolvedOptions, FunctionLength::ZERO);
3617 }
3618 
InitializeSegmenter(const JSHandle<GlobalEnv> & env)3619 void Builtins::InitializeSegmenter(const JSHandle<GlobalEnv> &env)
3620 {
3621     [[maybe_unused]] EcmaHandleScope scope(thread_);
3622     // Segmenter.prototype
3623     JSHandle<JSFunction> objFun(env->GetObjectFunction());
3624     JSHandle<JSObject> sgPrototype = factory_->NewJSObjectByConstructor(env, objFun);
3625     JSHandle<JSTaggedValue> sgPrototypeValue(sgPrototype);
3626 
3627     // Segmenter.prototype_or_hclass
3628     JSHandle<JSHClass> sgFuncInstanceHClass =
3629         factory_->NewEcmaHClass(JSSegmenter::SIZE, JSType::JS_SEGMENTER, sgPrototypeValue);
3630 
3631     // Segmenter = new Function()
3632     // 18.3.1 Intl.Segmenter.prototype.constructor
3633     JSHandle<JSObject> sgFunction(NewIntlConstructor(env, sgPrototype, Segmenter::SegmenterConstructor,
3634                                                      "Segmenter", FunctionLength::ZERO));
3635     JSFunction::SetFunctionPrototypeOrInstanceHClass(thread_,
3636                                                      JSHandle<JSFunction>(sgFunction),
3637                                                      sgFuncInstanceHClass.GetTaggedValue());
3638 
3639     // 18.2.2 Intl.Segmenter.supportedLocalesOf ( locales [ , options ] )
3640     SetFunction(env, sgFunction, "supportedLocalesOf", Segmenter::SupportedLocalesOf, FunctionLength::ONE);
3641 
3642     // Segmenter.prototype method
3643     // 18.3.2 Intl.Segmenter.prototype [ @@toStringTag ]
3644     SetStringTagSymbol(env, sgPrototype, "Intl.Segmenter");
3645     env->SetSegmenterFunction(thread_, sgFunction);
3646 
3647     // 18.3.4 Intl.Segmenter.prototype.resolvedOptions ( )
3648     SetFunction(env, sgPrototype, "resolvedOptions", Segmenter::ResolvedOptions, FunctionLength::ZERO);
3649 
3650     // 18.3.3 Intl.Segmenter.prototype.segment ( string )
3651     SetFunction(env, sgPrototype, "segment", Segmenter::Segment, FunctionLength::ONE);
3652 }
3653 
InitializeSegments(const JSHandle<GlobalEnv> & env)3654 void Builtins::InitializeSegments(const JSHandle<GlobalEnv> &env)
3655 {
3656     [[maybe_unused]] EcmaHandleScope scope(thread_);
3657     // Segments.prototype
3658     JSHandle<JSFunction> objFun(env->GetObjectFunction());
3659     JSHandle<JSObject> segmentsPrototype = factory_->NewJSObjectByConstructor(env, objFun);
3660     JSHandle<JSTaggedValue> segmentsPrototypeValue(segmentsPrototype);
3661 
3662     // Segments.prototype_or_hclass
3663     JSHandle<JSHClass> segmentsFuncInstanceHClass =
3664         factory_->NewEcmaHClass(JSSegments::SIZE, JSType::JS_SEGMENTS, segmentsPrototypeValue);
3665 
3666     JSHandle<JSFunction> segmentsFunction(
3667         factory_->NewJSBuiltinFunction(env, static_cast<void *>(nullptr), FunctionKind::BASE_CONSTRUCTOR));
3668     JSFunction::SetFunctionPrototypeOrInstanceHClass(thread_,
3669                                                      JSHandle<JSFunction>(segmentsFunction),
3670                                                      segmentsFuncInstanceHClass.GetTaggedValue());
3671 
3672     env->SetSegmentsFunction(thread_, segmentsFunction);
3673 
3674     // %SegmentsPrototype%.containing ( index )
3675     SetFunction(env, segmentsPrototype, "containing", Segments::Containing, FunctionLength::ONE);
3676     SetAndReturnFunctionAtSymbol(env, segmentsPrototype,
3677         env->GetIteratorSymbol(), "[Symbol.iterator]", Segments::GetSegmentIterator, FunctionLength::ZERO);
3678 }
3679 
InitializeSegmentIterator(const JSHandle<GlobalEnv> & env,const JSHandle<JSHClass> & iteratorFuncClass) const3680 void Builtins::InitializeSegmentIterator(const JSHandle<GlobalEnv> &env,
3681                                          const JSHandle<JSHClass> &iteratorFuncClass) const
3682 {
3683     // SegmentIterator.prototype
3684     JSHandle<JSObject> segIterPrototype(factory_->NewJSObjectWithInit(iteratorFuncClass));
3685 
3686     // SegmentIterator.prototype_or_hclass
3687     JSHandle<JSHClass> segIterFuncInstanceHClass = factory_->NewEcmaHClass(
3688         JSSegmentIterator::SIZE, JSType::JS_SEGMENT_ITERATOR, JSHandle<JSTaggedValue>(segIterPrototype));
3689 
3690     JSHandle<JSFunction> segIterFunction(
3691         factory_->NewJSBuiltinFunction(env, static_cast<void *>(nullptr), FunctionKind::BASE_CONSTRUCTOR));
3692     JSFunction::SetFunctionPrototypeOrInstanceHClass(thread_,
3693                                                      JSHandle<JSFunction>(segIterFunction),
3694                                                      segIterFuncInstanceHClass.GetTaggedValue());
3695 
3696     SetFunction(env, segIterPrototype, "next", SegmentIterator::Next, FunctionLength::ZERO);
3697     SetStringTagSymbol(env, segIterPrototype, "Segmenter String Iterator");
3698 
3699     env->SetSegmentIterator(thread_, segIterFunction);
3700     env->SetSegmentIteratorPrototype(thread_, segIterPrototype);
3701 }
3702 #endif // #ifdef ARK_SUPPORT_INTL
3703 
InitializeArkTools(const JSHandle<GlobalEnv> & env) const3704 JSHandle<JSObject> Builtins::InitializeArkTools(const JSHandle<GlobalEnv> &env) const
3705 {
3706     JSHandle<JSObject> tools = factory_->NewEmptyJSObject(env);
3707     for (const base::BuiltinFunctionEntry &entry: builtins::BuiltinsArkTools::GetArkToolsFunctions()) {
3708         SetFunction(env, tools, entry.GetName(), entry.GetEntrypoint(),
3709                     entry.GetLength(), entry.GetBuiltinStubId());
3710     }
3711     JSHandle<JSTaggedValue> gcBuiltins(InitializeGcBuiltins(env));
3712     SetConstantObject(tools, "GC", gcBuiltins);
3713     return tools;
3714 }
3715 
InitializeGcBuiltins(const JSHandle<GlobalEnv> & env) const3716 JSHandle<JSObject> Builtins::InitializeGcBuiltins(const JSHandle<GlobalEnv> &env) const
3717 {
3718     JSHandle<JSObject> builtins = factory_->NewEmptyJSObject(env);
3719     for (const base::BuiltinFunctionEntry &entry: builtins::BuiltinsGc::GetGcFunctions()) {
3720         SetFunction(env, builtins, entry.GetName(), entry.GetEntrypoint(),
3721                     entry.GetLength(), entry.GetBuiltinStubId());
3722     }
3723 
3724     for (const base::BuiltinFunctionEntry &entry: builtins::BuiltinsGc::GetGcFunctionsHybrid()) {
3725         SetFunction(env, builtins, entry.GetName(), entry.GetEntrypoint(),
3726                     entry.GetLength(), entry.GetBuiltinStubId());
3727     }
3728 
3729     return builtins;
3730 }
3731 
InitializeGlobalRegExp(JSHandle<JSObject> & obj) const3732 void Builtins::InitializeGlobalRegExp(JSHandle<JSObject> &obj) const
3733 {
3734     // $1
3735     auto accessor1 = factory_->NewInternalAccessor(reinterpret_cast<void *>(RegExp::SetCapture1),
3736                                                    reinterpret_cast<void *>(RegExp::GetCapture1));
3737     PropertyDescriptor descriptor1(thread_, JSHandle<JSTaggedValue>::Cast(accessor1), true, false, true);
3738     JSHandle<JSTaggedValue> dollar1Key = thread_->GlobalConstants()->GetHandledDollarStringOne();
3739     JSObject::DefineOwnProperty(thread_, obj, dollar1Key, descriptor1);
3740     // $2
3741     auto accessor2 = factory_->NewInternalAccessor(reinterpret_cast<void *>(RegExp::SetCapture2),
3742                                                    reinterpret_cast<void *>(RegExp::GetCapture2));
3743     PropertyDescriptor descriptor2(thread_, JSHandle<JSTaggedValue>::Cast(accessor2), true, false, true);
3744     JSHandle<JSTaggedValue> dollar2Key = thread_->GlobalConstants()->GetHandledDollarStringTwo();
3745     JSObject::DefineOwnProperty(thread_, obj, dollar2Key, descriptor2);
3746     // $3
3747     auto accessor3 = factory_->NewInternalAccessor(reinterpret_cast<void *>(RegExp::SetCapture3),
3748                                                    reinterpret_cast<void *>(RegExp::GetCapture3));
3749     PropertyDescriptor descriptor3(thread_, JSHandle<JSTaggedValue>::Cast(accessor3), true, false, true);
3750     JSHandle<JSTaggedValue> dollar3Key = thread_->GlobalConstants()->GetHandledDollarStringThree();
3751     JSObject::DefineOwnProperty(thread_, obj, dollar3Key, descriptor3);
3752     // $4
3753     auto accessor4 = factory_->NewInternalAccessor(reinterpret_cast<void *>(RegExp::SetCapture4),
3754                                                    reinterpret_cast<void *>(RegExp::GetCapture4));
3755     PropertyDescriptor descriptor4(thread_, JSHandle<JSTaggedValue>::Cast(accessor4), true, false, true);
3756     JSHandle<JSTaggedValue> dollar4Key = thread_->GlobalConstants()->GetHandledDollarStringFour();
3757     JSObject::DefineOwnProperty(thread_, obj, dollar4Key, descriptor4);
3758     // $5
3759     auto accessor5 = factory_->NewInternalAccessor(reinterpret_cast<void *>(RegExp::SetCapture5),
3760                                                    reinterpret_cast<void *>(RegExp::GetCapture5));
3761     PropertyDescriptor descriptor5(thread_, JSHandle<JSTaggedValue>::Cast(accessor5), true, false, true);
3762     JSHandle<JSTaggedValue> dollar5Key = thread_->GlobalConstants()->GetHandledDollarStringFive();
3763     JSObject::DefineOwnProperty(thread_, obj, dollar5Key, descriptor5);
3764     // $6
3765     auto accessor6 = factory_->NewInternalAccessor(reinterpret_cast<void *>(RegExp::SetCapture6),
3766                                                    reinterpret_cast<void *>(RegExp::GetCapture6));
3767     PropertyDescriptor descriptor6(thread_, JSHandle<JSTaggedValue>::Cast(accessor6), true, false, true);
3768     JSHandle<JSTaggedValue> dollar6Key = thread_->GlobalConstants()->GetHandledDollarStringSix();
3769     JSObject::DefineOwnProperty(thread_, obj, dollar6Key, descriptor6);
3770     // $7
3771     auto accessor7 = factory_->NewInternalAccessor(reinterpret_cast<void *>(RegExp::SetCapture7),
3772                                                    reinterpret_cast<void *>(RegExp::GetCapture7));
3773     PropertyDescriptor descriptor7(thread_, JSHandle<JSTaggedValue>::Cast(accessor7), true, false, true);
3774     JSHandle<JSTaggedValue> dollar7Key = thread_->GlobalConstants()->GetHandledDollarStringSeven();
3775     JSObject::DefineOwnProperty(thread_, obj, dollar7Key, descriptor7);
3776     // $8
3777     auto accessor8 = factory_->NewInternalAccessor(reinterpret_cast<void *>(RegExp::SetCapture8),
3778                                                    reinterpret_cast<void *>(RegExp::GetCapture8));
3779     PropertyDescriptor descriptor8(thread_, JSHandle<JSTaggedValue>::Cast(accessor8), true, false, true);
3780     JSHandle<JSTaggedValue> dollar8Key = thread_->GlobalConstants()->GetHandledDollarStringEight();
3781     JSObject::DefineOwnProperty(thread_, obj, dollar8Key, descriptor8);
3782     // $9
3783     auto accessor9 = factory_->NewInternalAccessor(reinterpret_cast<void *>(RegExp::SetCapture9),
3784                                                    reinterpret_cast<void *>(RegExp::GetCapture9));
3785     PropertyDescriptor descriptor9(thread_, JSHandle<JSTaggedValue>::Cast(accessor9), true, false, true);
3786     JSHandle<JSTaggedValue> dollar9Key = thread_->GlobalConstants()->GetHandledDollarStringNine();
3787     JSObject::DefineOwnProperty(thread_, obj, dollar9Key, descriptor9);
3788 }
3789 
InitializeArkPrivate(const JSHandle<GlobalEnv> & env) const3790 JSHandle<JSObject> Builtins::InitializeArkPrivate(const JSHandle<GlobalEnv> &env) const
3791 {
3792     JSHandle<JSObject> arkPrivate = factory_->NewEmptyJSObject(env);
3793     SetFrozenFunction(env, arkPrivate, "Load", ContainersPrivate::Load, FunctionLength::ZERO);
3794 
3795     // It is used to provide non ECMA standard jsapi containers.
3796     SetConstant(arkPrivate, "ArrayList", JSTaggedValue(static_cast<int>(containers::ContainerTag::ArrayList)));
3797     SetConstant(arkPrivate, "Queue", JSTaggedValue(static_cast<int>(containers::ContainerTag::Queue)));
3798     SetConstant(arkPrivate, "Deque", JSTaggedValue(static_cast<int>(containers::ContainerTag::Deque)));
3799     SetConstant(arkPrivate, "Stack", JSTaggedValue(static_cast<int>(containers::ContainerTag::Stack)));
3800     SetConstant(arkPrivate, "Vector", JSTaggedValue(static_cast<int>(containers::ContainerTag::Vector)));
3801     SetConstant(arkPrivate, "BitVector", JSTaggedValue(static_cast<int>(containers::ContainerTag::BitVector)));
3802     SetConstant(arkPrivate, "List", JSTaggedValue(static_cast<int>(containers::ContainerTag::List)));
3803     SetConstant(arkPrivate, "LinkedList", JSTaggedValue(static_cast<int>(containers::ContainerTag::LinkedList)));
3804     SetConstant(arkPrivate, "TreeMap", JSTaggedValue(static_cast<int>(containers::ContainerTag::TreeMap)));
3805     SetConstant(arkPrivate, "TreeSet", JSTaggedValue(static_cast<int>(containers::ContainerTag::TreeSet)));
3806     SetConstant(arkPrivate, "HashMap", JSTaggedValue(static_cast<int>(containers::ContainerTag::HashMap)));
3807     SetConstant(arkPrivate, "HashSet", JSTaggedValue(static_cast<int>(containers::ContainerTag::HashSet)));
3808     SetConstant(arkPrivate, "LightWeightMap",
3809                 JSTaggedValue(static_cast<int>(containers::ContainerTag::LightWeightMap)));
3810     SetConstant(arkPrivate, "LightWeightSet",
3811                 JSTaggedValue(static_cast<int>(containers::ContainerTag::LightWeightSet)));
3812     SetConstant(arkPrivate, "PlainArray", JSTaggedValue(static_cast<int>(containers::ContainerTag::PlainArray)));
3813     SetConstant(arkPrivate, "FastBuffer", JSTaggedValue(static_cast<int>(containers::ContainerTag::FastBuffer)));
3814     return arkPrivate;
3815 }
3816 
InitializeModuleNamespace(const JSHandle<GlobalEnv> & env,const JSHandle<JSHClass> & objFuncClass) const3817 void Builtins::InitializeModuleNamespace(const JSHandle<GlobalEnv> &env,
3818                                          const JSHandle<JSHClass> &objFuncClass) const
3819 {
3820     [[maybe_unused]] EcmaHandleScope scope(thread_);
3821     // ModuleNamespace.prototype
3822     JSHandle<JSObject> moduleNamespacePrototype = factory_->NewJSObjectWithInit(objFuncClass);
3823     JSHandle<JSTaggedValue> moduleNamespacePrototypeValue(moduleNamespacePrototype);
3824 
3825     //  ModuleNamespace.prototype_or_hclass
3826     JSHandle<JSHClass> moduleNamespaceHClass =
3827         factory_->NewEcmaHClass(ModuleNamespace::SIZE, JSType::JS_MODULE_NAMESPACE, moduleNamespacePrototypeValue);
3828     moduleNamespaceHClass->SetPrototype(thread_, JSTaggedValue::Null());
3829     env->SetModuleNamespaceClass(thread_, moduleNamespaceHClass.GetTaggedValue());
3830 
3831     // moduleNamespace.prototype [ @@toStringTag ]
3832     SetStringTagSymbol(env, moduleNamespacePrototype, "Module");
3833 }
3834 
InitializeNativeModuleFailureInfo(const JSHandle<GlobalEnv> & env,const JSHandle<JSHClass> & objFuncClass) const3835 void Builtins::InitializeNativeModuleFailureInfo(const JSHandle<GlobalEnv> &env,
3836                                                  const JSHandle<JSHClass> &objFuncClass) const
3837 {
3838     [[maybe_unused]] EcmaHandleScope scope(thread_);
3839     // NativeModuleFailureInfo.prototype
3840     JSHandle<JSObject> nativeModuleFailureInfoPrototype = factory_->NewJSObjectWithInit(objFuncClass);
3841     JSHandle<JSTaggedValue> nativeModuleFailureInfoPrototypeValue(nativeModuleFailureInfoPrototype);
3842 
3843     // NativeModuleFailureInfo.prototype_or_hclass
3844     JSHandle<JSHClass> nativeModuleFailureInfoHClass =
3845         factory_->NewEcmaHClass(NativeModuleFailureInfo::SIZE, JSType::NATIVE_MODULE_FAILURE_INFO,
3846             nativeModuleFailureInfoPrototypeValue);
3847     nativeModuleFailureInfoHClass->SetPrototype(thread_, JSTaggedValue::Null());
3848     env->SetNativeModuleFailureInfoClass(thread_, nativeModuleFailureInfoHClass.GetTaggedValue());
3849 }
3850 
InitializeCjsModule(const JSHandle<GlobalEnv> & env) const3851 void Builtins::InitializeCjsModule(const JSHandle<GlobalEnv> &env) const
3852 {
3853     [[maybe_unused]] EcmaHandleScope scope(thread_);
3854     // CjsModule.prototype
3855     JSHandle<JSFunction> objFun(env->GetObjectFunction());
3856     JSHandle<JSObject> cjsModulePrototype = factory_->NewJSObjectByConstructor(env, objFun);
3857     JSHandle<JSTaggedValue> cjsModulePrototypeValue(cjsModulePrototype);
3858 
3859     // CjsModule.prototype_or_hclass
3860     JSHandle<JSHClass> cjsModuleHClass =
3861         factory_->NewEcmaHClass(CjsModule::SIZE, JSType::JS_CJS_MODULE, cjsModulePrototypeValue);
3862 
3863     // CjsModule.prototype.Constructor
3864     JSHandle<JSObject> cjsModuleFunction(
3865         NewBuiltinCjsCtor(env, cjsModulePrototype, BuiltinsCjsModule::CjsModuleConstructor, "Module",
3866                           FunctionLength::TWO));
3867 
3868     JSFunction::SetFunctionPrototypeOrInstanceHClass(thread_,
3869                                                      JSHandle<JSFunction>(cjsModuleFunction),
3870                                                      cjsModuleHClass.GetTaggedValue());
3871 
3872     // CjsModule method
3873     SetFunction(env, cjsModuleFunction, "_load", BuiltinsCjsModule::Load, FunctionLength::ONE);
3874     SetFunction(env, cjsModuleFunction, "_resolveFilename", BuiltinsCjsModule::ResolveFilename, FunctionLength::ONE);
3875 
3876     // CjsModule.prototype method
3877     SetFunction(env, cjsModulePrototype, "require", BuiltinsCjsModule::Require, FunctionLength::ONE);
3878     SetFunction(env, cjsModulePrototype, "getExportsForCircularRequire",
3879                 BuiltinsCjsModule::GetExportsForCircularRequire, FunctionLength::ONE);
3880     SetFunction(env, cjsModulePrototype, "updateChildren", BuiltinsCjsModule::UpdateChildren, FunctionLength::ONE);
3881 
3882     JSHandle<JSTaggedValue> id(thread_->GlobalConstants()->GetHandledEmptyString());
3883     JSHandle<JSTaggedValue> path(thread_->GlobalConstants()->GetHandledEmptyString());
3884     JSHandle<JSTaggedValue> exports(factory_->NewEmptyJSObject(env));
3885     JSHandle<JSTaggedValue> parent(factory_->NewEmptyJSObject(env));
3886     JSHandle<JSTaggedValue> filename(thread_->GlobalConstants()->GetHandledEmptyString());
3887     JSHandle<JSTaggedValue> loaded(factory_->NewEmptyJSObject(env));
3888     JSHandle<JSTaggedValue> children(factory_->NewEmptyJSObject(env));
3889     JSHandle<JSTaggedValue> cache = JSHandle<JSTaggedValue>::Cast(CjsModuleCache::Create(thread_,
3890         CjsModuleCache::DEAULT_DICTIONART_CAPACITY));
3891 
3892     // CjsModule.prototype members
3893     SetNonConstantObject(cjsModulePrototype, "id", id);
3894     SetNonConstantObject(cjsModulePrototype, "path", path);
3895     SetNonConstantObject(cjsModulePrototype, "exports", exports);
3896     SetNonConstantObject(cjsModulePrototype, "parent", parent);
3897     SetNonConstantObject(cjsModulePrototype, "filename", filename);
3898     SetNonConstantObject(cjsModulePrototype, "loaded", loaded);
3899     SetNonConstantObject(cjsModulePrototype, "children", children);
3900 
3901     // CjsModule members
3902     SetNonConstantObject(cjsModuleFunction, "_cache", cache);
3903 
3904     env->SetCjsModuleFunction(thread_, cjsModuleFunction);
3905 }
3906 
InitializeCjsExports(const JSHandle<GlobalEnv> & env) const3907 void Builtins::InitializeCjsExports(const JSHandle<GlobalEnv> &env) const
3908 {
3909     [[maybe_unused]] EcmaHandleScope scope(thread_);
3910 
3911     // CjsExports.prototype
3912     JSHandle<JSFunction> objFun(env->GetObjectFunction());
3913     JSHandle<JSObject> cjsExportsPrototype = factory_->NewJSObjectByConstructor(env, objFun);
3914     JSHandle<JSTaggedValue> cjsExportsPrototypeValue(cjsExportsPrototype);
3915 
3916     // CjsExports.prototype_or_hclass
3917     JSHandle<JSHClass> cjsExportsHClass =
3918         factory_->NewEcmaHClass(CjsExports::SIZE, JSType::JS_CJS_EXPORTS, cjsExportsPrototypeValue);
3919 
3920     // CjsExports.prototype.Constructor
3921     JSHandle<JSObject> cjsExportsFunction(
3922         NewBuiltinCjsCtor(env, cjsExportsPrototype, BuiltinsCjsExports::CjsExportsConstructor, "Exports",
3923                           FunctionLength::TWO));
3924 
3925     JSFunction::SetFunctionPrototypeOrInstanceHClass(thread_,
3926                                                      JSHandle<JSFunction>(cjsExportsFunction),
3927                                                      cjsExportsHClass.GetTaggedValue());
3928 
3929     env->SetCjsExportsFunction(thread_, cjsExportsFunction);
3930 }
3931 
InitializeCjsRequire(const JSHandle<GlobalEnv> & env) const3932 void Builtins::InitializeCjsRequire(const JSHandle<GlobalEnv> &env) const
3933 {
3934     [[maybe_unused]] EcmaHandleScope scope(thread_);
3935     // CjsRequire.prototype
3936     JSHandle<JSFunction> objFun(env->GetObjectFunction());
3937     JSHandle<JSObject> cjsRequirePrototype = factory_->NewJSObjectByConstructor(env, objFun);
3938     JSHandle<JSTaggedValue> cjsRequirePrototypeValue(cjsRequirePrototype);
3939 
3940     // CjsExports.prototype_or_hclass
3941     JSHandle<JSHClass> cjsRequireHClass =
3942         factory_->NewEcmaHClass(CjsRequire::SIZE, JSType::JS_CJS_REQUIRE, cjsRequirePrototypeValue);
3943 
3944     // CjsExports.prototype.Constructor
3945     JSHandle<JSFunction> cjsRequireFunction =
3946         NewBuiltinCjsCtor(env, cjsRequirePrototype, BuiltinsCjsRequire::CjsRequireConstructor, "require",
3947                           FunctionLength::ONE);
3948     JSFunction::SetFunctionPrototypeOrInstanceHClass(thread_,
3949                                                      JSHandle<JSFunction>(cjsRequireFunction),
3950                                                      cjsRequireHClass.GetTaggedValue());
3951 
3952     // CjsModule.prototype method
3953     SetFunction(env, cjsRequirePrototype, "Main", BuiltinsCjsRequire::Main, FunctionLength::ONE);
3954 
3955     env->SetCjsRequireFunction(thread_, cjsRequireFunction);
3956 }
3957 
InitializeDefaultExportOfScript(const JSHandle<GlobalEnv> & env) const3958 void Builtins::InitializeDefaultExportOfScript(const JSHandle<GlobalEnv> &env) const
3959 {
3960     JSHandle<JSFunction> builtinObj(env->GetObjectFunction());
3961     JSHandle<JSTaggedValue> emptyObj(factory_->NewJSObjectByConstructor(env, builtinObj));
3962     JSHandle<JSTaggedValue> defaultKey(factory_->NewFromUtf8ReadOnly("default"));
3963 
3964     JSHandle<TaggedArray> props(factory_->NewTaggedArray(2)); // 2 : two propertise
3965     props->Set(thread_, 0, defaultKey);
3966     props->Set(thread_, 1, emptyObj);
3967     JSHandle<JSHClass> hclass = factory_->CreateObjectClass(env, props, 1);
3968     JSHandle<JSObject> obj = factory_->NewJSObject(hclass);
3969     obj->SetPropertyInlinedProps(thread_, 0, props->Get(thread_, 1));
3970     env->SetExportOfScript(thread_, obj);
3971     return;
3972 }
3973 
CreateArrayUnscopables(JSThread * thread) const3974 JSHandle<JSTaggedValue> Builtins::CreateArrayUnscopables(JSThread *thread) const
3975 {
3976     ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
3977     const GlobalEnvConstants *globalConst = thread->GlobalConstants();
3978 
3979     JSHandle<JSObject> unscopableList = factory->CreateNullJSObject();
3980 
3981     JSHandle<JSTaggedValue> trueVal(thread, JSTaggedValue::True());
3982 
3983     JSHandle<JSTaggedValue> atKey((factory->NewFromASCIIReadOnly("at")));
3984     JSObject::CreateDataProperty(thread, unscopableList, atKey, trueVal);
3985 
3986     JSHandle<JSTaggedValue> copyWithKey = globalConst->GetHandledCopyWithinString();
3987     JSObject::CreateDataProperty(thread, unscopableList, copyWithKey, trueVal);
3988 
3989     JSHandle<JSTaggedValue> entriesKey = globalConst->GetHandledEntriesString();
3990     JSObject::CreateDataProperty(thread, unscopableList, entriesKey, trueVal);
3991 
3992     JSHandle<JSTaggedValue> fillKey = globalConst->GetHandledFillString();
3993     JSObject::CreateDataProperty(thread, unscopableList, fillKey, trueVal);
3994 
3995     JSHandle<JSTaggedValue> findKey = globalConst->GetHandledFindString();
3996     JSObject::CreateDataProperty(thread, unscopableList, findKey, trueVal);
3997 
3998     JSHandle<JSTaggedValue> findIndexKey = globalConst->GetHandledFindIndexString();
3999     JSObject::CreateDataProperty(thread, unscopableList, findIndexKey, trueVal);
4000 
4001     JSHandle<JSTaggedValue> findLastKey((factory->NewFromASCIIReadOnly("findLast")));
4002     JSObject::CreateDataProperty(thread, unscopableList, findLastKey, trueVal);
4003 
4004     JSHandle<JSTaggedValue> findLastIndexKey((factory->NewFromASCIIReadOnly("findLastIndex")));
4005     JSObject::CreateDataProperty(thread, unscopableList, findLastIndexKey, trueVal);
4006 
4007     JSHandle<JSTaggedValue> flatKey = globalConst->GetHandledFlatString();
4008     JSObject::CreateDataProperty(thread, unscopableList, flatKey, trueVal);
4009 
4010     JSHandle<JSTaggedValue> flatMapKey = globalConst->GetHandledFlatMapString();
4011     JSObject::CreateDataProperty(thread, unscopableList, flatMapKey, trueVal);
4012 
4013     JSHandle<JSTaggedValue> includesKey = globalConst->GetHandledIncludesString();
4014     JSObject::CreateDataProperty(thread, unscopableList, includesKey, trueVal);
4015 
4016     JSHandle<JSTaggedValue> keysKey = globalConst->GetHandledKeysString();
4017     JSObject::CreateDataProperty(thread, unscopableList, keysKey, trueVal);
4018 
4019     JSHandle<JSTaggedValue> valuesKey = globalConst->GetHandledValuesString();
4020     JSObject::CreateDataProperty(thread, unscopableList, valuesKey, trueVal);
4021 
4022     JSHandle<JSTaggedValue> toReversedKey((factory->NewFromASCIIReadOnly("toReversed")));
4023     JSObject::CreateDataProperty(thread, unscopableList, toReversedKey, trueVal);
4024 
4025     JSHandle<JSTaggedValue> toSortedKey((factory->NewFromASCIIReadOnly("toSorted")));
4026     JSObject::CreateDataProperty(thread, unscopableList, toSortedKey, trueVal);
4027 
4028     JSHandle<JSTaggedValue> toSplicedKey((factory->NewFromASCIIReadOnly("toSpliced")));
4029     JSObject::CreateDataProperty(thread, unscopableList, toSplicedKey, trueVal);
4030     return JSHandle<JSTaggedValue>::Cast(unscopableList);
4031 }
4032 
RegisterSendableContainers(const JSHandle<GlobalEnv> & env) const4033 void Builtins::RegisterSendableContainers(const JSHandle<GlobalEnv> &env) const
4034 {
4035     auto globalObject = JSHandle<JSObject>::Cast(env->GetJSGlobalObject());
4036     {
4037         JSHandle<JSTaggedValue> nameString(factory_->NewFromUtf8ReadOnly("SendableMap"));
4038         PropertyDescriptor desc(thread_, env->GetSBuiltininMapFunction(), true, false, true);
4039         JSObject::DefineOwnProperty(thread_, globalObject, nameString, desc);
4040     }
4041     {
4042         JSHandle<JSTaggedValue> nameString(factory_->NewFromUtf8ReadOnly("SendableSet"));
4043         PropertyDescriptor desc(thread_, env->GetSBuiltininSetFunction(), true, false, true);
4044         JSObject::DefineOwnProperty(thread_, globalObject, nameString, desc);
4045     }
4046     {
4047         JSHandle<JSTaggedValue> nameString(factory_->NewFromUtf8ReadOnly("SendableArray"));
4048         PropertyDescriptor desc(thread_, env->GetSharedArrayFunction(), true, false, true);
4049         JSObject::DefineOwnProperty(thread_, globalObject, nameString, desc);
4050     }
4051     {
4052         JSHandle<JSTaggedValue> nameString(factory_->NewFromUtf8ReadOnly("SendableArrayBuffer"));
4053         PropertyDescriptor desc(thread_, env->GetSBuiltininArrayBufferFunction(), true, false, true);
4054         JSObject::DefineOwnProperty(thread_, globalObject, nameString, desc);
4055     }
4056 // todo: remove sendableName when refactor
4057 #define REGISTER_BUILTIN_SHARED_TYPED_ARRAY(Type, ctorName, TYPE, bytesPerElement, sendableName)           \
4058     {                                                                                        \
4059         JSHandle<JSTaggedValue> nameString(factory_->NewFromUtf8ReadOnly(#sendableName));    \
4060         PropertyDescriptor desc(thread_, env->Get##ctorName##Function(), true, false, true); \
4061         JSObject::DefineOwnProperty(thread_, globalObject, nameString, desc);                \
4062     }
4063     BUILTIN_SHARED_TYPED_ARRAY_TYPES(REGISTER_BUILTIN_SHARED_TYPED_ARRAY)
4064 #undef REGISTER_BUILTIN_SHARED_TYPED_ARRAY
4065 }
4066 }  // namespace panda::ecmascript
4067