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