1 /* 2 * Copyright (c) 2021 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 #ifndef ECMASCRIPT_TS_TYPES_TS_MANAGER_H 17 #define ECMASCRIPT_TS_TYPES_TS_MANAGER_H 18 19 #include "ecmascript/compiler/bytecode_info_collector.h" 20 #include "ecmascript/compiler/compilation_driver.h" 21 #include "ecmascript/js_handle.h" 22 #include "ecmascript/js_tagged_value-inl.h" 23 #include "ecmascript/ts_types/global_ts_type_ref.h" 24 #include "ecmascript/ts_types/ts_obj_layout_info.h" 25 #include "ecmascript/ts_types/global_type_info.h" 26 27 namespace panda::ecmascript { 28 enum class PropertyType : uint8_t { 29 NORMAL = 0, 30 STATIC, 31 OTHERS, 32 }; 33 34 /* Since AOT allows loading lib_ark_builtins.d.ts optionally, the localId of the GlobalTSTypeRef 35 * (abbreviated as GT) of one builtin object will be different in different cases. 36 * 37 * In case where AOT does not load lib_ark_builtins.d.ts, builtin objects will be assigned localIds 38 * according to the following enum order. For example, the GT of FUNCTION will be (1, 21), where 1 39 * is the index of builtin TSTypeTable. Note that in this case, it is prohibited to get TSType from 40 * builtin TSTypeTable. 41 * 42 * In case where AOT has loaded lib_ark_builtins.d.ts, builtin objects will be assigned localIds in 43 * the order in which they appear in bytecodes. To identify types of builtin objects, the following 44 * enum is required as a parameter to the TSManager::GetBuiltinOffset to help to get the GT of some 45 * builtin object. 46 */ 47 enum class BuiltinTypeId : uint8_t { // keep the same with enum BuiltinType in ets_frontend 48 NUM_INDEX_IN_SUMMARY = 0, 49 BUILTIN_OFFSET = 20, 50 FUNCTION, 51 RANGE_ERROR, 52 ERROR, 53 OBJECT, 54 SYNTAX_ERROR, 55 TYPE_ERROR, 56 REFERENCE_ERROR, 57 URI_ERROR, 58 SYMBOL, 59 EVAL_ERROR, 60 NUMBER, 61 PARSE_FLOAT, 62 DATE, 63 BOOLEAN, 64 BIG_INT, 65 PARSE_INT, 66 WEAK_MAP, 67 REG_EXP, 68 SET, 69 MAP, 70 WEAK_REF, 71 WEAK_SET, 72 FINALIZATION_REGISTRY, 73 ARRAY, 74 UINT8_CLAMPED_ARRAY, 75 UINT8_ARRAY, 76 TYPED_ARRAY, 77 INT8_ARRAY, 78 UINT16_ARRAY, 79 UINT32_ARRAY, 80 INT16_ARRAY, 81 INT32_ARRAY, 82 FLOAT32_ARRAY, 83 FLOAT64_ARRAY, 84 BIG_INT64_ARRAY, 85 BIG_UINT64_ARRAY, 86 SHARED_ARRAY_BUFFER, 87 DATA_VIEW, 88 STRING, 89 ARRAY_BUFFER, 90 EVAL, 91 IS_FINITE, 92 ARK_PRIVATE, 93 PRINT, 94 DECODE_URI, 95 DECODE_URI_COMPONENT, 96 IS_NAN, 97 ENCODE_URI, 98 JS_NAN, 99 GLOBAL_THIS, 100 ENCODE_URI_COMPONENT, 101 JS_INFINITY, 102 MATH, 103 JSON, 104 ATOMICS, 105 UNDEFINED, 106 REFLECT, 107 PROMISE, 108 PROXY, 109 GENERATOR_FUNCTION, 110 INTL, 111 NUM_OF_BUILTIN_TYPES = INTL - BUILTIN_OFFSET, 112 TYPED_ARRAY_FIRST = UINT8_CLAMPED_ARRAY, 113 TYPED_ARRAY_LAST = BIG_UINT64_ARRAY, 114 }; 115 116 struct ModuleInfo { 117 const JSPandaFile *jsPandaFile {nullptr}; // there may be serval merged abc files. 118 const CString recordName {""}; // distinguish different files which are all merged to one abc file. 119 uint32_t index {0}; // bytecode "stmoudlevar index", exportVar index is unique in the same record. 120 bool operator < (const ModuleInfo &moduleInfo) const 121 { 122 if (index < moduleInfo.index) { 123 return true; 124 } 125 if (index == moduleInfo.index && recordName < moduleInfo.recordName) { 126 return true; 127 } 128 if (index == moduleInfo.index && recordName == moduleInfo.recordName && 129 jsPandaFile < moduleInfo.jsPandaFile) { 130 return true; 131 } 132 return false; 133 } 134 }; 135 136 class TSModuleTable : public TaggedArray { 137 public: 138 // Each TSTypeTable occupies three positions 139 static constexpr int ELEMENTS_LENGTH = 3; 140 static constexpr int MODULE_REQUEST_OFFSET = 1; 141 static constexpr int SORT_ID_OFFSET = 2; 142 static constexpr int TYPE_TABLE_OFFSET = 3; 143 // Reserve a position which is used to store the number of TSTypeTables and a TSTypeTable storage space 144 static constexpr int INITIAL_CAPACITY = ELEMENTS_LENGTH + 1; 145 static constexpr int NUMBER_OF_TABLES_INDEX = 0; 146 static constexpr int INCREASE_CAPACITY_RATE = 2; 147 static constexpr int NOT_FOUND = -1; 148 Cast(TaggedObject * object)149 static TSModuleTable *Cast(TaggedObject *object) 150 { 151 ASSERT(JSTaggedValue(object).IsTaggedArray()); 152 return static_cast<TSModuleTable *>(object); 153 } 154 155 JSHandle<EcmaString> GetModuleRequestByModuleId(JSThread *thread, int entry) const; 156 157 int GetGlobalModuleID(JSThread *thread, JSHandle<EcmaString> amiPath) const; 158 GetNumberOfTSTypeTables()159 inline int GetNumberOfTSTypeTables() const 160 { 161 return Get(NUMBER_OF_TABLES_INDEX).GetInt(); 162 } 163 SetNumberOfTSTypeTables(JSThread * thread,int num)164 inline void SetNumberOfTSTypeTables(JSThread *thread, int num) 165 { 166 Set(thread, NUMBER_OF_TABLES_INDEX, JSTaggedValue(num)); 167 } 168 GetTSTypeTableOffset(int entry)169 static uint32_t GetTSTypeTableOffset(int entry) 170 { 171 return entry * ELEMENTS_LENGTH + TYPE_TABLE_OFFSET; 172 } 173 GetModuleRequestOffset(int entry)174 static int GetModuleRequestOffset(int entry) 175 { 176 return entry * ELEMENTS_LENGTH + MODULE_REQUEST_OFFSET; 177 } 178 GetSortIdOffset(int entry)179 static int GetSortIdOffset(int entry) 180 { 181 return entry * ELEMENTS_LENGTH + SORT_ID_OFFSET; 182 } 183 }; 184 185 class TSManager { 186 public: 187 explicit TSManager(EcmaVM *vm); 188 ~TSManager() = default; 189 190 void Initialize(); 191 192 void Dump(); 193 194 void Iterate(const RootVisitor &v); 195 GetTSModuleTable()196 JSHandle<TSModuleTable> GetTSModuleTable() const 197 { 198 return JSHandle<TSModuleTable>(reinterpret_cast<uintptr_t>(&globalModuleTable_)); 199 } 200 SetTSModuleTable(JSHandle<TSModuleTable> table)201 void SetTSModuleTable(JSHandle<TSModuleTable> table) 202 { 203 globalModuleTable_ = table.GetTaggedValue(); 204 } 205 206 JSHandle<TSTypeTable> GetTSTypeTable(int entry) const; 207 208 void SetTSTypeTable(const JSHandle<TSTypeTable> &table, int tableId) const; 209 210 void GenerateBuiltinSummary(); 211 GetBuiltinOffset(uint32_t index)212 inline uint32_t GetBuiltinOffset(uint32_t index) const 213 { 214 if (index == static_cast<uint32_t>(BuiltinTypeId::NUM_INDEX_IN_SUMMARY)) { 215 return builtinOffsets_[index]; 216 } 217 return builtinOffsets_[index - static_cast<uint32_t>(BuiltinTypeId::BUILTIN_OFFSET)]; 218 } 219 GetPropType(GlobalTSTypeRef gt,JSTaggedValue propertyName)220 inline GlobalTSTypeRef PUBLIC_API GetPropType(GlobalTSTypeRef gt, JSTaggedValue propertyName) const 221 { 222 return GetPropType(gt, JSHandle<JSTaggedValue>(thread_, propertyName)); 223 } 224 225 GlobalTSTypeRef PUBLIC_API GetPropType(GlobalTSTypeRef gt, const uint64_t key) const; 226 227 GlobalTSTypeRef PUBLIC_API GetIndexSignType(GlobalTSTypeRef objType, kungfu::GateType indexType) const; 228 CreateClassInstanceType(kungfu::GateType gateType)229 inline GlobalTSTypeRef PUBLIC_API CreateClassInstanceType(kungfu::GateType gateType) 230 { 231 GlobalTSTypeRef gt = gateType.GetGTRef(); 232 return CreateClassInstanceType(gt); 233 } 234 235 GlobalTSTypeRef PUBLIC_API CreateClassInstanceType(GlobalTSTypeRef gt); 236 GetClassType(kungfu::GateType gateType)237 inline GlobalTSTypeRef PUBLIC_API GetClassType(kungfu::GateType gateType) 238 { 239 GlobalTSTypeRef gt = gateType.GetGTRef(); 240 return GetClassType(gt); 241 } 242 243 GlobalTSTypeRef PUBLIC_API GetClassType(GlobalTSTypeRef classInstanceGT) const; 244 245 JSHandle<TSClassType> GetExtendedClassType(JSHandle<TSClassType> classType) const; 246 247 TSClassType* GetExtendedClassType(const TSClassType *classType) const; 248 249 uint32_t PUBLIC_API GetUnionTypeLength(GlobalTSTypeRef gt) const; 250 251 GlobalTSTypeRef PUBLIC_API GetUnionTypeByIndex(GlobalTSTypeRef gt, int index) const; 252 253 GlobalTSTypeRef PUBLIC_API GetOrCreateUnionType(CVector<GlobalTSTypeRef> unionTypeVec); 254 255 uint32_t PUBLIC_API GetFunctionTypeLength(GlobalTSTypeRef gt) const; 256 257 GlobalTSTypeRef PUBLIC_API GetOrCreateTSIteratorInstanceType(TSRuntimeType runtimeType, GlobalTSTypeRef elementGt); 258 259 GlobalTSTypeRef PUBLIC_API GetIteratorInstanceElementGt(GlobalTSTypeRef gt) const; 260 GetIteratorInstanceElementGt(kungfu::GateType gateType)261 inline GlobalTSTypeRef PUBLIC_API GetIteratorInstanceElementGt(kungfu::GateType gateType) const 262 { 263 GlobalTSTypeRef gt = GlobalTSTypeRef(gateType.GetGTRef()); 264 return GetIteratorInstanceElementGt(gt); 265 } 266 267 bool PUBLIC_API IsStaticFunc(GlobalTSTypeRef gt) const; 268 269 bool PUBLIC_API GetSuperGateType(kungfu::GateType &gateType) const; 270 271 GlobalTSTypeRef PUBLIC_API GetSuperPropType(GlobalTSTypeRef gt, 272 JSHandle<JSTaggedValue> propertyName, 273 PropertyType propType) const; 274 GetSuperPropType(GlobalTSTypeRef gt,JSTaggedValue propertyName,PropertyType propType)275 inline GlobalTSTypeRef PUBLIC_API GetSuperPropType(GlobalTSTypeRef gt, 276 JSTaggedValue propertyName, 277 PropertyType propType) const 278 { 279 return GetSuperPropType(gt, JSHandle<JSTaggedValue>(vm_->GetJSThread(), propertyName), 280 propType); 281 } 282 283 GlobalTSTypeRef PUBLIC_API GetSuperPropType(GlobalTSTypeRef gt, 284 const uint64_t key, 285 PropertyType propType) const; 286 287 GlobalTSTypeRef PUBLIC_API GetFuncParameterTypeGT(GlobalTSTypeRef gt, int index) const; 288 289 GlobalTSTypeRef PUBLIC_API GetFuncThisGT(GlobalTSTypeRef gt) const; 290 291 void PUBLIC_API SetFuncMethodOffset(GlobalTSTypeRef gt, uint32_t methodOffset); 292 293 uint32_t PUBLIC_API GetFuncMethodOffset(GlobalTSTypeRef gt) const; 294 295 bool PUBLIC_API IsGetterSetterFunc(GlobalTSTypeRef gt) const; 296 297 bool IsAbstractMethod(GlobalTSTypeRef gt) const; 298 299 bool IsMethodSignature(GlobalTSTypeRef gt) const; 300 bool CanFastCall(GlobalTSTypeRef gt) const; 301 bool IsNoGC(GlobalTSTypeRef gt) const; 302 bool MethodOffsetIsVaild(GlobalTSTypeRef gt) const; 303 bool FastCallFlagIsVaild(GlobalTSTypeRef gt) const; 304 GetFuncReturnValueTypeGT(kungfu::GateType gateType)305 inline GlobalTSTypeRef PUBLIC_API GetFuncReturnValueTypeGT(kungfu::GateType gateType) const 306 { 307 GlobalTSTypeRef gt = gateType.GetGTRef(); 308 return GetFuncReturnValueTypeGT(gt); 309 } 310 311 GlobalTSTypeRef PUBLIC_API GetFuncReturnValueTypeGT(GlobalTSTypeRef gt) const; 312 313 std::string PUBLIC_API GetFuncName(kungfu::GateType gt) const; 314 315 int PUBLIC_API GetMethodIndex(GlobalTSTypeRef gt) const; 316 GetArrayParameterTypeGT(kungfu::GateType gateType)317 inline GlobalTSTypeRef PUBLIC_API GetArrayParameterTypeGT(kungfu::GateType gateType) const 318 { 319 GlobalTSTypeRef gt = gateType.GetGTRef(); 320 return GetArrayParameterTypeGT(gt); 321 } 322 323 GlobalTSTypeRef PUBLIC_API GetArrayParameterTypeGT(GlobalTSTypeRef gt) const; 324 AssertTypes()325 bool PUBLIC_API AssertTypes() const 326 { 327 return assertTypes_; 328 } 329 GetTypeThreshold()330 double PUBLIC_API GetTypeThreshold() const 331 { 332 return typeThreshold_; 333 } 334 IsBuiltinsDTSEnabled()335 bool IsBuiltinsDTSEnabled() const 336 { 337 return vm_->GetJSOptions().WasSetBuiltinsDTS(); 338 } 339 GetBuiltinsDTS()340 CString GetBuiltinsDTS() const 341 { 342 std::string fileName = vm_->GetJSOptions().GetBuiltinsDTS(); 343 return CString(fileName); 344 } 345 346 void AddArrayTSElements(panda_file::File::EntityId id, JSHandle<TaggedArray> &elements); 347 348 void AddArrayTSHClass(panda_file::File::EntityId id, JSHandle<JSHClass> &ihclass); 349 350 void AddInstanceTSHClass(GlobalTSTypeRef gt, JSHandle<JSHClass> &ihclass); 351 352 void AddConstructorTSHClass(GlobalTSTypeRef gt, JSHandle<JSHClass> &constructorHClass); 353 354 JSTaggedValue GetInstanceTSHClass(const JSHandle<TSClassType> &classType) const; 355 356 bool HasTSHClass(const JSHandle<TSClassType> &classType) const; 357 358 bool HasTSHClass(const TSClassType *classType) const; 359 360 JSHandle<JSTaggedValue> GetTSType(const GlobalTSTypeRef >) const; 361 362 std::string PUBLIC_API GetTypeStr(kungfu::GateType gateType) const; 363 364 int PUBLIC_API GetElementsIndexByArrayType(const kungfu::GateType &gateType, 365 const panda_file::File::EntityId id); 366 367 int PUBLIC_API GetHClassIndexByArrayType(const kungfu::GateType &gateType, 368 const panda_file::File::EntityId id); 369 370 int PUBLIC_API GetHClassIndexByObjectType(const kungfu::GateType &gateType); 371 372 int PUBLIC_API GetHClassIndexByInstanceGateType(const kungfu::GateType &gateType); 373 374 int PUBLIC_API GetConstructorHClassIndexByClassGateType(const kungfu::GateType &gateType); 375 376 int PUBLIC_API GetHClassIndexByClassGateType(const kungfu::GateType &gateType); 377 378 JSTaggedValue GetTSHClass(const kungfu::GateType &gateType) const; 379 380 JSTaggedValue PUBLIC_API GetValueFromCache(uint32_t index); 381 382 GlobalTSTypeRef PUBLIC_API CreateNamespaceType(); 383 384 void AddNamespacePropType(kungfu::GateType objType, JSTaggedValue name, kungfu::GateType valueType); 385 IsUserDefinedClassTypeKind(const kungfu::GateType & gateType)386 inline bool IsUserDefinedClassTypeKind(const kungfu::GateType &gateType) const 387 { 388 GlobalTSTypeRef gt = gateType.GetGTRef(); 389 return IsUserDefinedClassTypeKind(gt); 390 } 391 IsUserDefinedClassTypeKind(const GlobalTSTypeRef & gt)392 inline bool IsUserDefinedClassTypeKind(const GlobalTSTypeRef >) const 393 { 394 return IsClassTypeKind(gt) && (!gt.IsBuiltinModule()); 395 } 396 StoreNamespaceType(const uint32_t methodOffset,const kungfu::GateType type)397 inline void StoreNamespaceType(const uint32_t methodOffset, const kungfu::GateType type) 398 { 399 methodOffsetToType_.insert(std::make_pair(methodOffset, type)); 400 } 401 GetNamespaceObjType(const uint32_t methodOffset)402 inline kungfu::GateType GetNamespaceObjType(const uint32_t methodOffset) const 403 { 404 ASSERT(HasInferredNamespaceType(methodOffset)); 405 return methodOffsetToType_.at(methodOffset); 406 } 407 HasInferredNamespaceType(const uint32_t methodOffset)408 inline bool HasInferredNamespaceType(const uint32_t methodOffset) const 409 { 410 return methodOffsetToType_.find(methodOffset) != methodOffsetToType_.end(); 411 } 412 GetEcmaVM()413 EcmaVM *GetEcmaVM() const 414 { 415 return vm_; 416 } 417 GetThread()418 JSThread *GetThread() const 419 { 420 return thread_; 421 } 422 423 #define IS_TSTYPEKIND_METHOD_LIST(V) \ 424 V(Primitive, TSTypeKind::PRIMITIVE) \ 425 V(Class, TSTypeKind::CLASS) \ 426 V(ClassInstance, TSTypeKind::CLASS_INSTANCE) \ 427 V(Function, TSTypeKind::FUNCTION) \ 428 V(Union, TSTypeKind::UNION) \ 429 V(Array, TSTypeKind::ARRAY) \ 430 V(Object, TSTypeKind::OBJECT) \ 431 V(Import, TSTypeKind::IMPORT) \ 432 V(Interface, TSTypeKind::INTERFACE) \ 433 V(IteratorInstance, TSTypeKind::ITERATOR_INSTANCE) \ 434 V(Namespace, TSTypeKind::NAMESPACE) 435 436 #define IS_TSTYPEKIND(NAME, TSTYPEKIND) \ 437 inline bool PUBLIC_API Is##NAME##TypeKind(const kungfu::GateType &gateType) const \ 438 { \ 439 GlobalTSTypeRef gt = gateType.GetGTRef(); \ 440 return GetTypeKind(gt) == (TSTYPEKIND); \ 441 } \ 442 \ 443 inline bool PUBLIC_API Is##NAME##TypeKind(const GlobalTSTypeRef >) const \ 444 { \ 445 return GetTypeKind(gt) == (TSTYPEKIND); \ 446 } 447 448 IS_TSTYPEKIND_METHOD_LIST(IS_TSTYPEKIND) 449 #undef IS_TSTYPEKIND 450 451 bool PUBLIC_API IsBuiltinInstanceType(BuiltinTypeId id, kungfu::GateType gateType) const; 452 453 bool PUBLIC_API IsTypedArrayType(kungfu::GateType gateType) const; 454 455 bool PUBLIC_API IsValidTypedArrayType(kungfu::GateType gateType) const; 456 IsBuiltinObjectType(kungfu::GateType gateType)457 inline bool PUBLIC_API IsBuiltinObjectType(kungfu::GateType gateType) const 458 { 459 return gateType.GetGTRef().IsBuiltinModule() && IsClassTypeKind(gateType); 460 } 461 462 bool PUBLIC_API IsIntTypedArrayType(kungfu::GateType gateType) const; 463 464 bool PUBLIC_API IsDoubleTypedArrayType(kungfu::GateType gateType) const; 465 466 BuiltinTypeId PUBLIC_API GetTypedArrayBuiltinId(kungfu::GateType gateType) const; 467 468 static const std::vector<BuiltinTypeId> &GetValidTypedArrayIds(); 469 470 inline void AddElementToIdGTMap(const GlobalTypeID &id, GlobalTSTypeRef gt, 471 const CString &recordName = "", bool isImportType = false) 472 { 473 auto it = idGTMap_.find(id); 474 if (it != idGTMap_.end()) { 475 it->second = gt; 476 } else { 477 idGTMap_.emplace(id, gt); 478 } 479 if (!isImportType && !id.IsPGOType()) { 480 auto value = std::make_pair(recordName, id.GetTypeId()); 481 gtLiteralOffsetMap_.emplace(gt, value); 482 } 483 } 484 HasCreatedGT(const GlobalTypeID & id)485 inline bool HasCreatedGT(const GlobalTypeID &id) const 486 { 487 return idGTMap_.find(id) != idGTMap_.end(); 488 } 489 GetGTByGlobalTypeID(const GlobalTypeID & id)490 inline GlobalTSTypeRef GetGTByGlobalTypeID(const GlobalTypeID &id) const 491 { 492 return idGTMap_.at(id); 493 } 494 HasOffsetFromGT(GlobalTSTypeRef gt)495 inline bool HasOffsetFromGT(GlobalTSTypeRef gt) const 496 { 497 return gtLiteralOffsetMap_.find(gt) != gtLiteralOffsetMap_.end(); 498 } 499 GetOffsetFromGt(GlobalTSTypeRef gt)500 inline std::pair<CString, uint32_t> GetOffsetFromGt(GlobalTSTypeRef gt) const 501 { 502 return gtLiteralOffsetMap_.at(gt); 503 } 504 AddTypeToModuleVarGtMap(const JSPandaFile * jsPandaFile,const CString & recordName,uint32_t index,GlobalTSTypeRef gt)505 inline void AddTypeToModuleVarGtMap(const JSPandaFile *jsPandaFile, const CString &recordName, 506 uint32_t index, GlobalTSTypeRef gt) 507 { 508 ModuleInfo key = {jsPandaFile, recordName, index}; 509 if (moduleVarGtMap_.find(key) == moduleVarGtMap_.end()) { 510 moduleVarGtMap_.emplace(key, gt); 511 } else { 512 moduleVarGtMap_[key] = gt; 513 } 514 } 515 HasExportGT(const JSPandaFile * jsPandaFile,const CString & recordName,uint32_t index)516 inline bool HasExportGT(const JSPandaFile *jsPandaFile, const CString &recordName, 517 uint32_t index) const 518 { 519 ModuleInfo key = {jsPandaFile, recordName, index}; 520 return moduleVarGtMap_.find(key) != moduleVarGtMap_.end(); 521 } 522 GetGTFromModuleMap(const JSPandaFile * jsPandaFile,const CString & recordName,uint32_t index)523 inline GlobalTSTypeRef GetGTFromModuleMap(const JSPandaFile *jsPandaFile, const CString &recordName, 524 uint32_t index) const 525 { 526 ModuleInfo key = {jsPandaFile, recordName, index}; 527 return moduleVarGtMap_.at(key); 528 } 529 AddResolvedExportTable(const JSPandaFile * jsPandaFile,const CString & recordName,JSTaggedValue exportTable)530 inline void AddResolvedExportTable(const JSPandaFile *jsPandaFile, const CString &recordName, 531 JSTaggedValue exportTable) 532 { 533 auto key = std::make_pair(jsPandaFile, recordName); 534 if (resolvedExportTable_.find(key) == resolvedExportTable_.end()) { 535 resolvedExportTable_.emplace(key, exportTable); 536 } else { 537 resolvedExportTable_[key] = exportTable; 538 } 539 } 540 HasResolvedExportTable(const JSPandaFile * jsPandaFile,const CString & recordName)541 inline bool HasResolvedExportTable(const JSPandaFile *jsPandaFile, const CString &recordName) const 542 { 543 auto key = std::make_pair(jsPandaFile, recordName); 544 return resolvedExportTable_.find(key) != resolvedExportTable_.end(); 545 } 546 GetResolvedExportTable(const JSPandaFile * jsPandaFile,const CString & recordName)547 inline JSTaggedValue GetResolvedExportTable(const JSPandaFile *jsPandaFile, const CString &recordName) const 548 { 549 auto key = std::make_pair(jsPandaFile, recordName); 550 return resolvedExportTable_.at(key); 551 } 552 IsTSIterator(GlobalTSTypeRef gt)553 bool IsTSIterator(GlobalTSTypeRef gt) const 554 { 555 uint32_t l = gt.GetLocalId(); 556 return gt.IsRuntimeModule() && (l == static_cast<uint32_t>(TSRuntimeType::ITERATOR)); 557 } 558 IsTSIteratorResult(GlobalTSTypeRef gt)559 bool IsTSIteratorResult(GlobalTSTypeRef gt) const 560 { 561 uint32_t l = gt.GetLocalId(); 562 return gt.IsRuntimeModule() && (l == static_cast<uint32_t>(TSRuntimeType::ITERATOR_RESULT)); 563 } 564 565 void PUBLIC_API SetCurConstantPool(const JSPandaFile *jsPandaFile, uint32_t methodOffset); 566 567 int32_t PUBLIC_API GetConstantPoolIDByMethodOffset(const JSPandaFile *jsPandaFile, uint32_t methodOffset); 568 GetConstantPool()569 JSHandle<JSTaggedValue> PUBLIC_API GetConstantPool() const 570 { 571 return JSHandle<JSTaggedValue>(uintptr_t(&curCP_)); 572 } 573 574 JSTaggedValue PUBLIC_API GetStringFromConstantPool(const uint16_t stringId) const; 575 GetStdStringFromConstantPool(const uint16_t stringId)576 inline std::string PUBLIC_API GetStdStringFromConstantPool(const uint16_t stringId) const 577 { 578 JSTaggedValue str = GetStringFromConstantPool(stringId); 579 return EcmaStringAccessor(str).ToStdString(StringConvertedUsage::LOGICOPERATION); 580 } 581 582 bool PUBLIC_API IsBuiltinObjectMethod(BuiltinTypeId id, kungfu::GateType funcType) const; 583 GetBuiltinPandaFile()584 inline const JSPandaFile *GetBuiltinPandaFile() const 585 { 586 return builtinPandaFile_; 587 } 588 GetBuiltinRecordName()589 inline const CString &GetBuiltinRecordName() const 590 { 591 return builtinsRecordName_; 592 } 593 GetBytecodeInfoCollector()594 inline kungfu::BytecodeInfoCollector *GetBytecodeInfoCollector() const 595 { 596 return bcInfoCollector_; 597 } 598 SetBytecodeInfoCollector(kungfu::BytecodeInfoCollector * bcInfoCollector)599 inline void SetBytecodeInfoCollector(kungfu::BytecodeInfoCollector *bcInfoCollector) 600 { 601 bcInfoCollector_ = bcInfoCollector; 602 } 603 604 class ElementData { 605 public: ElementData(JSTaggedType element)606 explicit ElementData(JSTaggedType element) : element_(element) {} 607 Iterate(const RootVisitor & v)608 void Iterate(const RootVisitor &v) 609 { 610 v(Root::ROOT_VM, ObjectSlot(reinterpret_cast<uintptr_t>(&element_))); 611 } 612 GetCPIndexMap()613 std::unordered_map<int32_t, uint32_t>& GetCPIndexMap() 614 { 615 return cpIndexMap_; 616 } 617 GetELM()618 JSTaggedType GetELM() const 619 { 620 return element_; 621 } 622 623 private: 624 JSTaggedType element_ {0}; 625 std::unordered_map<int32_t, uint32_t> cpIndexMap_ {}; 626 }; 627 628 class IHClassData { 629 public: IHClassData(JSTaggedType ihc)630 explicit IHClassData(JSTaggedType ihc) : ihc_(ihc) {} 631 Iterate(const RootVisitor & v)632 void Iterate(const RootVisitor &v) 633 { 634 v(Root::ROOT_VM, ObjectSlot(reinterpret_cast<uintptr_t>(&ihc_))); 635 } 636 GetCPIndexMap()637 std::unordered_map<int32_t, uint32_t>& GetCPIndexMap() 638 { 639 return cpIndexMap_; 640 } 641 GetIHC()642 JSTaggedType GetIHC() const 643 { 644 return ihc_; 645 } 646 647 private: 648 JSTaggedType ihc_ {0}; 649 std::unordered_map<int32_t, uint32_t> cpIndexMap_ {}; 650 }; 651 652 class JSArrayData { 653 public: JSArrayData()654 explicit JSArrayData() {} 655 Iterate(const RootVisitor & v)656 void Iterate(const RootVisitor &v) 657 { 658 for (auto iter : idElmMap_) { 659 iter.second.Iterate(v); 660 } 661 for (auto iter : idIhcMap_) { 662 iter.second.Iterate(v); 663 } 664 } 665 GetElmMap()666 std::map<panda_file::File::EntityId, ElementData>& GetElmMap() 667 { 668 return idElmMap_; 669 } 670 GetIhcMap()671 std::map<panda_file::File::EntityId, IHClassData>& GetIhcMap() 672 { 673 return idIhcMap_; 674 } 675 AddElmMap(panda_file::File::EntityId id,ElementData data)676 void AddElmMap(panda_file::File::EntityId id, ElementData data) 677 { 678 idElmMap_.insert({id, data}); 679 } 680 AddIhcMap(panda_file::File::EntityId id,IHClassData data)681 void AddIhcMap(panda_file::File::EntityId id, IHClassData data) 682 { 683 idIhcMap_.insert({id, data}); 684 } 685 686 private: 687 std::map<panda_file::File::EntityId, ElementData> idElmMap_ {}; 688 std::map<panda_file::File::EntityId, IHClassData> idIhcMap_ {}; 689 }; 690 691 // for snapshot 692 class SnapshotData { 693 public: 694 enum RecordType { 695 METHOD = 0, 696 LITERAL, 697 698 RECORD_TYPE_NUM, 699 RECORD_TYPE_FIRST = METHOD, 700 RECORD_TYPE_LAST = LITERAL, 701 }; 702 703 static constexpr uint8_t SNAPSHOT_CP_LIST_ITEM_SIZE = 2; 704 705 using RecordData = std::vector<std::pair<uint32_t, uint32_t>>; 706 SnapshotData()707 SnapshotData() : recordInfo_(RecordType::RECORD_TYPE_NUM, RecordData{}) {} 708 Iterate(const RootVisitor & v)709 void Iterate(const RootVisitor &v) 710 { 711 v(Root::ROOT_VM, ObjectSlot(reinterpret_cast<uintptr_t>(&snapshotCPList_))); 712 } 713 SetSnapshotCPList(JSTaggedValue snapshotCPList)714 void SetSnapshotCPList(JSTaggedValue snapshotCPList) 715 { 716 snapshotCPList_ = snapshotCPList; 717 } 718 GetSnapshotCPList()719 JSTaggedValue GetSnapshotCPList() const 720 { 721 return snapshotCPList_; 722 } 723 GetSnapshotValVector(int32_t cpID)724 CVector<JSTaggedType>& GetSnapshotValVector(int32_t cpID) 725 { 726 return snapshotVals_[cpID]; 727 } 728 AddIndexInfoToRecordInfo(RecordType type,std::pair<uint32_t,uint32_t> indexInfo)729 void AddIndexInfoToRecordInfo(RecordType type, std::pair<uint32_t, uint32_t> indexInfo) 730 { 731 ASSERT(RECORD_TYPE_FIRST <= type && type <= RECORD_TYPE_LAST); 732 recordInfo_[type].emplace_back(indexInfo); 733 } 734 GetRecordInfo(RecordType type)735 const RecordData& GetRecordInfo(RecordType type) 736 { 737 ASSERT(RECORD_TYPE_FIRST <= type && type <= RECORD_TYPE_LAST); 738 return recordInfo_[type]; 739 } 740 741 private: 742 JSTaggedValue snapshotCPList_ {JSTaggedValue::Hole()}; 743 744 // key: constantpoolnum, value: store hclass or element which produced from static type info 745 CMap<int32_t, CVector<JSTaggedType>> snapshotVals_ {}; 746 747 // used to record the data that needs to be modified into the aot code entry index 748 std::vector<RecordData> recordInfo_ {}; 749 }; 750 SetCompilationDriver(kungfu::CompilationDriver * cmpDriver)751 void SetCompilationDriver(kungfu::CompilationDriver *cmpDriver) 752 { 753 cmpDriver_ = cmpDriver; 754 } 755 GetCompilationDriver()756 kungfu::CompilationDriver *GetCompilationDriver() const 757 { 758 return cmpDriver_; 759 } 760 GetSnapshotCPList()761 JSTaggedValue PUBLIC_API GetSnapshotCPList() const 762 { 763 return snapshotData_.GetSnapshotCPList(); 764 } 765 766 void PUBLIC_API ProcessSnapshotConstantPool(kungfu::BytecodeInfoCollector *bcInfoCollector); 767 768 void PUBLIC_API ResolveSnapshotConstantPool(const std::map<uint32_t, uint32_t> &methodToEntryIndexMap); 769 AddElementToClassNameMap(const JSPandaFile * jsPandaFile,uint32_t offset,std::string className)770 void AddElementToClassNameMap(const JSPandaFile *jsPandaFile, uint32_t offset, std::string className) 771 { 772 literalOffsetClassNameMap_.emplace(std::make_pair(jsPandaFile, offset), className); 773 } 774 GetClassNameByOffset(const JSPandaFile * jsPandaFile,uint32_t typeId)775 const std::string GetClassNameByOffset(const JSPandaFile *jsPandaFile, uint32_t typeId) const 776 { 777 std::pair<const JSPandaFile *, uint32_t> pair = std::make_pair(jsPandaFile, typeId); 778 std::string name = ""; 779 if (literalOffsetClassNameMap_.find(pair) != literalOffsetClassNameMap_.end()) { 780 name = literalOffsetClassNameMap_.at(pair); 781 } 782 return name; 783 } 784 CollectGT(GlobalTSTypeRef gt)785 inline void CollectGT(GlobalTSTypeRef gt) 786 { 787 if (IsClassTypeKind(gt)) { 788 collectedGT_.insert(gt); 789 } 790 } 791 GetCollectedGT()792 inline std::set<GlobalTSTypeRef>& GetCollectedGT() 793 { 794 return collectedGT_; 795 } 796 InsertLiteralGTMap(TypeLocation & loc,GlobalTSTypeRef gt)797 inline void InsertLiteralGTMap(TypeLocation &loc, GlobalTSTypeRef gt) 798 { 799 literalGTMap_[loc] = gt; 800 } 801 GetLiteralGT(TypeLocation & loc)802 inline GlobalTSTypeRef GetLiteralGT(TypeLocation &loc) 803 { 804 auto it = literalGTMap_.find(loc); 805 if (it != literalGTMap_.end()) { 806 return it->second; 807 } 808 return GlobalTSTypeRef::Default(); 809 } 810 InsertPtToGtMap(ClassType pgoType,const kungfu::GateType & gateType)811 inline void InsertPtToGtMap(ClassType pgoType, const kungfu::GateType &gateType) 812 { 813 ptToGtMap_.emplace(pgoType, gateType); 814 } 815 GetGateTypeByPt(ClassType pgoType)816 inline const kungfu::GateType GetGateTypeByPt(ClassType pgoType) 817 { 818 auto it = ptToGtMap_.find(pgoType); 819 if (it != ptToGtMap_.end()) { 820 return it->second; 821 } 822 return kungfu::GateType::AnyType(); 823 } 824 825 void PrintNumOfTypes() const; 826 827 void PrintTypeInfo(const JSPandaFile *jsPandaFile) const; 828 829 kungfu::GateType TryNarrowUnionType(kungfu::GateType gateType); 830 831 JSHandle<TaggedArray> GetExportTableFromLiteral(const JSPandaFile *jsPandaFile, const CString &recordName); 832 833 int GetElementsIndex(panda_file::File::EntityId id); 834 835 int GetHClassIndex(panda_file::File::EntityId id); 836 837 int GetHClassIndex(GlobalTSTypeRef classGT, bool isConstructor = false); 838 GetPGOGTCountByRecordName(const CString & recordName)839 uint32_t GetPGOGTCountByRecordName(const CString &recordName) const 840 { 841 if (bcInfoCollector_ == nullptr) { 842 return 0; 843 } 844 kungfu::PGOBCInfo *bcInfo = bcInfoCollector_->GetPGOBCInfo(); 845 return bcInfo->GetPGOExtendGTCount(recordName); 846 } 847 GetBuiltinsName(GlobalTSTypeRef builtinGT)848 inline std::string GetBuiltinsName(GlobalTSTypeRef builtinGT) const 849 { 850 uint32_t index = GetBuiltinIndex(builtinGT); 851 return GetBuiltinsName(index); 852 } 853 854 TSTypeKind PUBLIC_API GetTypeKind(const GlobalTSTypeRef >) const; 855 856 #define TSTYPETABLE_ACCESSOR_LIST(V) \ 857 V(Builtin, ModuleTableIdx::BUILTIN) \ 858 V(Inferred, ModuleTableIdx::INFERRED) \ 859 V(Runtime, ModuleTableIdx::RUNTIME) \ 860 V(Generics, ModuleTableIdx::GENERICS) 861 862 #define TSTYPETABLE_ACCESSOR(NAME, MODULEID) \ 863 inline GlobalTSTypeRef AddTSTypeTo##NAME##Table(const JSHandle<TSType> &type) const \ 864 { \ 865 return AddTSTypeToTypeTable(type, static_cast<uint32_t>(MODULEID)); \ 866 } \ 867 \ 868 inline JSHandle<TSTypeTable> Get##NAME##Table() const \ 869 { \ 870 return GetTSTypeTable(static_cast<uint32_t>(MODULEID)); \ 871 } \ 872 \ 873 inline void Set##NAME##Table(const JSHandle<TSTypeTable> &table) \ 874 { \ 875 SetTSTypeTable(table, static_cast<uint32_t>(MODULEID)); \ 876 } 877 878 TSTYPETABLE_ACCESSOR_LIST(TSTYPETABLE_ACCESSOR) 879 #undef TSTYPETABLE_ACCESSOR 880 881 private: 882 NO_COPY_SEMANTIC(TSManager); 883 NO_MOVE_SEMANTIC(TSManager); 884 885 GlobalTSTypeRef AddTSTypeToTypeTable(const JSHandle<TSType> &type, int tableId) const; 886 887 JSHandle<TaggedArray> GenerateExportTableFromLiteral(const JSPandaFile *jsPandaFile, const CString &recordName); 888 889 GlobalTSTypeRef FindUnionInTypeTable(JSHandle<TSTypeTable> table, JSHandle<TSUnionType> unionType) const; 890 891 GlobalTSTypeRef FindIteratorInstanceInInferTable(GlobalTSTypeRef kindGt, GlobalTSTypeRef elementGt) const; 892 893 GlobalTSTypeRef PUBLIC_API GetPropType(GlobalTSTypeRef gt, JSHandle<JSTaggedValue> propertyName) const; 894 895 std::string GetClassTypeStr(GlobalTSTypeRef gt) const; 896 897 std::string GetClassInstanceTypeStr(GlobalTSTypeRef gt) const; 898 899 std::string GetFunctionTypeStr(GlobalTSTypeRef gt) const; 900 901 std::string GetArrayTypeStr(GlobalTSTypeRef gt) const; 902 903 std::string GetPrimitiveStr(const GlobalTSTypeRef >) const; 904 905 uint32_t RecordElmToVecAndIndexMap(ElementData &elmData); 906 907 uint32_t RecordIhcToVecAndIndexMap(IHClassData &ihcData); 908 909 uint32_t GetBuiltinIndex(GlobalTSTypeRef builtinGT) const; 910 911 std::string GetBuiltinsName(uint32_t index) const; 912 913 void CollectLiteralInfo(JSHandle<TaggedArray> array, uint32_t constantPoolIndex, 914 JSHandle<ConstantPool> snapshotConstantPool, 915 kungfu::BytecodeInfoCollector *bcInfoCollector, 916 JSHandle<JSTaggedValue> ihc, JSHandle<JSTaggedValue> chc); 917 SetBuiltinPandaFile(JSPandaFile * jsPandaFile)918 inline void SetBuiltinPandaFile(JSPandaFile *jsPandaFile) 919 { 920 builtinPandaFile_ = jsPandaFile; 921 } 922 SetBuiltinRecordName(CString & builtinsRecordName)923 inline void SetBuiltinRecordName(CString &builtinsRecordName) 924 { 925 builtinsRecordName_ = builtinsRecordName; 926 } 927 928 void GenerateSnapshotConstantPoolList(std::map<int32_t, uint32_t> &cpListIndexMap, 929 const CMap<int32_t, JSTaggedValue> &oldCPValues); 930 931 void TryGetIhcAndChc(GlobalTSTypeRef gt, JSHandle<JSTaggedValue> &ihc, JSHandle<JSTaggedValue> &chc); 932 933 void FillSnapshotConstantPoolList(const std::map<int32_t, uint32_t> &cpListIndexMap, 934 kungfu::BytecodeInfoCollector *bcInfoCollector); 935 936 void AddValueToSnapshotConstantPoolList(const std::map<int32_t, uint32_t> &cpListIndexMap, 937 kungfu::BytecodeInfoCollector *bcInfoCollector); 938 939 JSHandle<ConstantPool> GetSnapshotConstantPool(uint32_t cpListIndex); 940 941 EcmaVM *vm_ {nullptr}; 942 JSThread *thread_ {nullptr}; 943 ObjectFactory *factory_ {nullptr}; 944 JSTaggedValue globalModuleTable_ {JSTaggedValue::Hole()}; 945 CMap<ClassType, const kungfu::GateType> ptToGtMap_ {}; 946 std::map<GlobalTSTypeRef, IHClassData> gtIhcMap_ {}; 947 std::map<GlobalTSTypeRef, IHClassData> gtConstructorhcMap_ {}; 948 std::unordered_map<TypeLocation, GlobalTSTypeRef, HashTypeLocation> literalGTMap_ {}; 949 bool assertTypes_ {false}; 950 double typeThreshold_ {-1}; 951 952 // when the passmanager iterates each method, the curCP_ and curCPID_ should be updated 953 // so that subsequent passes (type_infer, ts_hcr_lowering) can obtain the correct constpool. 954 JSTaggedValue curCP_ {JSTaggedValue::Hole()}; 955 int32_t curCPID_ {0}; 956 957 // for jsarray 958 JSArrayData jsArrayData_ {}; 959 960 // for snapshot 961 SnapshotData snapshotData_ {}; 962 963 std::unordered_map<GlobalTypeID, GlobalTSTypeRef, HashGlobalTypeID> idGTMap_ {}; 964 std::map<GlobalTSTypeRef, std::pair<CString, uint32_t>> gtLiteralOffsetMap_ {}; 965 std::vector<uint32_t> builtinOffsets_ {}; 966 JSPandaFile *builtinPandaFile_ {nullptr}; 967 CString builtinsRecordName_ {""}; 968 std::map<ModuleInfo, GlobalTSTypeRef> moduleVarGtMap_{}; 969 kungfu::CompilationDriver *cmpDriver_ {nullptr}; 970 std::set<GlobalTSTypeRef> collectedGT_ {}; // use for storing types that need to generate hclasses 971 972 friend class EcmaVM; 973 friend class TSTypeAccessor; 974 975 std::map<std::pair<const JSPandaFile *, uint32_t>, std::string> literalOffsetClassNameMap_ {}; 976 kungfu::BytecodeInfoCollector *bcInfoCollector_ {nullptr}; 977 // use for collect the literal of export type table. 978 CMap<std::pair<const JSPandaFile *, CString>, JSTaggedValue> resolvedExportTable_ {}; 979 CMap<uint32_t, kungfu::GateType> methodOffsetToType_ {}; 980 }; 981 } // namespace panda::ecmascript 982 983 #endif // ECMASCRIPT_TS_TYPES_TS_MANAGER_H 984