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