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