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