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