1/*
2 * Copyright (c) 2023-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_function.h"
19#include "ecmascript/builtins/builtins_object.h"
20#include "ecmascript/builtins/builtins_symbol.h"
21#include "ecmascript/builtins/builtins_sendable_arraybuffer.h"
22#include "ecmascript/builtins/builtins_shared_async_function.h"
23#include "ecmascript/builtins/builtins_shared_function.h"
24#include "ecmascript/builtins/builtins_shared_object.h"
25#include "ecmascript/builtins/builtins_shared_map.h"
26#include "ecmascript/builtins/builtins_shared_set.h"
27#include "ecmascript/builtins/builtins_shared_typedarray.h"
28#include "ecmascript/shared_objects/js_shared_array.h"
29#include "ecmascript/shared_objects/js_sendable_arraybuffer.h"
30#include "ecmascript/shared_objects/js_shared_map.h"
31#include "ecmascript/shared_objects/js_shared_set.h"
32#include "ecmascript/shared_objects/js_shared_typed_array.h"
33#include "ecmascript/js_async_function.h"
34#include "ecmascript/js_object-inl.h"
35#include "ecmascript/symbol_table.h"
36#include "ecmascript/builtins/builtins_shared_array.h"
37
38namespace panda::ecmascript {
39using BuiltinsSharedObject = builtins::BuiltinsSharedObject;
40using BuiltinsSharedFunction = builtins::BuiltinsSharedFunction;
41using BuiltinsSharedAsyncFunction = builtins::BuiltinsSharedAsyncFunction;
42using Function = builtins::BuiltinsFunction;
43using Object = builtins::BuiltinsObject;
44using BuiltinsSharedSet = builtins::BuiltinsSharedSet;
45using BuiltinsSharedMap = builtins::BuiltinsSharedMap;
46using BuiltinsSharedArray = builtins::BuiltinsSharedArray;
47using BuiltinsSharedTypedArray = builtins::BuiltinsSharedTypedArray;
48using BuiltinsSendableArrayBuffer = builtins::BuiltinsSendableArrayBuffer;
49
50void Builtins::InitializeSObjectAndSFunction(const JSHandle<GlobalEnv> &env) const
51{
52    [[maybe_unused]] EcmaHandleScope scope(thread_);
53    // SharedObject.prototype[hclass]
54    JSHandle<JSHClass> sobjPrototypeHClass = CreateSObjectPrototypeHClass();
55    // SharedObject.prototype
56    JSHandle<JSObject> sObjPrototype =
57        factory_->NewSharedOldSpaceJSObject(sobjPrototypeHClass);
58    JSHandle<JSTaggedValue> sObjPrototypeVal(sObjPrototype);
59    // SharedObject.prototype_or_hclass
60    auto emptySLayout = thread_->GlobalConstants()->GetHandledEmptySLayoutInfo();
61    JSHandle<JSHClass> sObjIHClass =
62        factory_->NewSEcmaHClass(JSSharedObject::SIZE, 0, JSType::JS_SHARED_OBJECT, sObjPrototypeVal,
63                                 emptySLayout);
64    // SharedFunction.prototype_or_hclass
65    JSHandle<JSHClass> sFuncPrototypeHClass = CreateSFunctionPrototypeHClass(sObjPrototypeVal);
66    // SharedFunction.prototype
67    JSHandle<JSFunction> sFuncPrototype = factory_->NewSFunctionByHClass(
68        reinterpret_cast<void *>(Function::FunctionPrototypeInvokeSelf), sFuncPrototypeHClass,
69        FunctionKind::NORMAL_FUNCTION);
70    InitializeSFunction(env, sFuncPrototype);
71    InitializeSAsyncFunction(env, sObjIHClass);
72    InitializeSObject(env, sObjIHClass, sObjPrototype, sFuncPrototype);
73    InitializeSSet(env, sObjPrototype, sFuncPrototype);
74    InitializeSMap(env, sObjPrototype, sFuncPrototype);
75    InitializeSharedArray(env, sObjPrototype, sFuncPrototype);
76    InitializeSTypedArray(env, sObjPrototype, sFuncPrototype);
77    InitializeSArrayBuffer(env, sObjPrototype, sFuncPrototype);
78    InitializeSModuleNamespace(env, sObjIHClass);
79    env->SetSObjectFunctionPrototype(thread_, sObjPrototype);
80}
81
82void Builtins::CopySObjectAndSFunction(const JSHandle<GlobalEnv> &env, const JSTaggedValue &srcEnv) const
83{
84    // Copy shareds.
85    ASSERT(srcEnv.IsJSGlobalEnv());
86    auto sGlobalEnv = reinterpret_cast<GlobalEnv*>(srcEnv.GetTaggedObject());
87#define COPY_ENV_SHARED_FIELDS(Type, Name, INDEX)    \
88    env->Set##Name(thread_, sGlobalEnv->Get##Name());
89    GLOBAL_ENV_SHARED_FIELDS(COPY_ENV_SHARED_FIELDS)
90#undef COPY_ENV_SHARED_FIELDS
91}
92
93void Builtins::InitializeSObject(const JSHandle<GlobalEnv> &env, const JSHandle<JSHClass> &sObjIHClass,
94                                 const JSHandle<JSObject> &sObjPrototype,
95                                 const JSHandle<JSFunction> &sFuncPrototype) const
96{
97    [[maybe_unused]] EcmaHandleScope scope(thread_);
98    // SharedObject constructor (forbidden use NewBuiltinConstructor)
99    JSHandle<JSHClass> sObjectFunctionHClass = CreateSObjectFunctionHClass(sFuncPrototype);
100    JSHandle<JSFunction> sObjectFunction =
101        factory_->NewSFunctionByHClass(reinterpret_cast<void *>(BuiltinsSharedObject::SharedObjectConstructor),
102                                       sObjectFunctionHClass, FunctionKind::BUILTIN_CONSTRUCTOR);
103
104    InitializeSCtor(sObjIHClass, sObjectFunction, "SharedObject", FunctionLength::ONE);
105    env->SetSObjectFunction(thread_, sObjectFunction);
106    // sObject method.
107    uint32_t fieldIndex = JSFunction::PROTOTYPE_INLINE_PROPERTY_INDEX + 1;
108    for (const base::BuiltinFunctionEntry &entry : Object::GetObjectFunctions()) {
109        SetSFunction(env, JSHandle<JSObject>(sObjectFunction), entry.GetName(), entry.GetEntrypoint(),
110                     fieldIndex++, entry.GetLength(), entry.GetBuiltinStubId());
111    }
112    // sObject.prototype method
113    fieldIndex = 0; // constructor
114    sObjPrototype->SetPropertyInlinedProps(thread_, fieldIndex++, sObjectFunction.GetTaggedValue());
115    for (const base::BuiltinFunctionEntry &entry : Object::GetObjectPrototypeFunctions()) {
116        SetSFunction(env, sObjPrototype, entry.GetName(), entry.GetEntrypoint(), fieldIndex++, entry.GetLength(),
117                     entry.GetBuiltinStubId());
118    }
119    // B.2.2.1 sObject.prototype.__proto__
120    JSHandle<JSTaggedValue> protoGetter =
121        CreateSGetterSetter(env, Object::ProtoGetter, "__proto__", FunctionLength::ZERO);
122    JSHandle<JSTaggedValue> protoSetter =
123        CreateSGetterSetter(env, Object::ProtoSetter, "__proto__", FunctionLength::ONE);
124    SetSAccessor(sObjPrototype, fieldIndex, protoGetter, protoSetter);
125}
126
127void Builtins::InitializeSArrayBuffer(const JSHandle<GlobalEnv> &env, const JSHandle<JSObject> &sObjPrototype,
128    const JSHandle<JSFunction> &sFuncPrototype) const
129{
130    [[maybe_unused]] EcmaHandleScope scope(thread_);
131    const GlobalEnvConstants *globalConst = thread_->GlobalConstants();
132    // SendableArrayBuffer.prototype
133    JSHandle<JSHClass> arrayBufferPrototypeHClass = CreateSArrayBufferPrototypeHClass(sObjPrototype);
134    JSHandle<JSObject> arrayBufferPrototype =
135        factory_->NewSharedOldSpaceJSObjectWithInit(arrayBufferPrototypeHClass);
136
137    JSHandle<JSTaggedValue> arrayBufferPrototypeValue(arrayBufferPrototype);
138
139    // SendableArrayBuffer.prototype_or_hclass
140    auto emptySLayout = globalConst->GetHandledEmptySLayoutInfo();
141    JSHandle<JSHClass> arrayBufferIHClass = factory_->NewSEcmaHClass(
142        JSSendableArrayBuffer::SIZE, 0, JSType::JS_SENDABLE_ARRAY_BUFFER, arrayBufferPrototypeValue, emptySLayout);
143
144    // SendableArrayBuffer = new Function()
145    JSHandle<JSHClass> arrayBufferFuncHClass = CreateSArrayBufferFunctionHClass(sFuncPrototype);
146
147    JSHandle<JSFunction> arrayBufferFunction =
148        factory_->NewSFunctionByHClass(reinterpret_cast<void *>(BuiltinsSendableArrayBuffer::ArrayBufferConstructor),
149                                       arrayBufferFuncHClass, FunctionKind::BUILTIN_CONSTRUCTOR);
150
151    InitializeSCtor(arrayBufferIHClass, arrayBufferFunction, "SendableArrayBuffer", FunctionLength::ONE);
152    JSHandle<JSObject> globalObject(thread_, env->GetGlobalObject());
153    JSHandle<JSTaggedValue> nameString(factory_->NewFromUtf8ReadOnly("SendableArrayBuffer"));
154    PropertyDescriptor desc(thread_, JSHandle<JSTaggedValue>::Cast(arrayBufferFunction), true, false, true);
155    JSObject::DefineOwnProperty(thread_, globalObject, nameString, desc);
156    RETURN_IF_ABRUPT_COMPLETION(thread_);
157
158    // SendableArrayBuffer prototype method
159    uint32_t fieldIndex = 0;
160    SetSFunction(env, arrayBufferPrototype, "slice",
161        BuiltinsSendableArrayBuffer::Slice, fieldIndex++, FunctionLength::TWO);
162
163    // 24.1.4.1 get SendableArrayBuffer.prototype.byteLength
164    JSHandle<JSTaggedValue> lengthGetter =
165        CreateSGetterSetter(env, BuiltinsSendableArrayBuffer::GetByteLength, "byteLength", FunctionLength::ZERO);
166    SetSAccessor(
167        JSHandle<JSObject>(arrayBufferPrototype), fieldIndex++, lengthGetter, globalConst->GetHandledUndefined());
168
169    // 24.1.4.4 SendableArrayBuffer.prototype[@@toStringTag]
170    JSHandle<JSTaggedValue> strTag(factory_->NewFromUtf8ReadOnly("SendableArrayBuffer"));
171    arrayBufferPrototype->SetPropertyInlinedProps(thread_, fieldIndex++, strTag.GetTaggedValue());
172
173    // 24.1.3.3 get SendableArrayBuffer[@@species]
174    fieldIndex = JSFunction::PROTOTYPE_INLINE_PROPERTY_INDEX + 1;
175    JSHandle<JSTaggedValue> speciesGetter =
176        CreateSGetterSetter(env, BuiltinsSendableArrayBuffer::Species, "[Symbol.species]", FunctionLength::ZERO);
177    SetSAccessor(
178        JSHandle<JSObject>(arrayBufferFunction), fieldIndex++, speciesGetter, globalConst->GetHandledUndefined());
179
180    // SendableArrayBuffer method
181    for (const base::BuiltinFunctionEntry& entry: BuiltinsSendableArrayBuffer::GetArrayBufferFunctions()) {
182        SetSFunction(env, JSHandle<JSObject>(arrayBufferFunction), entry.GetName(), entry.GetEntrypoint(), fieldIndex++,
183                     entry.GetLength(), entry.GetBuiltinStubId());
184    }
185
186    env->SetSendableArrayBufferPrototype(thread_, arrayBufferPrototype);
187    env->SetSBuiltininArrayBufferFunction(thread_, arrayBufferFunction);
188}
189
190void Builtins::InitializeSSet(const JSHandle<GlobalEnv> &env, const JSHandle<JSObject> &sObjPrototype,
191    const JSHandle<JSFunction> &sFuncPrototype) const
192{
193    [[maybe_unused]] EcmaHandleScope scope(thread_);
194    const GlobalEnvConstants *globalConst = thread_->GlobalConstants();
195    // SharedSet.prototype
196    JSHandle<JSHClass> setPrototypeHClass = CreateSSetPrototypeHClass(sObjPrototype);
197    JSHandle<JSObject> setPrototype =
198        factory_->NewSharedOldSpaceJSObjectWithInit(setPrototypeHClass);
199
200    JSHandle<JSTaggedValue> setPrototypeValue(setPrototype);
201    // SharedSet.prototype_or_hclass
202    auto emptySLayout = globalConst->GetHandledEmptySLayoutInfo();
203    JSHandle<JSHClass> setIHClass =
204        factory_->NewSEcmaHClass(JSSharedSet::SIZE, 0, JSType::JS_SHARED_SET, setPrototypeValue, emptySLayout);
205    // SharedSet.hclass
206    JSHandle<JSHClass> setFuncHClass = CreateSSetFunctionHClass(sFuncPrototype);
207    // SharedSet() = new Function()
208    JSHandle<JSFunction> setFunction =
209        factory_->NewSFunctionByHClass(reinterpret_cast<void *>(BuiltinsSharedSet::Constructor),
210                                       setFuncHClass, FunctionKind::BUILTIN_CONSTRUCTOR);
211
212    InitializeSCtor(setIHClass, setFunction, "SendableSet", FunctionLength::ZERO);
213    JSHandle<JSObject> globalObject(thread_, env->GetGlobalObject());
214    JSHandle<JSTaggedValue> nameString(factory_->NewFromUtf8ReadOnly("SendableSet"));
215    PropertyDescriptor desc(thread_, JSHandle<JSTaggedValue>::Cast(setFunction), true, false, true);
216    JSObject::DefineOwnProperty(thread_, globalObject, nameString, desc);
217    RETURN_IF_ABRUPT_COMPLETION(thread_);
218
219    // "constructor" property on the prototype
220    uint32_t fieldIndex = 0; // constructor
221    setPrototype->SetPropertyInlinedProps(thread_, fieldIndex++, setFunction.GetTaggedValue());
222
223    // SharedSet.prototype functions, excluding keys()
224    for (const base::BuiltinFunctionEntry &entry: BuiltinsSharedSet::GetSetPrototypeFunctions()) {
225        SetSFunction(env, setPrototype, entry.GetName(), entry.GetEntrypoint(), fieldIndex++,
226        entry.GetLength(), entry.GetBuiltinStubId());
227    }
228    // SharedSet.prototype.keys, which is strictly equal to Set.prototype.values
229    JSHandle<JSTaggedValue> keys(factory_->NewFromASCIIReadOnly("keys"));
230    JSHandle<JSTaggedValue> values(factory_->NewFromASCIIReadOnly("values"));
231    JSHandle<JSTaggedValue> valuesFunc =
232        JSObject::GetMethod(thread_, JSHandle<JSTaggedValue>::Cast(setPrototype), values);
233    RETURN_IF_ABRUPT_COMPLETION(thread_);
234    setPrototype->SetPropertyInlinedProps(thread_, fieldIndex++, valuesFunc.GetTaggedValue());
235
236    // @@ToStringTag
237    JSHandle<JSTaggedValue> strTag(factory_->NewFromUtf8ReadOnly("SendableSet"));
238    setPrototype->SetPropertyInlinedProps(thread_, fieldIndex++, strTag.GetTaggedValue());
239
240    // 23.1.3.10get SharedSet.prototype.size
241    JSHandle<JSTaggedValue> sizeGetter = CreateSGetterSetter(env, BuiltinsSharedSet::GetSize, "size",
242        FunctionLength::ZERO);
243    SetSAccessor(setPrototype, fieldIndex++, sizeGetter, globalConst->GetHandledUndefined());
244
245    // %SetPrototype% [ @@iterator ]
246    setPrototype->SetPropertyInlinedProps(thread_, fieldIndex++, valuesFunc.GetTaggedValue());
247
248    fieldIndex = JSFunction::PROTOTYPE_INLINE_PROPERTY_INDEX + 1;
249    // 23.1.2.2get SharedSet [ @@species ]
250    JSHandle<JSTaggedValue> speciesGetter =
251        CreateSGetterSetter(env, BuiltinsSharedSet::Species, "[Symbol.species]", FunctionLength::ZERO);
252    SetSAccessor(JSHandle<JSObject>(setFunction), fieldIndex, speciesGetter, globalConst->GetHandledUndefined());
253
254    env->SetSharedSetPrototype(thread_, setPrototype);
255    env->SetSBuiltininSetFunction(thread_, setFunction);
256}
257
258void Builtins::InitializeSMap(const JSHandle<GlobalEnv> &env, const JSHandle<JSObject> &sObjPrototype,
259    const JSHandle<JSFunction> &sFuncPrototype) const
260{
261    [[maybe_unused]] EcmaHandleScope scope(thread_);
262    const GlobalEnvConstants *globalConst = thread_->GlobalConstants();
263    // SharedMap.prototype
264    JSHandle<JSHClass> mapPrototypeHClass = CreateSMapPrototypeHClass(sObjPrototype);
265    JSHandle<JSObject> mapPrototype =
266        factory_->NewSharedOldSpaceJSObjectWithInit(mapPrototypeHClass);
267    JSHandle<JSTaggedValue> mapPrototypeValue(mapPrototype);
268    // SharedMap.prototype_or_hclass
269    auto emptySLayout = globalConst->GetHandledEmptySLayoutInfo();
270    JSHandle<JSHClass> mapIHClass =
271        factory_->NewSEcmaHClass(JSSharedMap::SIZE, 0, JSType::JS_SHARED_MAP, mapPrototypeValue, emptySLayout);
272    // SharedMap.hclass
273    JSHandle<JSHClass> mapFuncHClass = CreateSMapFunctionHClass(sFuncPrototype);
274    // SharedMap() = new Function()
275    JSHandle<JSFunction> mapFunction =
276        factory_->NewSFunctionByHClass(reinterpret_cast<void *>(BuiltinsSharedMap::Constructor),
277                                       mapFuncHClass, FunctionKind::BUILTIN_CONSTRUCTOR);
278    InitializeSCtor(mapIHClass, mapFunction, "SendableMap", FunctionLength::ZERO);
279    JSHandle<JSObject> globalObject(thread_, env->GetGlobalObject());
280    JSHandle<JSTaggedValue> nameString(factory_->NewFromUtf8ReadOnly("SendableMap"));
281    PropertyDescriptor desc(thread_, JSHandle<JSTaggedValue>::Cast(mapFunction), true, false, true);
282    JSObject::DefineOwnProperty(thread_, globalObject, nameString, desc);
283    RETURN_IF_ABRUPT_COMPLETION(thread_);
284
285    // "constructor" property on the prototype
286    uint32_t fieldIndex = 0; // constructor
287    mapPrototype->SetPropertyInlinedProps(thread_, fieldIndex++, mapFunction.GetTaggedValue());
288    // SharedMap.prototype functions
289    for (const base::BuiltinFunctionEntry &entry: BuiltinsSharedMap::GetMapPrototypeFunctions()) {
290        SetSFunction(env, mapPrototype, entry.GetName(), entry.GetEntrypoint(), fieldIndex++,
291                     entry.GetLength(), entry.GetBuiltinStubId());
292    }
293    // @@ToStringTag
294    JSHandle<JSTaggedValue> strTag(factory_->NewFromUtf8ReadOnly("SendableMap"));
295    mapPrototype->SetPropertyInlinedProps(thread_, fieldIndex++, strTag.GetTaggedValue());
296
297    // 23.1.3.10get SharedMap.prototype.size
298    JSHandle<JSTaggedValue> sizeGetter = CreateSGetterSetter(env, BuiltinsSharedMap::GetSize, "size",
299        FunctionLength::ZERO);
300    SetSAccessor(mapPrototype, fieldIndex++, sizeGetter, globalConst->GetHandledUndefined());
301
302    // %MapPrototype% [ @@iterator ]
303    JSHandle<JSTaggedValue> entries(factory_->NewFromASCIIReadOnly("entries"));
304    JSHandle<JSTaggedValue> entriesFunc =
305        JSObject::GetMethod(thread_, JSHandle<JSTaggedValue>::Cast(mapPrototype), entries);
306    RETURN_IF_ABRUPT_COMPLETION(thread_);
307    mapPrototype->SetPropertyInlinedProps(thread_, fieldIndex++, entriesFunc.GetTaggedValue());
308
309    fieldIndex = JSFunction::PROTOTYPE_INLINE_PROPERTY_INDEX + 1;
310    // 23.1.2.2get SharedMap [ @@species ]
311    JSHandle<JSTaggedValue> speciesGetter =
312        CreateSGetterSetter(env, BuiltinsSharedMap::Species, "[Symbol.species]", FunctionLength::ZERO);
313    SetSAccessor(JSHandle<JSObject>(mapFunction), fieldIndex, speciesGetter, globalConst->GetHandledUndefined());
314
315    env->SetSharedMapPrototype(thread_, mapPrototype);
316    env->SetSBuiltininMapFunction(thread_, mapFunction);
317}
318
319void Builtins::InitializeSModuleNamespace(const JSHandle<GlobalEnv> &env, const JSHandle<JSHClass> &sObjIHClass) const
320{
321    [[maybe_unused]] EcmaHandleScope scope(thread_);
322    // SharedModuleNamespace.prototype
323    JSHandle<JSObject> moduleNamespacePrototype = factory_->NewSharedOldSpaceJSObjectWithInit(sObjIHClass);
324    JSHandle<JSTaggedValue> moduleNamespacePrototypeValue(moduleNamespacePrototype);
325
326    //  SharedModuleNamespace.prototype_or_hclass
327    auto emptySLayout = thread_->GlobalConstants()->GetHandledEmptySLayoutInfo();
328
329    JSHandle<JSHClass> moduleNamespaceHClass = factory_->NewSEcmaHClass(ModuleNamespace::SIZE, 0,
330        JSType::JS_MODULE_NAMESPACE, moduleNamespacePrototypeValue, emptySLayout);
331    moduleNamespaceHClass->SetPrototype(thread_, JSTaggedValue::Null());
332    env->SetSharedModuleNamespaceClass(thread_, moduleNamespaceHClass.GetTaggedValue());
333
334    // SharedmoduleNamespace.prototype [ @@toStringTag ]
335    SetStringTagSymbol(env, moduleNamespacePrototype, "Module");
336}
337
338void Builtins::InitializeSAsyncFunction(const JSHandle<GlobalEnv> &env,
339                                        const JSHandle<JSHClass> &sObjIHClass) const
340{
341    // SharedAsyncFunction.prototype
342    JSHandle<JSObject> sAsyncFuncPrototype = factory_->NewSharedOldSpaceJSObjectWithInit(sObjIHClass);
343    JSObject::SetPrototype(thread_, sAsyncFuncPrototype, env->GetSFunctionPrototype());
344    // SharedAsyncFunction.prototype_or_hclass
345    auto emptySLayout = thread_->GlobalConstants()->GetHandledEmptySLayoutInfo();
346    JSHandle<JSHClass> sAsyncFuncIHClass = factory_->NewSEcmaHClass(JSAsyncFunction::SIZE, 0,
347        JSType::JS_SHARED_ASYNC_FUNCTION, JSHandle<JSTaggedValue>(sAsyncFuncPrototype), emptySLayout);
348        // SharedAsyncFunction = new SharedFunction()
349    JSHandle<JSFunction> sAsyncFuncFunction = factory_->NewSFunctionByHClass(
350        reinterpret_cast<void *>(BuiltinsSharedAsyncFunction::SharedAsyncFunctionConstructor),
351        sAsyncFuncIHClass, FunctionKind::BUILTIN_CONSTRUCTOR);
352    JSObject::SetPrototype(thread_, JSHandle<JSObject>(sAsyncFuncFunction), env->GetSFunctionFunction());
353    sAsyncFuncFunction->SetProtoOrHClass(thread_, sAsyncFuncIHClass);
354    env->SetSAsyncFunctionFunction(thread_, sAsyncFuncFunction);
355    env->SetSAsyncFunctionPrototype(thread_, sAsyncFuncPrototype);
356    JSHandle<JSTaggedValue> sAsyncFuncPrototypeVal(thread_, sAsyncFuncPrototype.GetTaggedValue());
357    JSHandle<JSHClass> sAsyncFuncClass = factory_->CreateSFunctionClass(
358        JSAsyncFunction::SIZE, JSType::JS_SHARED_ASYNC_FUNCTION, sAsyncFuncPrototypeVal);
359    env->SetSAsyncFunctionClass(thread_, sAsyncFuncClass);
360}
361
362void Builtins::InitializeSFunction(const JSHandle<GlobalEnv> &env,
363                                   const JSHandle<JSFunction> &sFuncPrototype) const
364{
365    [[maybe_unused]] EcmaHandleScope scope(thread_);
366    SetSFunctionLength(sFuncPrototype, FunctionLength::ZERO);
367    SetSFunctionName(sFuncPrototype, thread_->GlobalConstants()->GetHandledEmptyString());
368    // SharedFunction.prototype_or_hclass
369    auto emptySLayout = thread_->GlobalConstants()->GetHandledEmptySLayoutInfo();
370    JSHandle<JSHClass> sFuncIHClass = factory_->NewSEcmaHClass(JSSharedFunction::SIZE, 0, JSType::JS_SHARED_FUNCTION,
371        JSHandle<JSTaggedValue>(sFuncPrototype), emptySLayout);
372    sFuncIHClass->SetCallable(true);
373    sFuncIHClass->SetConstructor(true);
374    // SharedFunction.hclass
375    JSHandle<JSHClass> sFuncHClass = CreateSFunctionHClass(sFuncPrototype);
376    // new SharedFunction() (forbidden use NewBuiltinConstructor)
377    JSHandle<JSFunction> sFuncFunction = factory_->NewSFunctionByHClass(
378        reinterpret_cast<void *>(BuiltinsSharedFunction::SharedFunctionConstructor),
379        sFuncHClass, FunctionKind::BUILTIN_CONSTRUCTOR);
380    InitializeSCtor(sFuncIHClass, sFuncFunction, "SharedFunction", FunctionLength::ONE);
381    env->SetSFunctionFunction(thread_, sFuncFunction);
382    env->SetSFunctionPrototype(thread_, sFuncPrototype);
383
384    JSHandle<JSTaggedValue> sFuncPrototypeVal(sFuncPrototype);
385    JSHandle<JSHClass> functionClass =
386        factory_->CreateSFunctionClass(JSSharedFunction::SIZE, JSType::JS_SHARED_FUNCTION,
387                                       sFuncPrototypeVal);
388    env->SetSFunctionClassWithoutProto(thread_, functionClass);
389    JSHandle<JSHClass> functionClassWithProto =
390        factory_->CreateSFunctionClass(JSSharedFunction::SIZE, JSType::JS_SHARED_FUNCTION,
391                                       sFuncPrototypeVal, true, true);
392    env->SetSFunctionClassWithProto(thread_, functionClassWithProto);
393
394    JSHandle<JSHClass> functionClassWithoutAccessor =
395        factory_->CreateSFunctionClass(JSSharedFunction::SIZE, JSType::JS_SHARED_FUNCTION,
396                                       sFuncPrototypeVal, false);
397    env->SetSFunctionClassWithoutAccessor(thread_, functionClassWithoutAccessor);
398    uint32_t fieldIndex = 2; // 2: length and name
399    JSHandle<JSObject> sFuncPrototypeObj(sFuncPrototype);
400    sFuncPrototypeObj->SetPropertyInlinedProps(thread_, fieldIndex++, sFuncFunction.GetTaggedValue()); // constructor
401    SharedStrictModeForbiddenAccessCallerArguments(env, fieldIndex, sFuncPrototypeObj);
402    // Function.prototype method
403    // 19.2.3.1 Function.prototype.apply ( thisArg, argArray )
404    SetSFunction(env, sFuncPrototypeObj, "apply", Function::FunctionPrototypeApply, fieldIndex++, FunctionLength::TWO,
405        BUILTINS_STUB_ID(FunctionPrototypeApply));
406    // 19.2.3.2 Function.prototype.bind ( thisArg , ...args)
407    SetSFunction(env, sFuncPrototypeObj, "bind", Function::FunctionPrototypeBind, fieldIndex++, FunctionLength::ONE);
408    // 19.2.3.3 Function.prototype.call (thisArg , ...args)
409    SetSFunction(env, sFuncPrototypeObj, "call", Function::FunctionPrototypeCall, fieldIndex++, FunctionLength::ONE);
410    // 19.2.3.5 Function.prototype.toString ( )
411    SetSFunction(env, sFuncPrototypeObj, thread_->GlobalConstants()->GetHandledToStringString(),
412        Function::FunctionPrototypeToString, fieldIndex++, FunctionLength::ZERO);
413    SetSFunction(env, sFuncPrototypeObj, "[Symbol.hasInstance]",
414        Function::FunctionPrototypeHasInstance, fieldIndex++, FunctionLength::ONE);
415}
416
417JSHandle<JSHClass> Builtins::CreateSObjectFunctionHClass(const JSHandle<JSFunction> &sFuncPrototype) const
418{
419    uint32_t index = 0;
420    PropertyAttributes attributes = PropertyAttributes::Default(false, false, false);
421    attributes.SetIsInlinedProps(true);
422    attributes.SetRepresentation(Representation::TAGGED);
423    auto properties = Object::GetFunctionProperties();
424    uint32_t length = properties.size();
425    JSHandle<LayoutInfo> layout = factory_->CreateSLayoutInfo(length);
426    for (const std::pair<std::string_view, bool> &each : properties) {
427        attributes.SetOffset(index);
428        attributes.SetIsAccessor(each.second);
429        JSHandle<JSTaggedValue> keyString(factory_->NewFromUtf8ReadOnly(each.first));
430        layout->AddKey(thread_, index++, keyString.GetTaggedValue(), attributes);
431    }
432    JSHandle<JSHClass> sobjPrototypeHClass =
433        factory_->NewSEcmaHClass(JSSharedFunction::SIZE, length, JSType::JS_SHARED_FUNCTION,
434                                 JSHandle<JSTaggedValue>(sFuncPrototype), JSHandle<JSTaggedValue>(layout));
435    sobjPrototypeHClass->SetConstructor(true);
436    sobjPrototypeHClass->SetCallable(true);
437    return sobjPrototypeHClass;
438}
439
440JSHandle<JSHClass> Builtins::CreateSObjectPrototypeHClass() const
441{
442    const GlobalEnvConstants *globalConst = thread_->GlobalConstants();
443    JSHandle<JSTaggedValue> nullHandle = globalConst->GetHandledNull();
444
445    uint32_t index = 0;
446    PropertyAttributes attributes = PropertyAttributes::Default(false, false, false);
447    attributes.SetIsInlinedProps(true);
448    attributes.SetRepresentation(Representation::TAGGED);
449    auto properties = Object::GetFunctionPrototypeProperties();
450    uint32_t length = properties.size();
451    JSHandle<LayoutInfo> layout = factory_->CreateSLayoutInfo(length);
452    for (const std::pair<std::string_view, bool> &each : properties) {
453        attributes.SetOffset(index);
454        attributes.SetIsAccessor(each.second);
455        JSHandle<JSTaggedValue> keyString(factory_->NewFromUtf8ReadOnly(each.first));
456        layout->AddKey(thread_, index++, keyString.GetTaggedValue(), attributes);
457    }
458
459    JSHandle<JSHClass> sobjPrototypeHClass =
460        factory_->NewSEcmaHClass(JSSharedObject::SIZE, length, JSType::JS_SHARED_OBJECT, nullHandle,
461                                 JSHandle<JSTaggedValue>(layout));
462    return sobjPrototypeHClass;
463}
464
465JSHandle<JSHClass> Builtins::CreateSFunctionHClass(const JSHandle<JSFunction> &sFuncPrototype) const
466{
467    uint32_t index = 0;
468    PropertyAttributes attributes = PropertyAttributes::Default(false, false, false);
469    attributes.SetIsInlinedProps(true);
470    attributes.SetRepresentation(Representation::TAGGED);
471    auto properties = Function::GetFunctionProperties();
472    uint32_t length = properties.size();
473    JSHandle<LayoutInfo> layout = factory_->CreateSLayoutInfo(length);
474    for (const base::BuiltinsPropertyConfig &each : properties) {
475        attributes.SetOffset(index);
476        attributes.SetIsAccessor(each.GetIsAccessor());
477        JSHandle<JSTaggedValue> keyString(factory_->NewFromUtf8ReadOnly(each.GetName()));
478        layout->AddKey(thread_, index++, keyString.GetTaggedValue(), attributes);
479    }
480    JSHandle<JSHClass> sobjPrototypeHClass =
481        factory_->NewSEcmaHClass(JSSharedFunction::SIZE, length, JSType::JS_SHARED_FUNCTION,
482                                 JSHandle<JSTaggedValue>(sFuncPrototype), JSHandle<JSTaggedValue>(layout));
483    sobjPrototypeHClass->SetConstructor(true);
484    sobjPrototypeHClass->SetCallable(true);
485    return sobjPrototypeHClass;
486}
487
488JSHandle<JSHClass> Builtins::CreateSArrayBufferFunctionHClass(const JSHandle<JSFunction> &sFuncPrototype) const
489{
490    uint32_t index = 0;
491    auto env = vm_->GetGlobalEnv();
492    PropertyAttributes attributes = PropertyAttributes::Default(false, false, false);
493    attributes.SetIsInlinedProps(true);
494    attributes.SetRepresentation(Representation::TAGGED);
495    auto properties = BuiltinsSendableArrayBuffer::GetFunctionProperties();
496    uint32_t length = properties.size();
497    JSHandle<JSTaggedValue> keyString;
498    JSHandle<LayoutInfo> layout = factory_->CreateSLayoutInfo(length);
499    for (const auto &[key, isAccessor] : properties) {
500        attributes.SetOffset(index);
501        attributes.SetIsAccessor(isAccessor);
502        if (key == "[Symbol.species]") {
503            keyString = env->GetSpeciesSymbol();
504        } else {
505            keyString = JSHandle<JSTaggedValue>(factory_->NewFromUtf8ReadOnly(key));
506        }
507        layout->AddKey(thread_, index++, keyString.GetTaggedValue(), attributes);
508    }
509    JSHandle<JSHClass> sobjPrototypeHClass =
510        factory_->NewSEcmaHClass(JSSharedFunction::SIZE, length, JSType::JS_SHARED_FUNCTION,
511                                 JSHandle<JSTaggedValue>(sFuncPrototype), JSHandle<JSTaggedValue>(layout));
512    sobjPrototypeHClass->SetConstructor(true);
513    sobjPrototypeHClass->SetCallable(true);
514    return sobjPrototypeHClass;
515}
516
517JSHandle<JSHClass> Builtins::CreateSSetFunctionHClass(const JSHandle<JSFunction> &sFuncPrototype) const
518{
519    uint32_t index = 0;
520    auto env = vm_->GetGlobalEnv();
521    PropertyAttributes attributes = PropertyAttributes::Default(false, false, false);
522    attributes.SetIsInlinedProps(true);
523    attributes.SetRepresentation(Representation::TAGGED);
524    auto properties = BuiltinsSharedSet::GetFunctionProperties();
525    uint32_t length = properties.size();
526    JSHandle<JSTaggedValue> keyString;
527    JSHandle<LayoutInfo> layout = factory_->CreateSLayoutInfo(length);
528    for (const auto &[key, isAccessor] : properties) {
529        attributes.SetOffset(index);
530        attributes.SetIsAccessor(isAccessor);
531        if (key == "[Symbol.species]") {
532            keyString = env->GetSpeciesSymbol();
533        } else {
534            keyString = JSHandle<JSTaggedValue>(factory_->NewFromUtf8ReadOnly(key));
535        }
536        layout->AddKey(thread_, index++, keyString.GetTaggedValue(), attributes);
537    }
538    JSHandle<JSHClass> sobjPrototypeHClass =
539        factory_->NewSEcmaHClass(JSSharedFunction::SIZE, length, JSType::JS_SHARED_FUNCTION,
540                                 JSHandle<JSTaggedValue>(sFuncPrototype), JSHandle<JSTaggedValue>(layout));
541    sobjPrototypeHClass->SetConstructor(true);
542    sobjPrototypeHClass->SetCallable(true);
543    return sobjPrototypeHClass;
544}
545
546JSHandle<JSHClass> Builtins::CreateSMapFunctionHClass(const JSHandle<JSFunction> &sFuncPrototype) const
547{
548    uint32_t index = 0;
549    auto env = vm_->GetGlobalEnv();
550    PropertyAttributes attributes = PropertyAttributes::Default(false, false, false);
551    attributes.SetIsInlinedProps(true);
552    attributes.SetRepresentation(Representation::TAGGED);
553    auto properties = BuiltinsSharedMap::GetFunctionProperties();
554    uint32_t length = properties.size();
555    JSHandle<JSTaggedValue> keyString;
556    JSHandle<LayoutInfo> layout = factory_->CreateSLayoutInfo(length);
557    for (const auto &[key, isAccessor] : properties) {
558        attributes.SetOffset(index);
559        attributes.SetIsAccessor(isAccessor);
560        if (key == "[Symbol.species]") {
561            keyString = env->GetSpeciesSymbol();
562        } else {
563            keyString = JSHandle<JSTaggedValue>(factory_->NewFromUtf8ReadOnly(key));
564        }
565        layout->AddKey(thread_, index++, keyString.GetTaggedValue(), attributes);
566    }
567    JSHandle<JSHClass> sobjPrototypeHClass =
568        factory_->NewSEcmaHClass(JSSharedFunction::SIZE, length, JSType::JS_SHARED_FUNCTION,
569                                 JSHandle<JSTaggedValue>(sFuncPrototype), JSHandle<JSTaggedValue>(layout));
570    sobjPrototypeHClass->SetConstructor(true);
571    sobjPrototypeHClass->SetCallable(true);
572    return sobjPrototypeHClass;
573}
574
575JSHandle<JSHClass> Builtins::CreateSFunctionPrototypeHClass(const JSHandle<JSTaggedValue> &sObjPrototypeVal) const
576{
577    uint32_t index = 0;
578    auto env = vm_->GetGlobalEnv();
579    PropertyAttributes attributes = PropertyAttributes::Default(false, false, false);
580    attributes.SetIsInlinedProps(true);
581    attributes.SetRepresentation(Representation::TAGGED);
582    auto properties = Function::GetFunctionPrototypeProperties();
583    uint32_t length = properties.size();
584    JSHandle<LayoutInfo> layout = factory_->CreateSLayoutInfo(length);
585    JSHandle<JSTaggedValue> keyString;
586    for (const base::BuiltinsPropertyConfig &each : properties) {
587        attributes.SetOffset(index);
588        attributes.SetIsAccessor(each.GetIsAccessor());
589        if (each.GetName() == "[Symbol.hasInstance]") {
590            keyString = env->GetHasInstanceSymbol();
591        } else {
592            keyString = JSHandle<JSTaggedValue>(factory_->NewFromUtf8ReadOnly(each.GetName()));
593        }
594        layout->AddKey(thread_, index++, keyString.GetTaggedValue(), attributes);
595    }
596    JSHandle<JSHClass> sobjPrototypeHClass =
597        factory_->NewSEcmaHClass(JSSharedFunction::SIZE, length, JSType::JS_SHARED_FUNCTION, sObjPrototypeVal,
598                                 JSHandle<JSTaggedValue>(layout));
599    sobjPrototypeHClass->SetCallable(true);
600    return sobjPrototypeHClass;
601}
602
603JSHandle<JSHClass> Builtins::CreateSArrayBufferPrototypeHClass(const JSHandle<JSObject> &sObjPrototype) const
604{
605    uint32_t index = 0;
606    auto env = vm_->GetGlobalEnv();
607    PropertyAttributes attributes = PropertyAttributes::Default(false, false, false);
608    attributes.SetIsInlinedProps(true);
609    attributes.SetRepresentation(Representation::TAGGED);
610    auto properties = BuiltinsSendableArrayBuffer::GetPrototypeProperties();
611    uint32_t length = properties.size();
612    ASSERT(length == BuiltinsSendableArrayBuffer::GetNumPrototypeInlinedProperties());
613    JSHandle<LayoutInfo> layout = factory_->CreateSLayoutInfo(length);
614    JSHandle<JSTaggedValue> keyString;
615    for (const auto &[key, isAccessor] : properties) {
616        attributes.SetOffset(index);
617        attributes.SetIsAccessor(isAccessor);
618        if (key == "[Symbol.toStringTag]") {
619            keyString = env->GetToStringTagSymbol();
620        } else {
621            keyString = JSHandle<JSTaggedValue>(factory_->NewFromUtf8ReadOnly(key));
622        }
623        layout->AddKey(thread_, index++, keyString.GetTaggedValue(), attributes);
624    }
625    JSHandle<JSHClass> sArrayBufferPrototypeHClass =
626        factory_->NewSEcmaHClass(JSSharedObject::SIZE, length, JSType::JS_SHARED_OBJECT,
627                                 JSHandle<JSTaggedValue>(sObjPrototype),
628                                 JSHandle<JSTaggedValue>(layout));
629    return sArrayBufferPrototypeHClass;
630}
631
632JSHandle<JSHClass> Builtins::CreateSSetPrototypeHClass(const JSHandle<JSObject> &sObjPrototype) const
633{
634    uint32_t index = 0;
635    auto env = vm_->GetGlobalEnv();
636    PropertyAttributes attributes = PropertyAttributes::Default(false, false, false);
637    attributes.SetIsInlinedProps(true);
638    attributes.SetRepresentation(Representation::TAGGED);
639    auto properties = BuiltinsSharedSet::GetPrototypeProperties();
640    uint32_t length = properties.size();
641    ASSERT(length == BuiltinsSharedSet::GetNumPrototypeInlinedProperties());
642    JSHandle<LayoutInfo> layout = factory_->CreateSLayoutInfo(length);
643    JSHandle<JSTaggedValue> keyString;
644    for (const auto &[key, isAccessor] : properties) {
645        attributes.SetOffset(index);
646        attributes.SetIsAccessor(isAccessor);
647        if (key == "[Symbol.iterator]") {
648            keyString = env->GetIteratorSymbol();
649        } else if (key == "[Symbol.toStringTag]") {
650            keyString = env->GetToStringTagSymbol();
651        } else {
652            keyString = JSHandle<JSTaggedValue>(factory_->NewFromUtf8ReadOnly(key));
653        }
654        layout->AddKey(thread_, index++, keyString.GetTaggedValue(), attributes);
655    }
656    JSHandle<JSHClass> sSetPrototypeHClass =
657        factory_->NewSEcmaHClass(JSSharedObject::SIZE, length, JSType::JS_SHARED_OBJECT,
658                                 JSHandle<JSTaggedValue>(sObjPrototype),
659                                 JSHandle<JSTaggedValue>(layout));
660    return sSetPrototypeHClass;
661}
662
663JSHandle<JSHClass> Builtins::CreateSMapPrototypeHClass(const JSHandle<JSObject> &sObjPrototype) const
664{
665    uint32_t index = 0;
666    auto env = vm_->GetGlobalEnv();
667    PropertyAttributes attributes = PropertyAttributes::Default(false, false, false);
668    attributes.SetIsInlinedProps(true);
669    attributes.SetRepresentation(Representation::TAGGED);
670    auto properties = BuiltinsSharedMap::GetPrototypeProperties();
671    uint32_t length = properties.size();
672    ASSERT(length == BuiltinsSharedMap::GetNumPrototypeInlinedProperties());
673    JSHandle<LayoutInfo> layout = factory_->CreateSLayoutInfo(length);
674    JSHandle<JSTaggedValue> keyString;
675    for (const auto &[key, isAccessor] : properties) {
676        attributes.SetOffset(index);
677        attributes.SetIsAccessor(isAccessor);
678        if (key == "[Symbol.iterator]") {
679            keyString = env->GetIteratorSymbol();
680        } else if (key == "[Symbol.toStringTag]") {
681            keyString = env->GetToStringTagSymbol();
682        } else {
683            keyString = JSHandle<JSTaggedValue>(factory_->NewFromUtf8ReadOnly(key));
684        }
685        layout->AddKey(thread_, index++, keyString.GetTaggedValue(), attributes);
686    }
687    JSHandle<JSHClass> sMapPrototypeHClass =
688        factory_->NewSEcmaHClass(JSSharedObject::SIZE, length, JSType::JS_SHARED_OBJECT,
689                                 JSHandle<JSTaggedValue>(sObjPrototype),
690                                 JSHandle<JSTaggedValue>(layout));
691    return sMapPrototypeHClass;
692}
693
694JSHandle<JSHClass> Builtins::CreateSArrayPrototypeHClass(const JSHandle<JSObject> &sObjPrototype) const
695{
696    uint32_t index = 0;
697    auto env = vm_->GetGlobalEnv();
698    PropertyAttributes attributes = PropertyAttributes::Default(false, false, false);
699    attributes.SetIsInlinedProps(true);
700    attributes.SetRepresentation(Representation::TAGGED);
701    auto properties = BuiltinsSharedArray::GetPrototypeProperties();
702    uint32_t length = properties.size();
703    ASSERT(length == BuiltinsSharedArray::GetNumPrototypeInlinedProperties());
704    JSHandle<LayoutInfo> layout = factory_->CreateSLayoutInfo(length);
705    JSHandle<JSTaggedValue> keyString;
706    for (const auto &[key, isAccessor] : properties) {
707        attributes.SetOffset(index);
708        attributes.SetIsAccessor(isAccessor);
709        if (key == "[Symbol.iterator]") {
710            keyString = env->GetIteratorSymbol();
711        } else if (key == "[Symbol.toStringTag]") {
712            keyString = env->GetToStringTagSymbol();
713        } else {
714            keyString = JSHandle<JSTaggedValue>(factory_->NewFromUtf8ReadOnly(key));
715        }
716        layout->AddKey(thread_, index++, keyString.GetTaggedValue(), attributes);
717    }
718    JSHandle<JSHClass> sArrayPrototypeHClass =
719        factory_->NewSEcmaHClass(JSSharedArray::SIZE, length, JSType::JS_SHARED_ARRAY,
720                                 JSHandle<JSTaggedValue>(sObjPrototype),
721                                 JSHandle<JSTaggedValue>(layout));
722    return sArrayPrototypeHClass;
723}
724
725JSHandle<JSHClass> Builtins::CreateSArrayFunctionHClass(const JSHandle<JSFunction> &sFuncPrototype) const
726{
727    uint32_t index = 0;
728    auto env = vm_->GetGlobalEnv();
729    PropertyAttributes attributes = PropertyAttributes::Default(false, false, false);
730    attributes.SetIsInlinedProps(true);
731    attributes.SetRepresentation(Representation::TAGGED);
732    auto properties = BuiltinsSharedArray::GetFunctionProperties();
733    uint32_t length = properties.size();
734    JSHandle<JSTaggedValue> keyString;
735    JSHandle<LayoutInfo> layout = factory_->CreateSLayoutInfo(length);
736    for (const auto &[key, isAccessor] : properties) {
737        LOG_ECMA(DEBUG) << "CreateSArrayFunctionHClass " << key;
738        attributes.SetOffset(index);
739        attributes.SetIsAccessor(isAccessor);
740        if (key == "[Symbol.species]") {
741            keyString = env->GetSpeciesSymbol();
742        } else {
743            keyString = JSHandle<JSTaggedValue>(factory_->NewFromUtf8ReadOnly(key));
744        }
745        layout->AddKey(thread_, index++, keyString.GetTaggedValue(), attributes);
746    }
747    JSHandle<JSHClass> sobjPrototypeHClass =
748        factory_->NewSEcmaHClass(JSSharedFunction::SIZE, length, JSType::JS_SHARED_FUNCTION,
749                                 JSHandle<JSTaggedValue>(sFuncPrototype), JSHandle<JSTaggedValue>(layout));
750    sobjPrototypeHClass->SetConstructor(true);
751    sobjPrototypeHClass->SetCallable(true);
752    return sobjPrototypeHClass;
753}
754
755void Builtins::SetSFunctionName(const JSHandle<JSFunction> &ctor, std::string_view name) const
756{
757    JSHandle<JSTaggedValue> nameString(factory_->NewFromUtf8ReadOnly(name));
758    SetSFunctionName(ctor, nameString);
759}
760
761void Builtins::SetSFunctionName(const JSHandle<JSFunction> &ctor, const JSHandle<JSTaggedValue> &name) const
762{
763    auto nameIndex = JSFunction::NAME_INLINE_PROPERTY_INDEX;
764    ctor->SetPropertyInlinedProps(thread_, nameIndex, name.GetTaggedValue());
765}
766
767void Builtins::SetSFunctionLength(const JSHandle<JSFunction> &ctor, int length) const
768{
769    JSTaggedValue taggedLength(length);
770    auto lengthIndex = JSFunction::LENGTH_INLINE_PROPERTY_INDEX;
771    ctor->SetPropertyInlinedProps(thread_, lengthIndex, taggedLength);
772}
773
774void Builtins::SetSFunctionPrototype(const JSHandle<JSFunction> &ctor, const JSTaggedValue &prototype) const
775{
776    auto prototypeIndex = JSFunction::PROTOTYPE_INLINE_PROPERTY_INDEX;
777    ctor->SetPropertyInlinedProps(thread_, prototypeIndex, prototype);
778}
779
780void Builtins::InitializeSCtor(const JSHandle<JSHClass> &protoHClass, const JSHandle<JSFunction> &ctor,
781                               std::string_view name, int length) const
782{
783    SetSFunctionLength(ctor, length);
784    SetSFunctionName(ctor, name);
785    SetSFunctionPrototype(ctor, protoHClass->GetProto());
786    ctor->SetProtoOrHClass(thread_, protoHClass);
787}
788
789JSHandle<JSFunction> Builtins::NewSFunction(const JSHandle<GlobalEnv> &env, const JSHandle<JSTaggedValue> &key,
790                                            EcmaEntrypoint func, int length,
791                                            kungfu::BuiltinsStubCSigns::ID builtinId) const
792{
793    JSHandle<JSHClass> hclass = JSHandle<JSHClass>::Cast(env->GetSFunctionClassWithoutAccessor());
794    JSHandle<JSFunction> function = factory_->NewSFunctionByHClass(reinterpret_cast<void *>(func),
795        hclass, FunctionKind::NORMAL_FUNCTION, builtinId, MemSpaceType::SHARED_NON_MOVABLE);
796    SetSFunctionLength(function, length);
797    SetSFunctionName(function, key);
798    function->GetJSHClass()->SetExtensible(false);
799    return function;
800}
801
802void Builtins::SetSFunction(const JSHandle<GlobalEnv> &env, const JSHandle<JSObject> &obj, std::string_view key,
803                            EcmaEntrypoint func, uint32_t index, int length,
804                            kungfu::BuiltinsStubCSigns::ID builtinId) const
805{
806    JSHandle<JSTaggedValue> keyString(factory_->NewFromUtf8ReadOnly(key));
807    SetSFunction(env, obj, keyString, func, index, length, builtinId);
808}
809
810void Builtins::SetSFunction(const JSHandle<GlobalEnv> &env, const JSHandle<JSObject> &obj,
811                            const JSHandle<JSTaggedValue> &key, EcmaEntrypoint func, uint32_t index, int length,
812                            kungfu::BuiltinsStubCSigns::ID builtinId) const
813{
814    JSHandle<JSFunction> function(NewSFunction(env, key, func, length, builtinId));
815    obj->SetPropertyInlinedProps(thread_, index, function.GetTaggedValue());
816}
817
818void Builtins::SetSAccessor(const JSHandle<JSObject> &obj, uint32_t index,
819                            const JSHandle<JSTaggedValue> &getter, const JSHandle<JSTaggedValue> &setter) const
820{
821    JSHandle<AccessorData> accessor = factory_->NewSAccessorData();
822    accessor->SetGetter(thread_, getter);
823    accessor->SetSetter(thread_, setter);
824    obj->SetPropertyInlinedProps(thread_, index, accessor.GetTaggedValue());
825}
826
827JSHandle<JSTaggedValue> Builtins::CreateSGetterSetter(const JSHandle<GlobalEnv> &env, EcmaEntrypoint func,
828                                                      std::string_view name, int length) const
829{
830    JSHandle<JSTaggedValue> funcName(factory_->NewFromUtf8ReadOnly(name));
831    JSHandle<JSFunction> function = NewSFunction(env, funcName, func, length);
832    return JSHandle<JSTaggedValue>(function);
833}
834
835void Builtins::SharedStrictModeForbiddenAccessCallerArguments(const JSHandle<GlobalEnv> &env, uint32_t &index,
836                                                              const JSHandle<JSObject> &prototype) const
837{
838    JSHandle<JSHClass> hclass = JSHandle<JSHClass>::Cast(env->GetSFunctionClassWithoutProto());
839    JSHandle<JSFunction> func =
840        factory_->NewSFunctionWithAccessor(
841            reinterpret_cast<void *>(JSFunction::AccessCallerArgumentsThrowTypeError), hclass,
842            FunctionKind::NORMAL_FUNCTION);
843    // "caller"
844    SetSAccessor(prototype, index++, JSHandle<JSTaggedValue>(func), JSHandle<JSTaggedValue>(func));
845    // "arguments"
846    SetSAccessor(prototype, index++, JSHandle<JSTaggedValue>(func), JSHandle<JSTaggedValue>(func));
847}
848
849void Builtins::InitializeSSymbolAttributes(const JSHandle<GlobalEnv> &env)
850{
851    JSHandle<JSTaggedValue> hasInstanceSymbol(
852        factory_->NewSWellKnownSymbolWithChar("Symbol.hasInstance"));
853    JSHandle<JSTaggedValue> isConcatSpreadableSymbol(
854        factory_->NewSWellKnownSymbolWithChar("Symbol.isConcatSpreadable"));
855    JSHandle<JSTaggedValue> toStringTagSymbol(
856        factory_->NewSWellKnownSymbolWithChar("Symbol.toStringTag"));
857    JSHandle<JSTaggedValue> asyncIteratorSymbol(
858        factory_->NewSPublicSymbolWithChar("Symbol.asyncIterator"));
859    JSHandle<JSTaggedValue> matchSymbol(
860        factory_->NewSPublicSymbolWithChar("Symbol.match"));
861    JSHandle<JSTaggedValue> searchSymbol(
862        factory_->NewSPublicSymbolWithChar("Symbol.search"));
863    JSHandle<JSTaggedValue> toPrimitiveSymbol(
864        factory_->NewSPublicSymbolWithChar("Symbol.toPrimitive"));
865    JSHandle<JSTaggedValue> unscopablesSymbol(
866        factory_->NewSPublicSymbolWithChar("Symbol.unscopables"));
867    JSHandle<JSTaggedValue> nativeBindingSymbol(
868        factory_->NewSPublicSymbolWithChar("Symbol.nativeBinding"));
869
870    // Symbol attributes with detectors
871    // Create symbol string before create symbol to allocate symbol continuously
872    // Attention: Symbol serialization & deserialization are not supported now and
873    // the order of symbols and symbol-strings must be maintained too when
874    // Symbol serialization & deserialization are ready.
875#define INIT_SYMBOL_STRING(name, description, key)                                                 \
876    {                                                                                              \
877        [[maybe_unused]] JSHandle<EcmaString> string = factory_->NewFromUtf8ReadOnly(description); \
878    }
879DETECTOR_SYMBOL_LIST(INIT_SYMBOL_STRING)
880#undef INIT_SYMBOL_STRING
881
882#define INIT_PUBLIC_SYMBOL(name, description, key)                                 \
883    JSHandle<JSSymbol> key##Symbol = factory_->NewSEmptySymbol();                  \
884    JSHandle<EcmaString> key##String = factory_->NewFromUtf8ReadOnly(description); \
885    key##Symbol->SetDescription(thread_, key##String.GetTaggedValue());            \
886    key##Symbol->SetHashField(SymbolTable::Hash(key##String.GetTaggedValue()));
887DETECTOR_SYMBOL_LIST(INIT_PUBLIC_SYMBOL)
888#undef INIT_PUBLIC_SYMBOL
889
890#define REGISTER_SYMBOL(name, Name)                                                \
891    env->Set##Name##Symbol(thread_, name##Symbol);
892BUILTIN_ALL_SYMBOLS(REGISTER_SYMBOL)
893#undef REGISTER_SYMBOL
894}
895
896JSHandle<JSObject> Builtins::InitializeArrayPrototype(JSHandle<JSHClass> &arrBaseFuncInstanceHClass) const
897{
898    JSHandle<JSObject> arrFuncPrototype = factory_->NewSharedOldSpaceJSObjectWithInit(arrBaseFuncInstanceHClass);
899    auto accessor = thread_->GlobalConstants()->GetSharedArrayLengthAccessor();
900    int32_t protoFieldIndex = JSSharedArray::LENGTH_INLINE_PROPERTY_INDEX;
901    static_assert(JSSharedArray::LENGTH_INLINE_PROPERTY_INDEX == 0);
902    arrFuncPrototype->SetPropertyInlinedProps(thread_, protoFieldIndex++, accessor);
903    return arrFuncPrototype;
904}
905
906JSHandle<JSHClass> Builtins::InitializeArrayPrototypeHClass(const JSHandle<JSObject> &arrFuncPrototype) const
907{
908    JSHandle<JSTaggedValue> arrFuncPrototypeValue(arrFuncPrototype);
909    JSHandle<LayoutInfo> layout = factory_->CreateSLayoutInfo(1);
910    PropertyAttributes attributes = PropertyAttributes::DefaultAccessor(true, false, false);
911    attributes.SetIsInlinedProps(true);
912    attributes.SetRepresentation(Representation::TAGGED);
913    layout->AddKey(thread_, 0, thread_->GlobalConstants()->GetHandledLengthString().GetTaggedValue(), attributes);
914
915    JSHandle<JSHClass> arrFuncInstanceHClass = factory_->NewSEcmaHClass(
916        JSSharedArray::SIZE, 1, JSType::JS_SHARED_ARRAY, arrFuncPrototypeValue, JSHandle<JSTaggedValue>::Cast(layout));
917    arrFuncInstanceHClass->SetExtensible(false);
918    return arrFuncInstanceHClass;
919}
920
921void Builtins::InitializeSharedArray(const JSHandle<GlobalEnv> &env, const JSHandle<JSObject> &sObjIHClass,
922                                     JSHandle<JSFunction> &sFuncPrototype) const
923{
924    [[maybe_unused]] EcmaHandleScope scope(thread_);
925    const GlobalEnvConstants *globalConst = thread_->GlobalConstants();
926    // Arraybase.prototype
927    JSHandle<JSHClass> arrBaseFuncInstanceHClass = CreateSArrayPrototypeHClass(sObjIHClass);
928
929    // Array.prototype
930    JSHandle<JSObject> arrFuncPrototype = InitializeArrayPrototype(arrBaseFuncInstanceHClass);
931    // Array.prototype_or_hclass
932    JSHandle<JSHClass> arrFuncInstanceHClass = InitializeArrayPrototypeHClass(arrFuncPrototype);
933    int32_t protoFieldIndex = JSSharedArray::LENGTH_INLINE_PROPERTY_INDEX + 1;
934
935    // SharedArray.hclass
936    JSHandle<JSHClass> arrayFuncHClass = CreateSArrayFunctionHClass(sFuncPrototype);
937    arrayFuncHClass->SetExtensible(false);
938    // SharedArray() = new Function()
939    JSHandle<JSFunction> arrayFunction =
940        factory_->NewSFunctionByHClass(reinterpret_cast<void *>(BuiltinsSharedArray::ArrayConstructor), arrayFuncHClass,
941                                       FunctionKind::BUILTIN_CONSTRUCTOR);
942
943    InitializeSCtor(arrFuncInstanceHClass, arrayFunction, "SendableArray", FunctionLength::ZERO);
944
945    arrFuncPrototype->SetPropertyInlinedProps(thread_, protoFieldIndex++, arrayFunction.GetTaggedValue());
946    JSHandle<JSObject> globalObject(thread_, env->GetGlobalObject());
947    JSHandle<JSTaggedValue> nameString(factory_->NewFromUtf8ReadOnly("SendableArray"));
948    PropertyDescriptor desc(thread_, JSHandle<JSTaggedValue>::Cast(arrayFunction), false, false, false);
949    JSObject::DefineOwnProperty(thread_, globalObject, nameString, desc);
950    RETURN_IF_ABRUPT_COMPLETION(thread_);
951    for (const base::BuiltinFunctionEntry &entry : BuiltinsSharedArray::GetSharedArrayPrototypeFunctions()) {
952        SetSFunction(env, arrFuncPrototype, entry.GetName(), entry.GetEntrypoint(), protoFieldIndex++,
953                     entry.GetLength(), entry.GetBuiltinStubId());
954    }
955
956    // %ArrayPrototype% [ @@iterator ]
957    JSHandle<JSTaggedValue> values(factory_->NewFromASCIIReadOnly("values"));
958    JSHandle<JSTaggedValue> valuesFunc =
959        JSObject::GetMethod(thread_, JSHandle<JSTaggedValue>::Cast(arrFuncPrototype), values);
960    RETURN_IF_ABRUPT_COMPLETION(thread_);
961    int32_t funcFieldIndex = 3;  // 3: length, name, prototype
962    for (const base::BuiltinFunctionEntry &entry : BuiltinsSharedArray::GetSharedArrayFunctions()) {
963        SetSFunction(env, JSHandle<JSObject>(arrayFunction), entry.GetName(), entry.GetEntrypoint(), funcFieldIndex++,
964                     entry.GetLength(), entry.GetBuiltinStubId());
965    }
966
967    // %SetPrototype% [ @@iterator ]
968    arrFuncPrototype->SetPropertyInlinedProps(thread_, protoFieldIndex++, valuesFunc.GetTaggedValue());
969
970    // 22.1.2.5 get %Array% [ @@species ]
971    JSHandle<JSTaggedValue> speciesGetter =
972        CreateSGetterSetter(env, BuiltinsSharedArray::Species, "[Symbol.species]", FunctionLength::ZERO);
973    SetSAccessor(JSHandle<JSObject>(arrayFunction), funcFieldIndex++, speciesGetter,
974                 globalConst->GetHandledUndefined());
975
976    // Array.prototype [ @@unscopables ]
977    JSHandle<JSTaggedValue> unscopablesGetter =
978        CreateSGetterSetter(env, BuiltinsSharedArray::Unscopables, "[Symbol.unscopables]", FunctionLength::ZERO);
979    SetSAccessor(JSHandle<JSObject>(arrFuncPrototype), protoFieldIndex++, unscopablesGetter,
980                 globalConst->GetHandledUndefined());
981    arrBaseFuncInstanceHClass->SetExtensible(false);
982    env->SetSharedArrayFunction(thread_, arrayFunction);
983    env->SetSharedArrayPrototype(thread_, arrFuncPrototype);
984}
985
986// todo: remove sendableName when refactor
987#define BUILTIN_SHARED_TYPED_ARRAY_DEFINE_INITIALIZE(Type, ctorName, TYPE, bytesPerElement, sendableName)       \
988void Builtins::InitializeS##Type(const JSHandle<GlobalEnv> &env, const JSHandle<JSHClass> &arrFuncClass) const  \
989{                                                                                                               \
990    [[maybe_unused]] EcmaHandleScope scope(thread_);                                                            \
991    const GlobalEnvConstants *globalConst = thread_->GlobalConstants();                                         \
992    auto emptySLayout = globalConst->GetHandledEmptySLayoutInfo();                                              \
993    /* %SharedTypedArray%.prototype (where %SharedTypedArray% is one of Int8Array, Uint8Array, etc.) */         \
994    JSHandle<JSObject> arrFuncPrototype = factory_->NewSharedOldSpaceJSObjectWithInit(arrFuncClass);            \
995    JSHandle<JSTaggedValue> arrFuncPrototypeValue(arrFuncPrototype);                                            \
996    /* %SharedTypedArray%.prototype_or_hclass */                                                                \
997    JSHandle<JSHClass> arrFuncInstanceHClass = factory_->NewSEcmaHClass(                                        \
998        JSSharedTypedArray::SIZE, 0, JSType::JS_SHARED_##TYPE, arrFuncPrototypeValue, emptySLayout);            \
999    JSHandle<JSHClass> arrFuncInstanceHClassOnHeap = factory_->NewSEcmaHClass(                                  \
1000        JSSharedTypedArray::SIZE, 0, JSType::JS_SHARED_##TYPE, arrFuncPrototypeValue, emptySLayout);            \
1001    arrFuncInstanceHClassOnHeap->SetIsOnHeap(true);                                                             \
1002    arrFuncInstanceHClass->SetHasConstructor(false);                                                            \
1003    /* %SharedTypedArray% = new Function() */                                                                   \
1004    JSHandle<JSHClass> specificTypedArrayFuncClass = JSHandle<JSHClass>::Cast(                                  \
1005        env->GetSharedSpecificTypedArrayFunctionClass());                                                       \
1006    JSHandle<JSFunction> arrayFunction = factory_->NewSFunctionByHClass(                                        \
1007        reinterpret_cast<void *>(BuiltinsSharedTypedArray::Type##Constructor), specificTypedArrayFuncClass,     \
1008        FunctionKind::BUILTIN_CONSTRUCTOR);                                                                     \
1009    InitializeSCtor(arrFuncInstanceHClass, arrayFunction, #sendableName, FunctionLength::THREE);                \
1010    JSHandle<JSObject> globalObject(thread_, env->GetGlobalObject());                                           \
1011    JSHandle<JSTaggedValue> nameString(factory_->NewFromUtf8ReadOnly(#sendableName));                           \
1012    PropertyDescriptor desc(thread_, JSHandle<JSTaggedValue>::Cast(arrayFunction), false, false, false);        \
1013    JSObject::DefineOwnProperty(thread_, globalObject, nameString, desc);                                       \
1014    RETURN_IF_ABRUPT_COMPLETION(thread_);                                                                       \
1015    /* 0: constructor index */                                                                                  \
1016    uint32_t fieldIndex = 0;                                                                                    \
1017    arrFuncPrototype->SetPropertyInlinedProps(thread_, fieldIndex++, arrayFunction.GetTaggedValue());           \
1018    arrFuncPrototype->SetPropertyInlinedProps(thread_, fieldIndex, JSTaggedValue(bytesPerElement));             \
1019    fieldIndex = JSFunction::PROTOTYPE_INLINE_PROPERTY_INDEX + 1;                                               \
1020    JSHandle<JSObject>(arrayFunction)->SetPropertyInlinedProps(thread_, fieldIndex,                             \
1021        JSTaggedValue(bytesPerElement));                                                                        \
1022    env->Set##ctorName##Function(thread_, arrayFunction);                                                       \
1023    env->Set##ctorName##FunctionPrototype(thread_, arrFuncPrototypeValue);                                      \
1024    env->Set##ctorName##RootHclass(thread_, arrFuncInstanceHClass);                                             \
1025    env->Set##ctorName##RootHclassOnHeap(thread_, arrFuncInstanceHClassOnHeap);                                 \
1026}
1027
1028BUILTIN_SHARED_TYPED_ARRAY_TYPES(BUILTIN_SHARED_TYPED_ARRAY_DEFINE_INITIALIZE)
1029#undef BUILTIN_SHARED_TYPED_ARRAY_DEFINE_INITIALIZE
1030
1031void Builtins::InitializeSTypedArray(const JSHandle<GlobalEnv> &env, const JSHandle<JSObject> &sObjPrototype,
1032    const JSHandle<JSFunction> &sFuncPrototype) const
1033{
1034    [[maybe_unused]] EcmaHandleScope scope(thread_);
1035    const GlobalEnvConstants *globalConst = thread_->GlobalConstants();
1036    // SharedTypedArray.prototype
1037    JSHandle<JSHClass> typedArrFuncPrototypeHClass = CreateSTypedArrayPrototypeHClass(sObjPrototype);
1038    JSHandle<JSObject> typedArrFuncPrototype = factory_->NewSharedOldSpaceJSObjectWithInit(typedArrFuncPrototypeHClass);
1039    JSHandle<JSTaggedValue> typedArrFuncPrototypeValue(typedArrFuncPrototype);
1040
1041    // SharedTypedArray.prototype_or_hclass
1042    JSHandle<JSHClass> typedArrFuncInstanceHClass = CreateSSpecificTypedArrayInstanceHClass(
1043        typedArrFuncPrototype);
1044    // SharedTypedArray.hclass
1045    JSHandle<JSHClass> typedArrFuncHClass = CreateSTypedArrayFunctionHClass(sFuncPrototype);
1046    // SharedTypedArray = new Function()
1047    JSHandle<JSFunction> typedArrayFunction =
1048        factory_->NewSFunctionByHClass(reinterpret_cast<void *>(BuiltinsSharedTypedArray::TypedArrayBaseConstructor),
1049                                       typedArrFuncHClass, FunctionKind::BUILTIN_CONSTRUCTOR);
1050    InitializeSCtor(typedArrFuncInstanceHClass, typedArrayFunction, "SharedTypedArray", FunctionLength::ZERO);
1051
1052    // "constructor" property on the prototype
1053    uint32_t fieldIndex = 0; // constructor
1054    typedArrFuncPrototype->SetPropertyInlinedProps(thread_, fieldIndex++, typedArrayFunction.GetTaggedValue());
1055
1056    // SharedTypedArray.prototype method
1057    for (const base::BuiltinFunctionEntry &entry: BuiltinsSharedTypedArray::GetTypedArrayPrototypeFunctions()) {
1058        SetSFunction(env, typedArrFuncPrototype, entry.GetName(), entry.GetEntrypoint(), fieldIndex++,
1059                     entry.GetLength(), entry.GetBuiltinStubId());
1060    }
1061    // SharedTypedArray.prototype get accessor
1062    for (const base::BuiltinFunctionEntry &entry: BuiltinsSharedTypedArray::GetTypedArrayPrototypeAccessors()) {
1063        JSHandle<JSTaggedValue> getter = CreateSGetterSetter(env, entry.GetEntrypoint(),
1064            entry.GetName(), entry.GetLength());
1065        SetSAccessor(typedArrFuncPrototype, fieldIndex++, getter, globalConst->GetHandledUndefined());
1066    }
1067
1068    // %SharedTypedArray%.prototype [ @@iterator ] ( )
1069    JSHandle<JSTaggedValue> values(factory_->NewFromASCIIReadOnly("values"));
1070    JSHandle<JSTaggedValue> valuesFunc =
1071        JSObject::GetMethod(thread_, JSHandle<JSTaggedValue>::Cast(typedArrFuncPrototype), values);
1072    RETURN_IF_ABRUPT_COMPLETION(thread_);
1073    typedArrFuncPrototype->SetPropertyInlinedProps(thread_, fieldIndex++, valuesFunc.GetTaggedValue());
1074
1075    // 22.2.3.31 get %SharedTypedArray%.prototype [ @@toStringTag ]
1076    JSHandle<JSTaggedValue> toStringTagGetter =
1077        CreateSGetterSetter(env, BuiltinsSharedTypedArray::ToStringTag, "[Symbol.toStringTag]", FunctionLength::ZERO);
1078    SetSAccessor(typedArrFuncPrototype, fieldIndex++, toStringTagGetter, globalConst->GetHandledUndefined());
1079
1080    uint32_t funcFieldIndex = JSFunction::PROTOTYPE_INLINE_PROPERTY_INDEX + 1; // length, name, prototype, ...
1081    // SharedTypedArray method
1082    for (const base::BuiltinFunctionEntry &entry: BuiltinsSharedTypedArray::GetTypedArrayFunctions()) {
1083        SetSFunction(env, JSHandle<JSObject>(typedArrayFunction), entry.GetName(), entry.GetEntrypoint(),
1084            funcFieldIndex++, entry.GetLength(), entry.GetBuiltinStubId());
1085    }
1086
1087    // 22.2.2.4 get %SharedTypedArray% [ @@species ]
1088    JSHandle<JSTaggedValue> speciesGetter =
1089        CreateSGetterSetter(env, BuiltinsSharedTypedArray::Species, "[Symbol.species]", FunctionLength::ZERO);
1090    SetSAccessor(JSHandle<JSObject>(typedArrayFunction), funcFieldIndex++, speciesGetter,
1091                 globalConst->GetHandledUndefined());
1092
1093    env->SetSharedTypedArrayFunction(thread_, typedArrayFunction.GetTaggedValue());
1094    env->SetSharedTypedArrayPrototype(thread_, typedArrFuncPrototype);
1095
1096    JSHandle<JSHClass> specificTypedArrayFuncClass = CreateSSpecificTypedArrayFuncHClass(typedArrayFunction);
1097    env->SetSharedSpecificTypedArrayFunctionClass(thread_, specificTypedArrayFuncClass);
1098
1099#define BUILTIN_SHARED_TYPED_ARRAY_CALL_INITIALIZE(Type, ctorName, TYPE, bytesPerElement, sendableName) \
1100    InitializeS##Type(env, typedArrFuncInstanceHClass);
1101    BUILTIN_SHARED_TYPED_ARRAY_TYPES(BUILTIN_SHARED_TYPED_ARRAY_CALL_INITIALIZE)
1102#undef BUILTIN_SHARED_TYPED_ARRAY_CALL_INITIALIZE
1103}
1104
1105JSHandle<JSHClass> Builtins::CreateSTypedArrayPrototypeHClass(const JSHandle<JSObject> &sObjPrototype) const
1106{
1107    uint32_t index = 0;
1108    auto env = vm_->GetGlobalEnv();
1109    PropertyAttributes attributes = PropertyAttributes::Default(false, false, false);
1110    attributes.SetIsInlinedProps(true);
1111    attributes.SetRepresentation(Representation::TAGGED);
1112    auto properties = BuiltinsSharedTypedArray::GetPrototypeProperties();
1113    uint32_t length = properties.size();
1114    ASSERT(length == BuiltinsSharedTypedArray::GetNumPrototypeInlinedProperties());
1115    JSHandle<LayoutInfo> layout = factory_->CreateSLayoutInfo(length);
1116    JSHandle<JSTaggedValue> keyString;
1117    for (const auto &[key, isAccessor] : properties) {
1118        attributes.SetOffset(index);
1119        attributes.SetIsAccessor(isAccessor);
1120        if (key == "[Symbol.iterator]") {
1121            keyString = env->GetIteratorSymbol();
1122        } else if (key == "[Symbol.toStringTag]") {
1123            keyString = env->GetToStringTagSymbol();
1124        } else {
1125            keyString = JSHandle<JSTaggedValue>(factory_->NewFromUtf8ReadOnly(key));
1126        }
1127        layout->AddKey(thread_, index++, keyString.GetTaggedValue(), attributes);
1128    }
1129    JSHandle<JSHClass> sTypedArrayPrototypeHClass =
1130        factory_->NewSEcmaHClass(JSSharedObject::SIZE, length, JSType::JS_SHARED_OBJECT,
1131                                 JSHandle<JSTaggedValue>(sObjPrototype),
1132                                 JSHandle<JSTaggedValue>(layout));
1133    return sTypedArrayPrototypeHClass;
1134}
1135
1136JSHandle<JSHClass> Builtins::CreateSTypedArrayFunctionHClass(const JSHandle<JSFunction> &sFuncPrototype) const
1137{
1138    uint32_t index = 0;
1139    auto env = vm_->GetGlobalEnv();
1140    PropertyAttributes attributes = PropertyAttributes::Default(false, false, false);
1141    attributes.SetIsInlinedProps(true);
1142    attributes.SetRepresentation(Representation::TAGGED);
1143    auto properties = BuiltinsSharedTypedArray::GetFunctionProperties();
1144    uint32_t length = properties.size();
1145    JSHandle<JSTaggedValue> keyString;
1146    JSHandle<LayoutInfo> layout = factory_->CreateSLayoutInfo(length);
1147    for (const auto &[key, isAccessor] : properties) {
1148        attributes.SetOffset(index);
1149        attributes.SetIsAccessor(isAccessor);
1150        if (key == "[Symbol.species]") {
1151            keyString = env->GetSpeciesSymbol();
1152        } else {
1153            keyString = JSHandle<JSTaggedValue>(factory_->NewFromUtf8ReadOnly(key));
1154        }
1155        layout->AddKey(thread_, index++, keyString.GetTaggedValue(), attributes);
1156    }
1157    JSHandle<JSHClass> sobjPrototypeHClass =
1158        factory_->NewSEcmaHClass(JSSharedFunction::SIZE, length, JSType::JS_SHARED_FUNCTION,
1159                                 JSHandle<JSTaggedValue>(sFuncPrototype), JSHandle<JSTaggedValue>(layout));
1160    sobjPrototypeHClass->SetConstructor(true);
1161    sobjPrototypeHClass->SetCallable(true);
1162    return sobjPrototypeHClass;
1163}
1164
1165JSHandle<JSHClass> Builtins::CreateSSpecificTypedArrayFuncHClass(const JSHandle<JSFunction> &sFuncPrototype) const
1166{
1167    uint32_t index = 0;
1168    PropertyAttributes attributes = PropertyAttributes::Default(false, false, false);
1169    attributes.SetIsInlinedProps(true);
1170    attributes.SetRepresentation(Representation::TAGGED);
1171    auto properties = BuiltinsSharedTypedArray::GetSpecificFunctionProperties();
1172    uint32_t length = properties.size();
1173    JSHandle<JSTaggedValue> keyString;
1174    JSHandle<LayoutInfo> layout = factory_->CreateSLayoutInfo(length);
1175    for (const auto &[key, isAccessor] : properties) {
1176        attributes.SetOffset(index);
1177        attributes.SetIsAccessor(isAccessor);
1178        keyString = JSHandle<JSTaggedValue>(factory_->NewFromUtf8ReadOnly(key));
1179        layout->AddKey(thread_, index++, keyString.GetTaggedValue(), attributes);
1180    }
1181    JSHandle<JSHClass> sobjPrototypeHClass =
1182        factory_->NewSEcmaHClass(JSSharedFunction::SIZE, length, JSType::JS_SHARED_FUNCTION,
1183                                 JSHandle<JSTaggedValue>(sFuncPrototype), JSHandle<JSTaggedValue>(layout));
1184    sobjPrototypeHClass->SetConstructor(true);
1185    sobjPrototypeHClass->SetCallable(true);
1186    return sobjPrototypeHClass;
1187}
1188
1189JSHandle<JSHClass> Builtins::CreateSSpecificTypedArrayInstanceHClass(const JSHandle<JSObject> &sObjPrototype) const
1190{
1191    uint32_t index = 0;
1192    PropertyAttributes attributes = PropertyAttributes::Default(false, false, false);
1193    attributes.SetIsInlinedProps(true);
1194    attributes.SetRepresentation(Representation::TAGGED);
1195    auto properties = BuiltinsSharedTypedArray::GetSpecificArrayPrototypeProperties();
1196    uint32_t length = properties.size();
1197    JSHandle<LayoutInfo> layout = factory_->CreateSLayoutInfo(length);
1198    JSHandle<JSTaggedValue> keyString;
1199    for (const auto &[key, isAccessor] : properties) {
1200        attributes.SetOffset(index);
1201        attributes.SetIsAccessor(isAccessor);
1202        keyString = JSHandle<JSTaggedValue>(factory_->NewFromUtf8ReadOnly(key));
1203        layout->AddKey(thread_, index++, keyString.GetTaggedValue(), attributes);
1204    }
1205    JSHandle<JSHClass> sSpecificTypedArrayPrototypeHClass =
1206        factory_->NewSEcmaHClass(JSSharedObject::SIZE, length, JSType::JS_SHARED_OBJECT,
1207                                 JSHandle<JSTaggedValue>(sObjPrototype),
1208                                 JSHandle<JSTaggedValue>(layout));
1209    return sSpecificTypedArrayPrototypeHClass;
1210}
1211}  // namespace panda::ecmascript
1212