1/*
2 * Copyright (c) 2023 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/jspandafile/program_object.h"
17#include "ecmascript/layout_info-inl.h"
18#include "ecmascript/mem/heap-inl.h"
19#include "ecmascript/runtime.h"
20#include "ecmascript/symbol_table.h"
21#include "ecmascript/jspandafile/program_object.h"
22
23// class Object;
24namespace panda::ecmascript {
25void ObjectFactory::NewSObjectHook() const
26{
27    CHECK_NO_HEAP_ALLOC;
28#ifndef NDEBUG
29    static std::atomic<uint32_t> count = 0;
30    static uint32_t frequency = vm_->GetJSOptions().GetForceSharedGCFrequency();
31    static constexpr uint32_t CONCURRENT_MARK_FREQUENCY_FACTOR = 2;
32    if (frequency == 0 || !vm_->GetJSOptions().EnableForceGC() || !vm_->IsInitialized() ||
33        !thread_->IsAllContextsInitialized()) {
34        return;
35    }
36    if (count++ % frequency == 0) {
37        if (count % (CONCURRENT_MARK_FREQUENCY_FACTOR * frequency) == 0) {
38            sHeap_->CollectGarbage<TriggerGCType::SHARED_GC, GCReason::OTHER>(thread_);
39        } else if (sHeap_->CheckCanTriggerConcurrentMarking(thread_)) {
40            sHeap_->TriggerConcurrentMarking<TriggerGCType::SHARED_GC, GCReason::OTHER>(thread_);
41        }
42        if (!ecmascript::AnFileDataManager::GetInstance()->IsEnable()) {
43            sHeap_->WaitGCFinished(thread_);
44            sHeap_->CollectGarbage<TriggerGCType::SHARED_FULL_GC, GCReason::OTHER>(thread_);
45        }
46    }
47#endif
48}
49
50JSHandle<JSHClass> ObjectFactory::CreateSFunctionClass(uint32_t size, JSType type,
51                                                       const JSHandle<JSTaggedValue> &prototype,
52                                                       bool isAccessor, bool setProto)
53{
54    const GlobalEnvConstants *globalConst = thread_->GlobalConstants();
55    uint32_t fieldOrder = 0;
56    ASSERT(JSFunction::LENGTH_INLINE_PROPERTY_INDEX == fieldOrder);
57    PropertyAttributes attributes = PropertyAttributes::Default(false, false, false);
58    attributes.SetIsAccessor(isAccessor);
59    attributes.SetIsInlinedProps(true);
60    attributes.SetRepresentation(Representation::TAGGED);
61    JSHandle<LayoutInfo> layoutInfoHandle = CreateSLayoutInfo(JSFunction::LENGTH_OF_INLINE_PROPERTIES);
62    {
63        attributes.SetOffset(fieldOrder);
64        layoutInfoHandle->AddKey(thread_, fieldOrder, globalConst->GetLengthString(), attributes);
65        fieldOrder++;
66    }
67
68    ASSERT(JSFunction::NAME_INLINE_PROPERTY_INDEX == fieldOrder);
69    {
70        attributes.SetOffset(fieldOrder);
71        layoutInfoHandle->AddKey(thread_, fieldOrder,
72                                 globalConst->GetHandledNameString().GetTaggedValue(), attributes);
73        fieldOrder++;
74    }
75    if (setProto) {
76        ASSERT(JSFunction::PROTOTYPE_INLINE_PROPERTY_INDEX == fieldOrder);
77        {
78            attributes.SetOffset(fieldOrder);
79            layoutInfoHandle->AddKey(thread_, fieldOrder,
80                                     globalConst->GetPrototypeString(), attributes);
81            fieldOrder++;
82        }
83    }
84    JSHandle<JSHClass> functionClass = NewSEcmaHClass(size, fieldOrder, type, prototype,
85        JSHandle<JSTaggedValue>(layoutInfoHandle));
86    functionClass->SetCallable(true);
87    return functionClass;
88}
89
90JSHandle<JSHClass> ObjectFactory::NewSEcmaHClass(uint32_t size, JSType type, uint32_t inlinedProps)
91{
92    return NewSEcmaHClass(JSHClass::Cast(thread_->GlobalConstants()->GetHClassClass().GetTaggedObject()),
93                          size, type, inlinedProps);
94}
95
96JSHandle<JSHClass> ObjectFactory::NewSEcmaHClass(JSHClass *hclass, uint32_t size, JSType type, uint32_t inlinedProps)
97{
98    NewSObjectHook();
99    uint32_t classSize = JSHClass::SIZE;
100    auto *newClass = static_cast<JSHClass *>(sHeap_->AllocateNonMovableOrHugeObject(thread_, hclass, classSize));
101    newClass->Initialize(thread_, size, type, inlinedProps, thread_->GlobalConstants()->GetHandledEmptySLayoutInfo());
102    return JSHandle<JSHClass>(thread_, newClass);
103}
104
105// This function don't UpdateProtoClass
106JSHandle<JSHClass> ObjectFactory::NewSEcmaHClass(uint32_t size, uint32_t inlinedProps, JSType type,
107    const JSHandle<JSTaggedValue> &prototype, const JSHandle<JSTaggedValue> &layout)
108{
109    NewSObjectHook();
110    uint32_t classSize = JSHClass::SIZE;
111    auto *newClass = static_cast<JSHClass *>(sHeap_->AllocateNonMovableOrHugeObject(
112        thread_, JSHClass::Cast(thread_->GlobalConstants()->GetHClassClass().GetTaggedObject()), classSize));
113    newClass->Initialize(thread_, size, type, inlinedProps, layout);
114    JSHandle<JSHClass> hclass(thread_, newClass);
115    if (prototype->IsJSObject()) {
116        prototype->GetTaggedObject()->GetClass()->SetIsPrototype(true);
117    }
118    hclass->SetProto(thread_, prototype.GetTaggedValue());
119    hclass->SetNumberOfProps(inlinedProps);
120    hclass->SetExtensible(false);
121    return hclass;
122}
123
124JSHandle<JSHClass> ObjectFactory::NewSEcmaHClassDictMode(uint32_t size, uint32_t inlinedProps, JSType type,
125                                                         const JSHandle<JSTaggedValue> &prototype)
126{
127    NewSObjectHook();
128    uint32_t classSize = JSHClass::SIZE;
129    auto *newClass = static_cast<JSHClass *>(sHeap_->AllocateNonMovableOrHugeObject(thread_,
130        JSHClass::Cast(thread_->GlobalConstants()->GetHClassClass().GetTaggedObject()), classSize));
131    newClass->Initialize(thread_, size, type, inlinedProps, thread_->GlobalConstants()->GetHandledEmptySLayoutInfo());
132    JSHandle<JSHClass> hclass(thread_, newClass);
133    if (prototype->IsJSObject()) {
134        prototype->GetTaggedObject()->GetClass()->SetIsPrototype(true);
135    }
136    hclass->SetProto(thread_, prototype.GetTaggedValue());
137    hclass->SetNumberOfProps(0);
138    hclass->SetIsDictionaryMode(true);
139    hclass->SetExtensible(false);
140    return hclass;
141}
142
143JSHandle<JSHClass> ObjectFactory::NewSEcmaHClassClass(JSHClass *hclass, uint32_t size, JSType type)
144{
145    NewSObjectHook();
146    uint32_t classSize = JSHClass::SIZE;
147    auto *newClass = static_cast<JSHClass *>(sHeap_->AllocateClassClass(thread_, hclass, classSize));
148    newClass->Initialize(thread_, size, type, 0, thread_->GlobalConstants()->GetHandledEmptySLayoutInfo());
149    return JSHandle<JSHClass>(thread_, newClass);
150}
151
152JSHandle<JSHClass> ObjectFactory::NewSEcmaReadOnlyHClass(JSHClass *hclass, uint32_t size, JSType type,
153                                                         uint32_t inlinedProps)
154{
155    NewSObjectHook();
156    uint32_t classSize = JSHClass::SIZE;
157    auto *newClass = static_cast<JSHClass *>(sHeap_->AllocateReadOnlyOrHugeObject(thread_, hclass, classSize));
158    ASSERT(newClass != nullptr);
159    newClass->Initialize(thread_, size, type, inlinedProps, thread_->GlobalConstants()->GetHandledEmptySLayoutInfo());
160    return JSHandle<JSHClass>(thread_, newClass);
161}
162
163JSHandle<JSHClass> ObjectFactory::InitSClassClass()
164{
165    JSHandle<JSHClass> hClassHandle = NewSEcmaHClassClass(nullptr, JSHClass::SIZE, JSType::HCLASS);
166    JSHClass *hclass = reinterpret_cast<JSHClass *>(hClassHandle.GetTaggedValue().GetTaggedObject());
167    hclass->SetClass(thread_, hclass);
168    return hClassHandle;
169}
170
171JSHandle<AccessorData> ObjectFactory::NewSAccessorData()
172{
173    NewSObjectHook();
174    TaggedObject *header = sHeap_->AllocateOldOrHugeObject(
175        thread_, JSHClass::Cast(thread_->GlobalConstants()->GetAccessorDataClass().GetTaggedObject()));
176    JSHandle<AccessorData> acc(thread_, AccessorData::Cast(header));
177    acc->SetGetter(thread_, JSTaggedValue::Undefined());
178    acc->SetSetter(thread_, JSTaggedValue::Undefined());
179    return acc;
180}
181
182JSHandle<Method> ObjectFactory::NewSMethod(const JSPandaFile *jsPandaFile, MethodLiteral *methodLiteral,
183                                           JSHandle<ConstantPool> constpool, uint32_t entryIndex,
184                                           bool needSetAotFlag, bool *canFastCall)
185{
186    JSHandle<Method> method;
187    if (jsPandaFile->IsNewVersion()) {
188        method = Method::Create(thread_, jsPandaFile, methodLiteral);
189    } else {
190        method = NewSMethod(methodLiteral);
191        method->SetConstantPool(thread_, constpool);
192    }
193    if (needSetAotFlag) {
194        auto aotFileManager = thread_->GetEcmaVM()->GetAOTFileManager();
195        aotFileManager->SetAOTFuncEntry(jsPandaFile, nullptr, *method, entryIndex, canFastCall);
196    } else {
197        method->InitInterpreterStatusForCompiledMethod(thread_);
198    }
199    return method;
200}
201
202JSHandle<Method> ObjectFactory::NewSMethod(const MethodLiteral *methodLiteral, MemSpaceType spaceType)
203{
204    ASSERT(spaceType == SHARED_NON_MOVABLE || spaceType == SHARED_OLD_SPACE);
205    NewSObjectHook();
206    TaggedObject *header = nullptr;
207    if (spaceType == SHARED_NON_MOVABLE) {
208        header = sHeap_->AllocateNonMovableOrHugeObject(thread_,
209            JSHClass::Cast(thread_->GlobalConstants()->GetMethodClass().GetTaggedObject()));
210    } else {
211        header = sHeap_->AllocateOldOrHugeObject(thread_,
212            JSHClass::Cast(thread_->GlobalConstants()->GetMethodClass().GetTaggedObject()));
213    }
214    JSHandle<Method> method(thread_, header);
215    InitializeMethod(methodLiteral, method);
216    return method;
217}
218
219JSHandle<Method> ObjectFactory::NewSMethodForNativeFunction(const void *func, FunctionKind kind,
220                                                            kungfu::BuiltinsStubCSigns::ID builtinId,
221                                                            MemSpaceType spaceType)
222{
223    uint32_t numArgs = 2;  // function object and this
224    auto method = NewSMethod(nullptr, spaceType);
225    method->SetNativePointer(const_cast<void *>(func));
226    method->SetNativeBit(true);
227    if (builtinId != kungfu::BuiltinsStubCSigns::INVALID) {
228        bool isFast = kungfu::BuiltinsStubCSigns::IsFastBuiltin(builtinId);
229        method->SetFastBuiltinBit(isFast);
230        method->SetBuiltinId(static_cast<uint8_t>(builtinId));
231    }
232    method->SetNumArgsWithCallField(numArgs);
233    method->SetFunctionKind(kind);
234    return method;
235}
236
237JSHandle<JSFunction> ObjectFactory::NewSFunctionByHClass(const JSHandle<Method> &method,
238                                                         const JSHandle<JSHClass> &hclass)
239{
240    JSHandle<JSFunction> function(NewSharedOldSpaceJSObject(hclass));
241    hclass->SetCallable(true);
242    JSFunction::InitializeSFunction(thread_, function, method->GetFunctionKind());
243    function->SetMethod(thread_, method);
244    function->SetTaskConcurrentFuncFlag(0); // 0 : default value
245    if (method->IsAotWithCallField()) {
246        thread_->GetEcmaVM()->GetAOTFileManager()->
247            SetAOTFuncEntry(method->GetJSPandaFile(), *function, *method);
248    }
249    return function;
250}
251
252// new function with name/length accessor
253JSHandle<JSFunction> ObjectFactory::NewSFunctionWithAccessor(const void *func, const JSHandle<JSHClass> &hclass,
254    FunctionKind kind, kungfu::BuiltinsStubCSigns::ID builtinId, MemSpaceType spaceType)
255{
256    ASSERT(spaceType == SHARED_NON_MOVABLE || spaceType == SHARED_OLD_SPACE);
257    JSHandle<Method> method = NewSMethodForNativeFunction(func, kind, builtinId, spaceType);
258    return NewSFunctionByHClass(method, hclass);
259}
260
261// new function without name/length accessor
262JSHandle<JSFunction> ObjectFactory::NewSFunctionByHClass(const void *func, const JSHandle<JSHClass> &hclass,
263    FunctionKind kind, kungfu::BuiltinsStubCSigns::ID builtinId, MemSpaceType spaceType)
264{
265    ASSERT(spaceType == SHARED_NON_MOVABLE || spaceType == SHARED_OLD_SPACE);
266    JSHandle<Method> method = NewSMethodForNativeFunction(func, kind, builtinId, spaceType);
267    JSHandle<JSFunction> function(NewSharedOldSpaceJSObject(hclass));
268    hclass->SetCallable(true);
269    JSFunction::InitializeWithDefaultValue(thread_, function);
270    function->SetMethod(thread_, method);
271    return function;
272}
273
274TaggedObject *ObjectFactory::NewSharedOldSpaceObject(const JSHandle<JSHClass> &hclass)
275{
276    NewSObjectHook();
277    TaggedObject *header = sHeap_->AllocateOldOrHugeObject(thread_, *hclass);
278    if (header == nullptr) {
279        LOG_ECMA(FATAL) << "ObjectFactory::NewSharedOldSpaceObject:header is nullptr";
280    }
281    uint32_t inobjPropCount = hclass->GetInlinedProperties();
282    if (inobjPropCount > 0) {
283        InitializeExtraProperties(hclass, header, inobjPropCount);
284    }
285    return header;
286}
287
288JSHandle<JSObject> ObjectFactory::NewSharedOldSpaceJSObjectWithInit(const JSHandle<JSHClass> &jshclass)
289{
290    auto obj = NewSharedOldSpaceJSObject(jshclass);
291    InitializeJSObject(obj, jshclass);
292    return obj;
293}
294
295JSHandle<JSObject> ObjectFactory::NewSharedOldSpaceJSObject(const JSHandle<JSHClass> &jshclass)
296{
297    JSHandle<JSObject> obj(thread_, JSObject::Cast(NewSharedOldSpaceObject(jshclass)));
298    JSHandle<TaggedArray> emptyArray = SharedEmptyArray();
299    obj->InitializeHash();
300    obj->SetElements(thread_, emptyArray);
301    obj->SetProperties(thread_, emptyArray);
302    return obj;
303}
304
305JSHandle<JSTaggedValue> ObjectFactory::CreateSObjectWithProperties(std::vector<PropertyDescriptor> &descs)
306{
307    JSHandle<JSHClass> hclass = JSHClass::CreateSHClass(thread_, descs);
308    JSHandle<JSObject> object = NewSharedOldSpaceJSObject(hclass);
309    JSObject::SetSProperties(thread_, object, descs);
310    JSHandle<GlobalEnv> env = vm_->GetGlobalEnv();
311    JSHandle<JSTaggedValue> objFuncProto = env->GetSObjectFunctionPrototype();
312    hclass->SetPrototype(thread_, objFuncProto);
313    hclass->SetExtensible(false);
314    return JSHandle<JSTaggedValue>(object);
315}
316
317JSHandle<TaggedArray> ObjectFactory::SharedEmptyArray() const
318{
319    return JSHandle<TaggedArray>(thread_->GlobalConstants()->GetHandledEmptyArray());
320}
321
322JSHandle<TaggedArray> ObjectFactory::CopySArray(const JSHandle<TaggedArray> &old, uint32_t oldLength,
323                                                uint32_t newLength, JSTaggedValue initVal, ElementsKind kind)
324{
325    if (newLength == 0) {
326        return SharedEmptyArray();
327    }
328    if (newLength > oldLength) {
329        return ExtendSArray(old, newLength, initVal, kind);
330    }
331
332    NewObjectHook();
333    // Shared-array does not support Mutantarray yet.
334    ASSERT(!old->GetClass()->IsMutantTaggedArray());
335
336    size_t size = TaggedArray::ComputeSize(JSTaggedValue::TaggedTypeSize(), newLength);
337    JSHClass *arrayClass = JSHClass::Cast(thread_->GlobalConstants()->GetArrayClass().GetTaggedObject());
338    TaggedObject *header = sHeap_->AllocateOldOrHugeObject(thread_, arrayClass, size);
339    JSHandle<TaggedArray> newArray(thread_, header);
340    newArray->SetLength(newLength);
341    newArray->SetExtraLength(old->GetExtraLength());
342
343    for (uint32_t i = 0; i < newLength; i++) {
344        newArray->Set(thread_, i, old->Get(i));
345    }
346
347    return newArray;
348}
349
350JSHandle<TaggedArray> ObjectFactory::ExtendSArray(const JSHandle<TaggedArray> &old, uint32_t length,
351                                                  JSTaggedValue initVal, [[maybe_unused]] ElementsKind kind)
352{
353    ASSERT(length > old->GetLength());
354    NewObjectHook();
355    size_t size = TaggedArray::ComputeSize(JSTaggedValue::TaggedTypeSize(), length);
356    JSHClass *arrayClass = nullptr;
357    // Shared-array does not support Mutantarray yet.
358    ASSERT(!old->GetClass()->IsMutantTaggedArray());
359    arrayClass = JSHClass::Cast(thread_->GlobalConstants()->GetArrayClass().GetTaggedObject());
360
361    TaggedObject *header = sHeap_->AllocateOldOrHugeObject(thread_, arrayClass, size);
362    JSHandle<TaggedArray> newArray(thread_, header);
363    newArray->SetLength(length);
364    newArray->SetExtraLength(old->GetExtraLength());
365
366    uint32_t oldLength = old->GetLength();
367    for (uint32_t i = 0; i < oldLength; i++) {
368        newArray->Set(thread_, i, old->Get(i));
369    }
370    for (uint32_t i = oldLength; i < length; i++) {
371        newArray->Set(thread_, i, initVal);
372    }
373    return newArray;
374}
375
376JSHandle<TaggedArray> ObjectFactory::NewSTaggedArrayWithoutInit(uint32_t length, MemSpaceType spaceType)
377{
378    NewSObjectHook();
379    size_t size = TaggedArray::ComputeSize(JSTaggedValue::TaggedTypeSize(), length);
380    TaggedObject *header;
381    auto arrayClass = JSHClass::Cast(thread_->GlobalConstants()->GetArrayClass().GetTaggedObject());
382    switch (spaceType) {
383        case MemSpaceType::SHARED_OLD_SPACE:
384            header = sHeap_->AllocateOldOrHugeObject(thread_, arrayClass, size);
385            break;
386        case MemSpaceType::SHARED_READ_ONLY_SPACE:
387            header = sHeap_->AllocateReadOnlyOrHugeObject(thread_, arrayClass, size);
388            break;
389        default:
390            LOG_ECMA(FATAL) << "this branch is unreachable";
391            UNREACHABLE();
392    }
393    JSHandle<TaggedArray> array(thread_, header);
394    array->SetLength(length);
395    return array;
396}
397
398JSHandle<LayoutInfo> ObjectFactory::CreateSLayoutInfo(uint32_t properties)
399{
400    uint32_t arrayLength = LayoutInfo::ComputeArrayLength(properties);
401    JSHandle<LayoutInfo> layoutInfoHandle = JSHandle<LayoutInfo>::Cast(NewSTaggedArrayWithoutInit(arrayLength));
402    layoutInfoHandle->Initialize(thread_);
403    return layoutInfoHandle;
404}
405
406JSHandle<LayoutInfo> ObjectFactory::NewSEmptyLayoutInfo()
407{
408    JSHandle<LayoutInfo> layoutInfoHandle = JSHandle<LayoutInfo>::Cast(
409        NewSTaggedArrayWithoutInit(0, MemSpaceType::SHARED_READ_ONLY_SPACE));
410    layoutInfoHandle->Initialize(thread_);
411    return layoutInfoHandle;
412}
413
414JSHandle<JSSharedArray> ObjectFactory::NewJSSArray()
415{
416    JSHandle<GlobalEnv> env = vm_->GetGlobalEnv();
417    JSHandle<JSFunction> function(env->GetSharedArrayFunction());
418    return JSHandle<JSSharedArray>(NewJSObjectByConstructor(function));
419}
420
421JSHandle<TaggedArray> ObjectFactory::NewSJsonFixedArray(size_t start, size_t length,
422                                                        const std::vector<JSHandle<JSTaggedValue>> &vec)
423{
424    if (length == 0) {
425        return SharedEmptyArray();
426    }
427
428    JSHandle<TaggedArray> array = NewTaggedArrayWithoutInit(length, MemSpaceType::SHARED_OLD_SPACE);
429    array->SetExtraLength(0);
430    for (size_t i = 0; i < length; i++) {
431        array->Set(thread_, i, vec[start + i]);
432    }
433    return array;
434}
435
436JSHandle<LayoutInfo> ObjectFactory::CopyAndReSortSLayoutInfo(const JSHandle<LayoutInfo> &old, int end, int capacity)
437{
438    ASSERT(capacity >= end);
439    JSHandle<LayoutInfo> newArr = CreateSLayoutInfo(capacity);
440    Span<struct Properties> sp(old->GetProperties(), end);
441    for (int i = 0; i < end; i++) {
442        newArr->AddKey(thread_, i, sp[i].key_, PropertyAttributes(sp[i].attr_));
443    }
444    return newArr;
445}
446
447JSHandle<TaggedArray> ObjectFactory::NewSDictionaryArray(uint32_t length)
448{
449    NewSObjectHook();
450    ASSERT(length > 0);
451    size_t size = TaggedArray::ComputeSize(JSTaggedValue::TaggedTypeSize(), length);
452    auto header = sHeap_->AllocateOldOrHugeObject(
453        thread_, JSHClass::Cast(thread_->GlobalConstants()->GetDictionaryClass().GetTaggedObject()), size);
454    JSHandle<TaggedArray> array(thread_, header);
455    array->InitializeWithSpecialValue(JSTaggedValue::Undefined(), length);
456    return array;
457}
458
459JSHandle<ProfileTypeInfoCell> ObjectFactory::NewSEmptyProfileTypeInfoCell()
460{
461    NewSObjectHook();
462    auto header = sHeap_->AllocateReadOnlyOrHugeObject(thread_,
463        JSHClass::Cast(thread_->GlobalConstants()->GetProfileTypeInfoCell0Class().GetTaggedObject()));
464    JSHandle<ProfileTypeInfoCell> profileTypeInfoCell(thread_, header);
465    profileTypeInfoCell->SetValue(thread_, JSTaggedValue::Undefined());
466    profileTypeInfoCell->SetMachineCode(thread_, JSTaggedValue::Hole());
467    profileTypeInfoCell->SetHandle(thread_, JSTaggedValue::Undefined());
468    return profileTypeInfoCell;
469}
470
471JSHandle<FunctionTemplate> ObjectFactory::NewSFunctionTemplate(
472    const JSHandle<Method> &method, const JSHandle<JSTaggedValue> &module, int32_t length)
473{
474    NewSObjectHook();
475    auto globalConstants = thread_->GlobalConstants();
476    auto header = sHeap_->AllocateOldOrHugeObject(thread_,
477        JSHClass::Cast(globalConstants->GetFunctionTemplateClass().GetTaggedObject()));
478    JSHandle<FunctionTemplate> functionTemplate(thread_, header);
479    functionTemplate->SetMethod(thread_, method);
480    functionTemplate->SetModule(thread_, module);
481    functionTemplate->SetRawProfileTypeInfo(thread_, globalConstants->GetEmptyProfileTypeInfoCell(), SKIP_BARRIER);
482    functionTemplate->SetLength(length);
483    return functionTemplate;
484}
485
486JSHandle<TaggedArray> ObjectFactory::NewSEmptyArray()
487{
488    NewSObjectHook();
489    auto header = sHeap_->AllocateReadOnlyOrHugeObject(thread_,
490        JSHClass::Cast(thread_->GlobalConstants()->GetArrayClass().GetTaggedObject()), TaggedArray::SIZE);
491    JSHandle<TaggedArray> array(thread_, header);
492    array->SetLength(0);
493    array->SetExtraLength(0);
494    return array;
495}
496
497JSHandle<MutantTaggedArray> ObjectFactory::NewSEmptyMutantArray()
498{
499    NewSObjectHook();
500    auto header = sHeap_->AllocateReadOnlyOrHugeObject(thread_,
501        JSHClass::Cast(thread_->GlobalConstants()->GetMutantTaggedArrayClass().GetTaggedObject()), TaggedArray::SIZE);
502    JSHandle<MutantTaggedArray> array(thread_, header);
503    array->SetLength(0);
504    array->SetExtraLength(0);
505    return array;
506}
507
508JSHandle<JSNativePointer> ObjectFactory::NewSJSNativePointer(void *externalPointer,
509                                                             const NativePointerCallback &callBack,
510                                                             void *data,
511                                                             bool nonMovable,
512                                                             size_t nativeBindingsize,
513                                                             NativeFlag flag)
514{
515    NewSObjectHook();
516    TaggedObject *header;
517    auto jsNativePointerClass =
518        JSHClass::Cast(thread_->GlobalConstants()->GetSJSNativePointerClass().GetTaggedObject());
519    jsNativePointerClass->SetIsJSShared(true);
520    if (nonMovable) {
521        header = sHeap_->AllocateNonMovableOrHugeObject(thread_, jsNativePointerClass);
522    } else {
523        header = sHeap_->AllocateOldOrHugeObject(thread_, jsNativePointerClass);
524    }
525    JSHandle<JSNativePointer> obj(thread_, header);
526    obj->SetExternalPointer(externalPointer);
527    obj->SetDeleter(callBack);
528    obj->SetData(data);
529    uint32_t fixedNativeBindingsize = nativeBindingsize < UINT32_MAX ? nativeBindingsize
530                                                                     : UINT32_MAX;
531    obj->SetBindingSize(fixedNativeBindingsize);
532    obj->SetNativeFlag(flag);
533
534    if (callBack != nullptr) {
535        sHeap_->IncNativeSizeAfterLastGC(fixedNativeBindingsize);
536        Runtime::GetInstance()->PushToSharedNativePointerList(static_cast<JSNativePointer *>(header));
537        // In some cases, the size of JS/TS object is too small and the native binding size is too large.
538        // Check and try trigger concurrent mark here.
539        size_t nativeSizeAfterLastGC = sHeap_->GetNativeSizeAfterLastGC();
540        if (nativeSizeAfterLastGC > sHeap_->GetNativeSizeTriggerSharedGC()) {
541            sHeap_->CollectGarbage<TriggerGCType::SHARED_GC, GCReason::ALLOCATION_FAILED>(thread_);
542        } else if (sHeap_->CheckCanTriggerConcurrentMarking(thread_) &&
543            nativeSizeAfterLastGC > sHeap_->GetNativeSizeTriggerSharedCM()) {
544            sHeap_->TriggerConcurrentMarking<TriggerGCType::SHARED_GC, GCReason::ALLOCATION_LIMIT>(thread_);
545        }
546    }
547    return obj;
548}
549
550JSHandle<JSNativePointer> ObjectFactory::NewSReadOnlyJSNativePointer(void* externalPointer)
551{
552    NewSObjectHook();
553    auto jsNativePointerClass =
554        JSHClass::Cast(thread_->GlobalConstants()->GetSJSNativePointerClass().GetTaggedObject());
555    jsNativePointerClass->SetIsJSShared(true);
556    TaggedObject* header = sHeap_->AllocateReadOnlyOrHugeObject(thread_, jsNativePointerClass);
557    JSHandle<JSNativePointer> obj(thread_, header);
558    obj->SetExternalPointer(externalPointer);
559    obj->SetDeleter(nullptr);
560    obj->SetData(nullptr);
561    obj->SetBindingSize(0U);
562    obj->SetNativeFlag(NativeFlag::NO_DIV);
563    return obj;
564}
565
566JSHandle<AccessorData> ObjectFactory::NewSInternalAccessor(void *setter, void *getter)
567{
568    NewSObjectHook();
569    TaggedObject *header = sHeap_->AllocateReadOnlyOrHugeObject(thread_,
570        JSHClass::Cast(thread_->GlobalConstants()->GetInternalAccessorClass().GetTaggedObject()));
571    JSHandle<InternalAccessor> obj(thread_, InternalAccessor::Cast(header));
572
573    obj->SetSetter(reinterpret_cast<InternalAccessor::InternalSetFunc>(setter));
574    obj->SetGetter(reinterpret_cast<InternalAccessor::InternalGetFunc>(getter));
575    return JSHandle<AccessorData>::Cast(obj);
576}
577
578JSHandle<ConstantPool> ObjectFactory::NewSConstantPool(uint32_t capacity)
579{
580    NewSObjectHook();
581    size_t size = ConstantPool::ComputeSize(capacity);
582    auto header = sHeap_->AllocateOldOrHugeObject(
583        thread_, JSHClass::Cast(sHeap_->GetGlobalConst()->GetConstantPoolClass().GetTaggedObject()), size);
584    JSHandle<ConstantPool> array(thread_, header);
585    array->InitializeWithSpecialValue(thread_, JSTaggedValue::Hole(), capacity);
586    return array;
587}
588
589JSHandle<COWTaggedArray> ObjectFactory::NewSCOWTaggedArray(uint32_t length, JSTaggedValue initVal)
590{
591    NewSObjectHook();
592    ASSERT(length > 0);
593
594    size_t size = TaggedArray::ComputeSize(JSTaggedValue::TaggedTypeSize(), length);
595    auto header = sHeap_->AllocateNonMovableOrHugeObject(
596        thread_, JSHClass::Cast(sHeap_->GetGlobalConst()->GetCOWArrayClass().GetTaggedObject()), size);
597    JSHandle<COWTaggedArray> cowArray(thread_, header);
598    cowArray->InitializeWithSpecialValue(initVal, length);
599    return cowArray;
600}
601
602JSHandle<ClassLiteral> ObjectFactory::NewSClassLiteral()
603{
604    NewSObjectHook();
605    TaggedObject *header = sHeap_->AllocateOldOrHugeObject(
606        thread_, JSHClass::Cast(sHeap_->GetGlobalConst()->GetClassLiteralClass().GetTaggedObject()));
607    JSHandle<TaggedArray> emptyArray = EmptyArray();
608
609    JSHandle<ClassLiteral> classLiteral(thread_, header);
610    classLiteral->SetArray(thread_, emptyArray);
611    classLiteral->SetIsAOTUsed(false);
612
613    return classLiteral;
614}
615
616JSHandle<ClassInfoExtractor> ObjectFactory::NewSClassInfoExtractor(
617    JSHandle<JSTaggedValue> method)
618{
619    NewSObjectHook();
620    TaggedObject *header = sHeap_->AllocateOldOrHugeObject(
621        thread_, JSHClass::Cast(sHeap_->GetGlobalConst()->GetClassInfoExtractorHClass().GetTaggedObject()));
622    JSHandle<ClassInfoExtractor> obj(thread_, header);
623    obj->ClearBitField();
624    obj->SetConstructorMethod(thread_, method.GetTaggedValue());
625    JSHandle<TaggedArray> emptyArray = EmptyArray();
626    obj->SetNonStaticKeys(thread_, emptyArray, SKIP_BARRIER);
627    obj->SetNonStaticProperties(thread_, emptyArray, SKIP_BARRIER);
628    obj->SetNonStaticElements(thread_, emptyArray, SKIP_BARRIER);
629    obj->SetStaticKeys(thread_, emptyArray, SKIP_BARRIER);
630    obj->SetStaticProperties(thread_, emptyArray, SKIP_BARRIER);
631    obj->SetStaticElements(thread_, emptyArray, SKIP_BARRIER);
632    return obj;
633}
634
635JSHandle<TaggedArray> ObjectFactory::NewSOldSpaceTaggedArray(uint32_t length, JSTaggedValue initVal)
636{
637    return NewSTaggedArray(length, initVal, MemSpaceType::SHARED_OLD_SPACE);
638}
639
640JSHandle<TaggedArray> ObjectFactory::NewSTaggedArray(uint32_t length, JSTaggedValue initVal, MemSpaceType spaceType)
641{
642    NewSObjectHook();
643    if (length == 0) {
644        return EmptyArray();
645    }
646
647    size_t size = TaggedArray::ComputeSize(JSTaggedValue::TaggedTypeSize(), length);
648    TaggedObject *header = nullptr;
649    JSHClass *arrayClass = JSHClass::Cast(thread_->GlobalConstants()->GetArrayClass().GetTaggedObject());
650    switch (spaceType) {
651        case MemSpaceType::SHARED_OLD_SPACE:
652            header = sHeap_->AllocateOldOrHugeObject(thread_, arrayClass, size);
653            break;
654        case MemSpaceType::SHARED_NON_MOVABLE:
655            header = sHeap_->AllocateNonMovableOrHugeObject(thread_, arrayClass, size);
656            break;
657        default:
658            LOG_ECMA(FATAL) << "this branch is unreachable";
659            UNREACHABLE();
660    }
661
662    JSHandle<TaggedArray> array(thread_, header);
663    array->InitializeWithSpecialValue(initVal, length);
664    return array;
665}
666
667JSHandle<JSSymbol> ObjectFactory::NewSWellKnownSymbol(const JSHandle<JSTaggedValue> &name)
668{
669    NewSObjectHook();
670    TaggedObject *header = sHeap_->AllocateNonMovableOrHugeObject(
671        thread_, JSHClass::Cast(thread_->GlobalConstants()->GetSymbolClass().GetTaggedObject()));
672    JSHandle<JSSymbol> obj(thread_, JSSymbol::Cast(header));
673    obj->SetFlags(0);
674    obj->SetWellKnownSymbol();
675    obj->SetDescription(thread_, name);
676    obj->SetHashField(SymbolTable::Hash(name.GetTaggedValue()));
677    return obj;
678}
679
680JSHandle<JSSymbol> ObjectFactory::NewSPublicSymbol(const JSHandle<JSTaggedValue> &name)
681{
682    NewObjectHook();
683    TaggedObject *header = sHeap_->AllocateNonMovableOrHugeObject(
684        thread_, JSHClass::Cast(thread_->GlobalConstants()->GetSymbolClass().GetTaggedObject()));
685    JSHandle<JSSymbol> obj(thread_, JSSymbol::Cast(header));
686    obj->SetFlags(0);
687    obj->SetDescription(thread_, name);
688    obj->SetHashField(SymbolTable::Hash(name.GetTaggedValue()));
689    return obj;
690}
691
692JSHandle<JSSymbol> ObjectFactory::NewSEmptySymbol()
693{
694    NewObjectHook();
695    TaggedObject *header = sHeap_->AllocateNonMovableOrHugeObject(
696        thread_, JSHClass::Cast(thread_->GlobalConstants()->GetSymbolClass().GetTaggedObject()));
697    JSHandle<JSSymbol> obj(thread_, JSSymbol::Cast(header));
698    obj->SetDescription(thread_, JSTaggedValue::Undefined());
699    obj->SetFlags(0);
700    obj->SetHashField(0);
701    return obj;
702}
703
704JSHandle<JSSymbol> ObjectFactory::NewSWellKnownSymbolWithChar(std::string_view description)
705{
706    JSHandle<EcmaString> string = NewFromUtf8(description);
707    return NewSWellKnownSymbol(JSHandle<JSTaggedValue>(string));
708}
709
710JSHandle<JSSymbol> ObjectFactory::NewSPublicSymbolWithChar(std::string_view description)
711{
712    JSHandle<EcmaString> string = NewFromUtf8(description);
713    return NewSPublicSymbol(JSHandle<JSTaggedValue>(string));
714}
715
716JSHandle<SourceTextModule> ObjectFactory::NewSSourceTextModule()
717{
718    NewObjectHook();
719    TaggedObject *header = sHeap_->AllocateOldOrHugeObject(thread_,
720        JSHClass::Cast(thread_->GlobalConstants()->GetSourceTextModuleClass().GetTaggedObject()));
721    JSHandle<SourceTextModule> obj(thread_, header);
722    JSTaggedValue undefinedValue = thread_->GlobalConstants()->GetUndefined();
723    obj->SetEnvironment(thread_, undefinedValue);
724    obj->SetNamespace(thread_, undefinedValue);
725    obj->SetRequestedModules(thread_, undefinedValue);
726    obj->SetImportEntries(thread_, undefinedValue);
727    obj->SetLocalExportEntries(thread_, undefinedValue);
728    obj->SetIndirectExportEntries(thread_, undefinedValue);
729    obj->SetStarExportEntries(thread_, undefinedValue);
730    obj->SetNameDictionary(thread_, undefinedValue);
731    // [[CycleRoot]]: For a module not in a cycle, this would be the module itself.
732    obj->SetCycleRoot(thread_, obj);
733    obj->SetTopLevelCapability(thread_, undefinedValue);
734    obj->SetAsyncParentModules(thread_, undefinedValue);
735    obj->SetHasTLA(false);
736    obj->SetAsyncEvaluatingOrdinal(SourceTextModule::NOT_ASYNC_EVALUATED);
737    obj->SetPendingAsyncDependencies(SourceTextModule::UNDEFINED_INDEX);
738    obj->SetDFSIndex(SourceTextModule::UNDEFINED_INDEX);
739    obj->SetDFSAncestorIndex(SourceTextModule::UNDEFINED_INDEX);
740    obj->SetEvaluationError(SourceTextModule::UNDEFINED_INDEX);
741    obj->SetStatus(ModuleStatus::UNINSTANTIATED);
742    obj->SetTypes(ModuleTypes::UNKNOWN);
743    obj->SetIsNewBcVersion(false);
744    obj->SetRegisterCounts(UINT16_MAX);
745    obj->SetLazyImportStatus(ToUintPtr(nullptr));
746    obj->SetEcmaModuleFilename(ToUintPtr(nullptr));
747    obj->SetEcmaModuleRecordName(ToUintPtr(nullptr));
748    obj->SetSharedType(SharedTypes::UNSENDABLE_MODULE);
749    obj->SetSendableEnv(thread_, undefinedValue);
750    return obj;
751}
752
753JSHandle<ModuleNamespace> ObjectFactory::NewSModuleNamespace()
754{
755    NewObjectHook();
756    JSHandle<GlobalEnv> env = vm_->GetGlobalEnv();
757    JSHandle<JSHClass> hclass = JSHandle<JSHClass>::Cast(env->GetSharedModuleNamespaceClass());
758    JSHandle<JSObject> obj = NewSharedOldSpaceJSObject(hclass);
759
760    JSHandle<ModuleNamespace> moduleNamespace = JSHandle<ModuleNamespace>::Cast(obj);
761    moduleNamespace->SetModule(thread_, JSTaggedValue::Undefined());
762    moduleNamespace->SetExports(thread_, JSTaggedValue::Undefined());
763    moduleNamespace->SetDeregisterProcession(thread_, JSTaggedValue::Undefined());
764    return moduleNamespace;
765}
766
767JSHandle<ImportEntry> ObjectFactory::NewSImportEntry(const JSHandle<JSTaggedValue> &moduleRequest,
768                                                     const JSHandle<JSTaggedValue> &importName,
769                                                     const JSHandle<JSTaggedValue> &localName)
770{
771    NewObjectHook();
772    TaggedObject *header = sHeap_->AllocateOldOrHugeObject(thread_,
773        JSHClass::Cast(thread_->GlobalConstants()->GetImportEntryClass().GetTaggedObject()));
774    JSHandle<ImportEntry> obj(thread_, header);
775    obj->SetModuleRequest(thread_, moduleRequest);
776    obj->SetImportName(thread_, importName);
777    obj->SetLocalName(thread_, localName);
778    return obj;
779}
780
781JSHandle<LocalExportEntry> ObjectFactory::NewSLocalExportEntry(const JSHandle<JSTaggedValue> &exportName,
782    const JSHandle<JSTaggedValue> &localName, const uint32_t index)
783{
784    NewObjectHook();
785    TaggedObject *header = sHeap_->AllocateOldOrHugeObject(thread_,
786        JSHClass::Cast(thread_->GlobalConstants()->GetLocalExportEntryClass().GetTaggedObject()));
787    JSHandle<LocalExportEntry> obj(thread_, header);
788    obj->SetExportName(thread_, exportName);
789    obj->SetLocalName(thread_, localName);
790    obj->SetLocalIndex(index);
791    return obj;
792}
793
794JSHandle<IndirectExportEntry> ObjectFactory::NewSIndirectExportEntry(const JSHandle<JSTaggedValue> &exportName,
795                                                                     const JSHandle<JSTaggedValue> &moduleRequest,
796                                                                     const JSHandle<JSTaggedValue> &importName)
797{
798    NewObjectHook();
799    TaggedObject *header = sHeap_->AllocateOldOrHugeObject(thread_,
800        JSHClass::Cast(thread_->GlobalConstants()->GetIndirectExportEntryClass().GetTaggedObject()));
801    JSHandle<IndirectExportEntry> obj(thread_, header);
802    obj->SetExportName(thread_, exportName);
803    obj->SetModuleRequest(thread_, moduleRequest);
804    obj->SetImportName(thread_, importName);
805    return obj;
806}
807
808JSHandle<StarExportEntry> ObjectFactory::NewSStarExportEntry(const JSHandle<JSTaggedValue> &moduleRequest)
809{
810    NewObjectHook();
811    TaggedObject *header = sHeap_->AllocateOldOrHugeObject(thread_,
812        JSHClass::Cast(thread_->GlobalConstants()->GetStarExportEntryClass().GetTaggedObject()));
813    JSHandle<StarExportEntry> obj(thread_, header);
814    obj->SetModuleRequest(thread_, moduleRequest);
815    return obj;
816}
817
818JSHandle<ResolvedIndexBinding> ObjectFactory::NewSResolvedIndexBindingRecord()
819{
820    JSHandle<JSTaggedValue> undefinedValue = thread_->GlobalConstants()->GetHandledUndefined();
821    JSHandle<SourceTextModule> ecmaModule(undefinedValue);
822    int32_t index = 0;
823    return NewSResolvedIndexBindingRecord(ecmaModule, index);
824}
825
826JSHandle<ResolvedIndexBinding> ObjectFactory::NewSResolvedIndexBindingRecord(const JSHandle<SourceTextModule> &module,
827                                                                             int32_t index)
828{
829    NewObjectHook();
830    TaggedObject *header = sHeap_->AllocateOldOrHugeObject(thread_,
831        JSHClass::Cast(thread_->GlobalConstants()->GetResolvedIndexBindingClass().GetTaggedObject()));
832    JSHandle<ResolvedIndexBinding> obj(thread_, header);
833    obj->SetModule(thread_, module);
834    obj->SetIndex(index);
835    return obj;
836}
837
838JSHandle<ResolvedBinding> ObjectFactory::NewSResolvedBindingRecord()
839{
840    JSHandle<JSTaggedValue> undefinedValue = thread_->GlobalConstants()->GetHandledUndefined();
841    JSHandle<SourceTextModule> ecmaModule(undefinedValue);
842    JSHandle<JSTaggedValue> bindingName(undefinedValue);
843    return NewSResolvedBindingRecord(ecmaModule, bindingName);
844}
845
846JSHandle<ResolvedBinding> ObjectFactory::NewSResolvedBindingRecord(const JSHandle<SourceTextModule> &module,
847                                                                   const JSHandle<JSTaggedValue> &bindingName)
848{
849    NewObjectHook();
850    TaggedObject *header = sHeap_->AllocateOldOrHugeObject(thread_,
851        JSHClass::Cast(thread_->GlobalConstants()->GetResolvedBindingClass().GetTaggedObject()));
852    JSHandle<ResolvedBinding> obj(thread_, header);
853    obj->SetModule(thread_, module);
854    obj->SetBindingName(thread_, bindingName);
855    return obj;
856}
857
858JSHandle<ResolvedRecordIndexBinding> ObjectFactory::NewSResolvedRecordIndexBindingRecord()
859{
860    JSHandle<JSTaggedValue> undefinedValue = thread_->GlobalConstants()->GetHandledUndefined();
861    JSHandle<EcmaString> ecmaModule(undefinedValue);
862    JSHandle<EcmaString> fileName(undefinedValue);
863    int32_t index = 0;
864    return NewSResolvedRecordIndexBindingRecord(ecmaModule, fileName, index);
865}
866
867JSHandle<ResolvedRecordIndexBinding> ObjectFactory::NewSResolvedRecordIndexBindingRecord(
868    const JSHandle<EcmaString> &moduleRecord, const JSHandle<EcmaString> &abcFileName, int32_t index)
869{
870    NewObjectHook();
871    TaggedObject *header = sHeap_->AllocateOldOrHugeObject(thread_,
872        JSHClass::Cast(thread_->GlobalConstants()->GetResolvedRecordIndexBindingClass().GetTaggedObject()));
873    JSHandle<ResolvedRecordIndexBinding> obj(thread_, header);
874    obj->SetModuleRecord(thread_, moduleRecord);
875    obj->SetAbcFileName(thread_, abcFileName);
876    obj->SetIndex(index);
877    return obj;
878}
879
880JSHandle<ResolvedRecordBinding> ObjectFactory::NewSResolvedRecordBindingRecord()
881{
882    JSHandle<JSTaggedValue> undefinedValue = thread_->GlobalConstants()->GetHandledUndefined();
883    JSHandle<EcmaString> ecmaModule(undefinedValue);
884    JSHandle<JSTaggedValue> bindingName(undefinedValue);
885    return NewSResolvedRecordBindingRecord(ecmaModule, bindingName);
886}
887
888JSHandle<ResolvedRecordBinding> ObjectFactory::NewSResolvedRecordBindingRecord(
889    const JSHandle<EcmaString> &moduleRecord, const JSHandle<JSTaggedValue> &bindingName)
890{
891    NewObjectHook();
892    TaggedObject *header = sHeap_->AllocateOldOrHugeObject(thread_,
893        JSHClass::Cast(thread_->GlobalConstants()->GetResolvedRecordBindingClass().GetTaggedObject()));
894    JSHandle<ResolvedRecordBinding> obj(thread_, header);
895    obj->SetModuleRecord(thread_, moduleRecord);
896    obj->SetBindingName(thread_, bindingName);
897    return obj;
898}
899
900JSHandle<AOTLiteralInfo> ObjectFactory::NewSAOTLiteralInfo(uint32_t length, JSTaggedValue initVal)
901{
902    NewObjectHook();
903    size_t size = AOTLiteralInfo::ComputeSize(length);
904    auto header = sHeap_->AllocateOldOrHugeObject(thread_,
905        JSHClass::Cast(sHeap_->GetGlobalConst()->GetAOTLiteralInfoClass().GetTaggedObject()), size);
906
907    JSHandle<AOTLiteralInfo> aotLiteralInfo(thread_, header);
908    aotLiteralInfo->InitializeWithSpecialValue(initVal, length);
909    return aotLiteralInfo;
910}
911
912JSHandle<SendableEnv> ObjectFactory::NewSendableEnv(int numSlots)
913{
914    NewObjectHook();
915    size_t size = SendableEnv::ComputeSize(numSlots);
916    auto header = sHeap_->AllocateOldOrHugeObject(thread_,
917        JSHClass::Cast(sHeap_->GetGlobalConst()->GetSendableEnvClass().GetTaggedObject()), size);
918    JSHandle<SendableEnv> array(thread_, header);
919    array->InitializeWithSpecialValue(JSTaggedValue::Hole(), numSlots + SendableEnv::SENDABLE_RESERVED_ENV_LENGTH);
920    return array;
921}
922
923JSHandle<JSFunction> ObjectFactory::NewJSSendableFunction(const JSHandle<Method> &methodHandle)
924{
925    JSHandle<GlobalEnv> env = vm_->GetGlobalEnv();
926    FunctionKind kind = methodHandle->GetFunctionKind();
927    JSHandle<JSHClass> hclass;
928    switch (kind) {
929        case FunctionKind::ASYNC_FUNCTION: {
930            hclass = JSHandle<JSHClass>::Cast(env->GetSAsyncFunctionClass());
931            break;
932        }
933        case FunctionKind::BASE_CONSTRUCTOR: {
934            hclass = JSHandle<JSHClass>::Cast(env->GetSFunctionClassWithProto());
935            break;
936        }
937        default:
938            LOG_ECMA(FATAL) << "this branch is unreachable";
939            UNREACHABLE();
940    }
941
942    JSHandle<JSFunction> func = NewSFunctionByHClass(methodHandle, hclass);
943    ASSERT_NO_ABRUPT_COMPLETION(thread_);
944    return func;
945}
946}  // namespace panda::ecmascript
947