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