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