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/js_handle.h" 20 #include "ecmascript/js_tagged_value-inl.h" 21 #include "ecmascript/ts_types/global_ts_type_ref.h" 22 #include "ecmascript/compiler/bytecode_info_collector.h" 23 #include "ecmascript/compiler/compilation_driver.h" 24 25 namespace panda::ecmascript { 26 enum class MTableIdx : uint8_t { 27 PRIMITIVE = 0, 28 BUILTIN, 29 INFERRED_UNTION, 30 NUM_OF_DEFAULT_TABLES, 31 }; 32 33 enum class PropertyType : uint8_t { 34 NORMAL = 0, 35 STATIC, 36 OTHERS, 37 }; 38 39 /* Since AOT allows loading lib_ark_builtins.d.ts optionally, the localId of the GlobalTSTypeRef 40 * (abbreviated as GT) of one builtin object will be different in different cases. 41 * 42 * In case where AOT does not load lib_ark_builtins.d.ts, builtin objects will be assigned localIds 43 * according to the following enum order. For example, the GT of FUNCTION will be (1, 21), where 1 44 * is the index of builtin TSTypeTable. Note that in this case, it is prohibited to get TSType from 45 * builtin TSTypeTable. 46 * 47 * In case where AOT has loaded lib_ark_builtins.d.ts, builtin objects will be assigned localIds in 48 * the order in which they appear in bytecodes. To identify types of builtin objects, the following 49 * enum is required as a parameter to the TSManager::GetBuiltinOffset to help to get the GT of some 50 * builtin object. 51 */ 52 enum class BuiltinTypeId : uint8_t { // keep the same with enum BuiltinType in ets_frontend 53 NUM_INDEX_IN_SUMMARY = 0, 54 BUILTIN_OFFSET = 20, 55 FUNCTION, 56 RANGE_ERROR, 57 ERROR, 58 OBJECT, 59 SYNTAX_ERROR, 60 TYPE_ERROR, 61 REFERENCE_ERROR, 62 URI_ERROR, 63 SYMBOL, 64 EVAL_ERROR, 65 NUMBER, 66 PARSE_FLOAT, 67 DATE, 68 BOOLEAN, 69 BIG_INT, 70 PARSE_INT, 71 WEAK_MAP, 72 REG_EXP, 73 SET, 74 MAP, 75 WEAK_REF, 76 WEAK_SET, 77 FINALIZATION_REGISTRY, 78 ARRAY, 79 UINT8_CLAMPED_ARRAY, 80 UINT8_ARRAY, 81 TYPED_ARRAY, 82 INT8_ARRAY, 83 UINT16_ARRAY, 84 UINT32_ARRAY, 85 INT16_ARRAY, 86 INT32_ARRAY, 87 FLOAT32_ARRAY, 88 FLOAT64_ARRAY, 89 BIG_INT64_ARRAY, 90 BIG_UINT64_ARRAY, 91 SHARED_ARRAY_BUFFER, 92 DATA_VIEW, 93 STRING, 94 ARRAY_BUFFER, 95 EVAL, 96 IS_FINITE, 97 ARK_PRIVATE, 98 PRINT, 99 DECODE_URI, 100 DECODE_URI_COMPONENT, 101 IS_NAN, 102 ENCODE_URI, 103 JS_NAN, 104 GLOBAL_THIS, 105 ENCODE_URI_COMPONENT, 106 JS_INFINITY, 107 MATH, 108 JSON, 109 ATOMICS, 110 UNDEFINED, 111 REFLECT, 112 PROMISE, 113 PROXY, 114 GENERATOR_FUNCTION, 115 INTL, 116 NUM_OF_BUILTIN_TYPES = INTL - BUILTIN_OFFSET, 117 TYPED_ARRAY_FIRST = UINT8_CLAMPED_ARRAY, 118 TYPED_ARRAY_LAST = BIG_UINT64_ARRAY, 119 }; 120 121 struct LocalModuleInfo { 122 const JSPandaFile *jsPandaFile {nullptr}; // there may be serval merged abc files. 123 const CString recordName {""}; // distinguish different files which are all merged to a abc file. 124 uint32_t index {0}; // bytecode "ldlocalmodulevar index", importVar index is unique in the same recordName. 125 bool operator < (const LocalModuleInfo &localModuleInfo) const 126 { 127 return index < localModuleInfo.index; 128 } 129 }; 130 131 class TSModuleTable : public TaggedArray { 132 public: 133 // Each TSTypeTable occupies three positions 134 static constexpr int ELEMENTS_LENGTH = 3; 135 static constexpr int MODULE_REQUEST_OFFSET = 1; 136 static constexpr int SORT_ID_OFFSET = 2; 137 static constexpr int TYPE_TABLE_OFFSET = 3; 138 // Reserve a position which is used to store the number of TSTypeTables and a TSTypeTable storage space 139 static constexpr int INITIAL_CAPACITY = ELEMENTS_LENGTH + 1; 140 static constexpr int NUMBER_OF_TABLES_INDEX = 0; 141 static constexpr int INCREASE_CAPACITY_RATE = 2; 142 // primitive table, builtins table, infer table and runtime table 143 static constexpr int DEFAULT_NUMBER_OF_TABLES = 4; 144 static constexpr int PRIMITIVE_TABLE_ID = 0; 145 static constexpr int BUILTINS_TABLE_ID = 1; 146 static constexpr int INFER_TABLE_ID = 2; 147 static constexpr int RUNTIME_TABLE_ID = 3; 148 static constexpr int NOT_FOUND = -1; 149 Cast(TaggedObject * object)150 static TSModuleTable *Cast(TaggedObject *object) 151 { 152 ASSERT(JSTaggedValue(object).IsTaggedArray()); 153 return static_cast<TSModuleTable *>(object); 154 } 155 156 JSHandle<EcmaString> GetModuleRequestByModuleId(JSThread *thread, int entry) const; 157 158 int GetGlobalModuleID(JSThread *thread, JSHandle<EcmaString> amiPath) const; 159 GetNumberOfTSTypeTables()160 inline int GetNumberOfTSTypeTables() const 161 { 162 return Get(NUMBER_OF_TABLES_INDEX).GetInt(); 163 } 164 SetNumberOfTSTypeTables(JSThread * thread,int num)165 inline void SetNumberOfTSTypeTables(JSThread *thread, int num) 166 { 167 Set(thread, NUMBER_OF_TABLES_INDEX, JSTaggedValue(num)); 168 } 169 GetTSTypeTableOffset(int entry)170 static uint32_t GetTSTypeTableOffset(int entry) 171 { 172 return entry * ELEMENTS_LENGTH + TYPE_TABLE_OFFSET; 173 } 174 GetModuleRequestOffset(int entry)175 static int GetModuleRequestOffset(int entry) 176 { 177 return entry * ELEMENTS_LENGTH + MODULE_REQUEST_OFFSET; 178 } 179 GetSortIdOffset(int entry)180 static int GetSortIdOffset(int entry) 181 { 182 return entry * ELEMENTS_LENGTH + SORT_ID_OFFSET; 183 } 184 }; 185 186 class TSManager { 187 public: 188 explicit TSManager(EcmaVM *vm); 189 ~TSManager() = default; 190 191 void Initialize(); 192 193 void Dump(); 194 195 void Iterate(const RootVisitor &v); 196 GetTSModuleTable()197 JSHandle<TSModuleTable> GetTSModuleTable() const 198 { 199 return JSHandle<TSModuleTable>(reinterpret_cast<uintptr_t>(&globalModuleTable_)); 200 } 201 SetTSModuleTable(JSHandle<TSModuleTable> table)202 void SetTSModuleTable(JSHandle<TSModuleTable> table) 203 { 204 globalModuleTable_ = table.GetTaggedValue(); 205 } 206 207 JSHandle<TSTypeTable> GetTSTypeTable(int entry) const; 208 209 void SetTSTypeTable(const JSHandle<TSTypeTable> &table, int tableId) const; 210 211 void GenerateBuiltinSummary(); 212 GetBuiltinOffset(uint32_t index)213 inline uint32_t GetBuiltinOffset(uint32_t index) const 214 { 215 if (index == static_cast<uint32_t>(BuiltinTypeId::NUM_INDEX_IN_SUMMARY)) { 216 return builtinOffsets_[index]; 217 } 218 return builtinOffsets_[index - static_cast<uint32_t>(BuiltinTypeId::BUILTIN_OFFSET)]; 219 } 220 GetPropType(kungfu::GateType gateType,JSTaggedValue propertyName)221 inline GlobalTSTypeRef PUBLIC_API GetPropType(kungfu::GateType gateType, JSTaggedValue propertyName) const 222 { 223 return GetPropType(gateType, JSHandle<EcmaString>(vm_->GetJSThread(), propertyName)); 224 } 225 GetPropType(kungfu::GateType gateType,JSHandle<EcmaString> propertyName)226 inline GlobalTSTypeRef PUBLIC_API GetPropType(kungfu::GateType gateType, JSHandle<EcmaString> propertyName) const 227 { 228 GlobalTSTypeRef gt = gateType.GetGTRef(); 229 return GetPropType(gt, propertyName); 230 } 231 232 GlobalTSTypeRef PUBLIC_API GetPropType(GlobalTSTypeRef gt, JSHandle<EcmaString> propertyName) const; 233 234 // use for object GetPropType(kungfu::GateType gateType,const uint64_t key)235 inline GlobalTSTypeRef PUBLIC_API GetPropType(kungfu::GateType gateType, const uint64_t key) const 236 { 237 GlobalTSTypeRef gt = gateType.GetGTRef(); 238 return GetPropType(gt, key); 239 } 240 CreateClassInstanceType(kungfu::GateType gateType)241 inline GlobalTSTypeRef PUBLIC_API CreateClassInstanceType(kungfu::GateType gateType) 242 { 243 GlobalTSTypeRef gt = gateType.GetGTRef(); 244 return CreateClassInstanceType(gt); 245 } 246 247 GlobalTSTypeRef PUBLIC_API CreateClassInstanceType(GlobalTSTypeRef gt); 248 249 GlobalTSTypeRef PUBLIC_API GetClassType(GlobalTSTypeRef classInstanceGT) const; 250 251 JSHandle<TSClassType> GetExtendClassType(JSHandle<TSClassType> classType) const; 252 253 GlobalTSTypeRef PUBLIC_API GetPropType(GlobalTSTypeRef gt, const uint64_t key) const; 254 255 uint32_t PUBLIC_API GetUnionTypeLength(GlobalTSTypeRef gt) const; 256 257 GlobalTSTypeRef PUBLIC_API GetUnionTypeByIndex(GlobalTSTypeRef gt, int index) const; 258 259 GlobalTSTypeRef PUBLIC_API GetOrCreateUnionType(CVector<GlobalTSTypeRef> unionTypeVec); 260 261 uint32_t PUBLIC_API GetFunctionTypeLength(GlobalTSTypeRef gt) const; 262 263 GlobalTSTypeRef PUBLIC_API GetOrCreateTSIteratorInstanceType(TSRuntimeType runtimeType, GlobalTSTypeRef elementGt); 264 265 GlobalTSTypeRef PUBLIC_API GetIteratorInstanceElementGt(GlobalTSTypeRef gt) const; 266 GetIteratorInstanceElementGt(kungfu::GateType gateType)267 inline GlobalTSTypeRef PUBLIC_API GetIteratorInstanceElementGt(kungfu::GateType gateType) const 268 { 269 GlobalTSTypeRef gt = GlobalTSTypeRef(gateType.GetGTRef()); 270 return GetIteratorInstanceElementGt(gt); 271 } 272 273 bool PUBLIC_API IsStaticFunc(GlobalTSTypeRef gt) const; 274 275 GlobalTSTypeRef PUBLIC_API GetSuperPropType(GlobalTSTypeRef gt, 276 JSHandle<EcmaString> propertyName, 277 PropertyType propType) const; 278 GetSuperPropType(GlobalTSTypeRef gt,JSTaggedValue propertyName,PropertyType propType)279 inline GlobalTSTypeRef PUBLIC_API GetSuperPropType(GlobalTSTypeRef gt, 280 JSTaggedValue propertyName, 281 PropertyType propType) const 282 { 283 return GetSuperPropType(gt, JSHandle<EcmaString>(vm_->GetJSThread(), propertyName), propType); 284 } 285 286 GlobalTSTypeRef PUBLIC_API GetSuperPropType(GlobalTSTypeRef gt, 287 const uint64_t key, 288 PropertyType propType) const; 289 290 GlobalTSTypeRef PUBLIC_API GetFuncParameterTypeGT(GlobalTSTypeRef gt, int index) const; 291 292 GlobalTSTypeRef PUBLIC_API GetFuncThisGT(GlobalTSTypeRef gt) const; 293 294 void PUBLIC_API SetFuncMethodOffset(GlobalTSTypeRef gt, uint32_t methodOffset); 295 296 uint32_t PUBLIC_API GetFuncMethodOffset(GlobalTSTypeRef gt) const; 297 298 bool PUBLIC_API IsGetterSetterFunc(GlobalTSTypeRef gt) const; 299 300 bool IsAbstractMethod(GlobalTSTypeRef gt) const; 301 302 bool IsMethodSignature(GlobalTSTypeRef gt) const; 303 GetFuncReturnValueTypeGT(kungfu::GateType gateType)304 inline GlobalTSTypeRef PUBLIC_API GetFuncReturnValueTypeGT(kungfu::GateType gateType) const 305 { 306 GlobalTSTypeRef gt = gateType.GetGTRef(); 307 return GetFuncReturnValueTypeGT(gt); 308 } 309 310 GlobalTSTypeRef PUBLIC_API GetFuncReturnValueTypeGT(GlobalTSTypeRef gt) const; 311 312 std::string PUBLIC_API GetFuncName(kungfu::GateType gt) const; 313 GetArrayParameterTypeGT(kungfu::GateType gateType)314 inline GlobalTSTypeRef PUBLIC_API GetArrayParameterTypeGT(kungfu::GateType gateType) const 315 { 316 GlobalTSTypeRef gt = gateType.GetGTRef(); 317 return GetArrayParameterTypeGT(gt); 318 } 319 320 GlobalTSTypeRef PUBLIC_API GetArrayParameterTypeGT(GlobalTSTypeRef gt) const; 321 AssertTypes()322 bool PUBLIC_API AssertTypes() const 323 { 324 return assertTypes_; 325 } 326 PrintAnyTypes()327 bool PUBLIC_API PrintAnyTypes() const 328 { 329 return printAnyTypes_; 330 } 331 IsBuiltinsDTSEnabled()332 bool IsBuiltinsDTSEnabled() const 333 { 334 return vm_->GetJSOptions().WasSetBuiltinsDTS(); 335 } 336 GetBuiltinsDTS()337 CString GetBuiltinsDTS() const 338 { 339 std::string fileName = vm_->GetJSOptions().GetBuiltinsDTS(); 340 return CString(fileName); 341 } 342 343 void GenerateTSHClass(JSHandle<TSClassType> classType); 344 345 void GenerateTSHClasses(); 346 347 JSHandle<JSTaggedValue> GetTSType(const GlobalTSTypeRef >) const; 348 349 std::string PUBLIC_API GetTypeStr(kungfu::GateType gateType) const; 350 351 int PUBLIC_API GetHClassIndexByInstanceGateType(const kungfu::GateType &gateType); 352 353 int PUBLIC_API GetHClassIndexByClassGateType(const kungfu::GateType &gateType); 354 355 JSTaggedValue PUBLIC_API GetHClassFromCache(uint32_t index); 356 IsUserDefinedClassTypeKind(const kungfu::GateType & gateType)357 inline bool IsUserDefinedClassTypeKind(const kungfu::GateType &gateType) const 358 { 359 GlobalTSTypeRef gt = gateType.GetGTRef(); 360 return IsUserDefinedClassTypeKind(gt); 361 } 362 IsUserDefinedClassTypeKind(const GlobalTSTypeRef & gt)363 inline bool IsUserDefinedClassTypeKind(const GlobalTSTypeRef >) const 364 { 365 uint32_t m = gt.GetModuleId(); 366 return (IsClassTypeKind(gt)) && 367 (m != TSModuleTable::BUILTINS_TABLE_ID); 368 } 369 GetEcmaVM()370 EcmaVM *GetEcmaVM() const 371 { 372 return vm_; 373 } 374 GetThread()375 JSThread *GetThread() const 376 { 377 return thread_; 378 } 379 380 #define IS_TSTYPEKIND_METHOD_LIST(V) \ 381 V(Primitive, TSTypeKind::PRIMITIVE) \ 382 V(Class, TSTypeKind::CLASS) \ 383 V(ClassInstance, TSTypeKind::CLASS_INSTANCE) \ 384 V(Function, TSTypeKind::FUNCTION) \ 385 V(Union, TSTypeKind::UNION) \ 386 V(Array, TSTypeKind::ARRAY) \ 387 V(Object, TSTypeKind::OBJECT) \ 388 V(Import, TSTypeKind::IMPORT) \ 389 V(Interface, TSTypeKind::INTERFACE_KIND) \ 390 V(IteratorInstance, TSTypeKind::ITERATOR_INSTANCE) \ 391 392 #define IS_TSTYPEKIND(NAME, TSTYPEKIND) \ 393 inline bool PUBLIC_API Is##NAME##TypeKind(const kungfu::GateType &gateType) const \ 394 { \ 395 GlobalTSTypeRef gt = gateType.GetGTRef(); \ 396 return GetTypeKind(gt) == (TSTYPEKIND); \ 397 } \ 398 \ 399 inline bool PUBLIC_API Is##NAME##TypeKind(const GlobalTSTypeRef >) const \ 400 { \ 401 return GetTypeKind(gt) == (TSTYPEKIND); \ 402 } 403 404 IS_TSTYPEKIND_METHOD_LIST(IS_TSTYPEKIND) 405 #undef IS_TSTYPEKIND 406 407 bool PUBLIC_API IsBuiltinArrayType(kungfu::GateType gateType) const; 408 409 bool PUBLIC_API IsTypedArrayType(kungfu::GateType gateType) const; 410 411 bool PUBLIC_API IsFloat32ArrayType(kungfu::GateType gateType) const; 412 413 inline void AddElementToLiteralOffsetGTMap(const JSPandaFile *jsPandaFile, uint32_t offset, 414 const CString &recordName, GlobalTSTypeRef gt, 415 bool isImportType = false) 416 { 417 auto key = std::make_pair(jsPandaFile, offset); 418 literalOffsetGTMap_.emplace(key, gt); 419 if (!isImportType) { 420 auto value = std::make_pair(recordName, offset); 421 gtLiteralOffsetMap_.emplace(gt, value); 422 } 423 } 424 HasCreatedGT(const JSPandaFile * jsPandaFile,uint32_t offset)425 inline bool HasCreatedGT(const JSPandaFile *jsPandaFile, uint32_t offset) const 426 { 427 auto key = std::make_pair(jsPandaFile, offset); 428 return literalOffsetGTMap_.find(key) != literalOffsetGTMap_.end(); 429 } 430 GetGTFromOffset(const JSPandaFile * jsPandaFile,uint32_t offset)431 inline GlobalTSTypeRef GetGTFromOffset(const JSPandaFile *jsPandaFile, uint32_t offset) const 432 { 433 auto key = std::make_pair(jsPandaFile, offset); 434 return literalOffsetGTMap_.at(key); 435 } 436 HasOffsetFromGT(GlobalTSTypeRef gt)437 inline bool HasOffsetFromGT(GlobalTSTypeRef gt) const 438 { 439 return gtLiteralOffsetMap_.find(gt) != gtLiteralOffsetMap_.end(); 440 } 441 GetOffsetFromGt(GlobalTSTypeRef gt)442 inline std::pair<CString, uint32_t> GetOffsetFromGt(GlobalTSTypeRef gt) const 443 { 444 return gtLiteralOffsetMap_.at(gt); 445 } 446 AddTypeToLocalModuleVarGtMap(const JSPandaFile * jsPandaFile,const CString & recordName,uint32_t index,GlobalTSTypeRef gt)447 inline void AddTypeToLocalModuleVarGtMap(const JSPandaFile *jsPandaFile, const CString &recordName, 448 uint32_t index, GlobalTSTypeRef gt) 449 { 450 LocalModuleInfo key = {jsPandaFile, recordName, index}; 451 if (localModuleVarGtMap_.find(key) == localModuleVarGtMap_.end()) { 452 localModuleVarGtMap_.emplace(key, gt); 453 } else { 454 localModuleVarGtMap_[key] = gt; 455 } 456 } 457 HasExportGT(const JSPandaFile * jsPandaFile,const CString & recordName,uint32_t index)458 inline bool HasExportGT(const JSPandaFile *jsPandaFile, const CString &recordName, 459 uint32_t index) 460 { 461 LocalModuleInfo key = {jsPandaFile, recordName, index}; 462 return localModuleVarGtMap_.find(key) != localModuleVarGtMap_.end(); 463 } 464 GetGTFromModuleMap(const JSPandaFile * jsPandaFile,const CString & recordName,uint32_t index)465 inline GlobalTSTypeRef GetGTFromModuleMap(const JSPandaFile *jsPandaFile, const CString &recordName, 466 uint32_t index) 467 { 468 LocalModuleInfo key = {jsPandaFile, recordName, index}; 469 return localModuleVarGtMap_.at(key); 470 } 471 IsTSIterator(GlobalTSTypeRef gt)472 bool IsTSIterator(GlobalTSTypeRef gt) const 473 { 474 uint32_t m = gt.GetModuleId(); 475 uint32_t l = gt.GetLocalId(); 476 return (m == TSModuleTable::RUNTIME_TABLE_ID) && (l == static_cast<int>(TSRuntimeType::ITERATOR)); 477 } 478 IsTSIteratorResult(GlobalTSTypeRef gt)479 bool IsTSIteratorResult(GlobalTSTypeRef gt) const 480 { 481 uint32_t m = gt.GetModuleId(); 482 uint32_t l = gt.GetLocalId(); 483 return (m == TSModuleTable::RUNTIME_TABLE_ID) && (l == static_cast<int>(TSRuntimeType::ITERATOR_RESULT)); 484 } 485 486 // not consider [[prototype]] properties and accessor, -1: not find 487 int PUBLIC_API GetPropertyOffset(JSTaggedValue hclass, JSTaggedValue key); 488 489 void PUBLIC_API SetCurConstantPool(const JSPandaFile *jsPandaFile, uint32_t methodOffset); 490 GetConstantPool()491 JSHandle<JSTaggedValue> PUBLIC_API GetConstantPool() const 492 { 493 return JSHandle<JSTaggedValue>(uintptr_t(&curCP_)); 494 } 495 496 bool PUBLIC_API IsBuiltin(kungfu::GateType funcType) const; 497 498 bool PUBLIC_API IsBuiltinMath(kungfu::GateType funcType) const; 499 500 void RecursivelyMergeClassField(JSHandle<TSClassType> classType); 501 GetBuiltinPandaFile()502 inline const JSPandaFile *GetBuiltinPandaFile() const 503 { 504 return builtinPandaFile_; 505 } 506 GetBuiltinRecordName()507 inline const CString &GetBuiltinRecordName() const 508 { 509 return builtinsRecordName_; 510 } 511 512 class IHClassData { 513 public: IHClassData(JSTaggedType ihc)514 IHClassData(JSTaggedType ihc) : ihc_(ihc) {} 515 Iterate(const RootVisitor & v)516 void Iterate(const RootVisitor &v) 517 { 518 v(Root::ROOT_VM, ObjectSlot(reinterpret_cast<uintptr_t>(&ihc_))); 519 } 520 GetCPIndexMap()521 std::unordered_map<int32_t, uint32_t>& GetCPIndexMap() 522 { 523 return cpIndexMap_; 524 } 525 GetIHC()526 JSTaggedType GetIHC() const 527 { 528 return ihc_; 529 } 530 531 private: 532 JSTaggedType ihc_ {0}; 533 std::unordered_map<int32_t, uint32_t> cpIndexMap_ {}; 534 }; 535 536 // for snapshot 537 class SnapshotData { 538 public: 539 enum RecordType { 540 METHOD = 0, 541 LITERAL, 542 543 RECORD_TYPE_NUM, 544 RECORD_TYPE_FIRST = METHOD, 545 RECORD_TYPE_LAST = LITERAL, 546 }; 547 548 static constexpr uint8_t SNAPSHOT_CP_LIST_ITEM_SIZE = 2; 549 550 using RecordData = std::vector<std::pair<uint32_t, uint32_t>>; 551 SnapshotData()552 SnapshotData() : recordInfo_(RecordType::RECORD_TYPE_NUM, RecordData{}) {} 553 Iterate(const RootVisitor & v)554 void Iterate(const RootVisitor &v) 555 { 556 v(Root::ROOT_VM, ObjectSlot(reinterpret_cast<uintptr_t>(&snapshotCPList_))); 557 } 558 SetSnapshotCPList(JSTaggedValue snapshotCPList)559 void SetSnapshotCPList(JSTaggedValue snapshotCPList) 560 { 561 snapshotCPList_ = snapshotCPList; 562 } 563 GetSnapshotCPList()564 JSTaggedValue GetSnapshotCPList() const 565 { 566 return snapshotCPList_; 567 } 568 GetSnapshotHCVector(int32_t cpID)569 CVector<JSTaggedType>& GetSnapshotHCVector(int32_t cpID) 570 { 571 return snapshotHCs_[cpID]; 572 } 573 AddIndexInfoToRecordInfo(RecordType type,std::pair<uint32_t,uint32_t> indexInfo)574 void AddIndexInfoToRecordInfo(RecordType type, std::pair<uint32_t, uint32_t> indexInfo) 575 { 576 ASSERT(RECORD_TYPE_FIRST <= type && type <= RECORD_TYPE_LAST); 577 recordInfo_[type].emplace_back(indexInfo); 578 } 579 GetRecordInfo(RecordType type)580 const RecordData& GetRecordInfo(RecordType type) 581 { 582 ASSERT(RECORD_TYPE_FIRST <= type && type <= RECORD_TYPE_LAST); 583 return recordInfo_[type]; 584 } 585 586 private: 587 JSTaggedValue snapshotCPList_ {JSTaggedValue::Hole()}; 588 589 // key: constantpoolnum, value: store hclass which produced from static type info 590 CMap<int32_t, CVector<JSTaggedType>> snapshotHCs_ {}; 591 592 // used to record the data that needs to be modified into the aot code entry index 593 std::vector<RecordData> recordInfo_ {}; 594 }; 595 SetCompilationDriver(kungfu::CompilationDriver * cmpDriver)596 void SetCompilationDriver(kungfu::CompilationDriver *cmpDriver) 597 { 598 cmpDriver_ = cmpDriver; 599 } 600 GetCompilationDriver()601 kungfu::CompilationDriver *GetCompilationDriver() const 602 { 603 return cmpDriver_; 604 } 605 GetSnapshotCPList()606 JSTaggedValue PUBLIC_API GetSnapshotCPList() const 607 { 608 return snapshotData_.GetSnapshotCPList(); 609 } 610 611 void PUBLIC_API ProcessSnapshotConstantPool(kungfu::BytecodeInfoCollector *bcInfoCollector); 612 613 void PUBLIC_API ResolveSnapshotConstantPool(const std::map<uint32_t, uint32_t> &methodToEntryIndexMap); 614 AddElementToClassNameMap(const JSPandaFile * jsPandaFile,uint32_t offset,std::string className)615 void AddElementToClassNameMap(const JSPandaFile *jsPandaFile, uint32_t offset, std::string className) 616 { 617 literalOffsetClassNameMap_.emplace(std::make_pair(jsPandaFile, offset), className); 618 } 619 GetClassNameByOffset(const JSPandaFile * jsPandaFile,uint32_t typeId)620 const std::string GetClassNameByOffset(const JSPandaFile *jsPandaFile, uint32_t typeId) const 621 { 622 std::pair<const JSPandaFile *, uint32_t> pair = std::make_pair(jsPandaFile, typeId); 623 std::string name = ""; 624 if (literalOffsetClassNameMap_.find(pair) != literalOffsetClassNameMap_.end()) { 625 name = literalOffsetClassNameMap_.at(pair); 626 } 627 return name; 628 } 629 CollectTypeOffsets(GlobalTSTypeRef classGT)630 inline void CollectTypeOffsets(GlobalTSTypeRef classGT) 631 { 632 if (IsClassTypeKind(classGT)) { 633 collectedTypeOffsets_.insert(classGT); 634 } 635 } 636 637 void PrintNumOfTypes() const; 638 639 private: 640 NO_COPY_SEMANTIC(TSManager); 641 NO_MOVE_SEMANTIC(TSManager); 642 643 bool IsDuplicatedKey(JSHandle<TSObjLayoutInfo> extendLayout, JSTaggedValue key); 644 645 GlobalTSTypeRef AddTSTypeToTypeTable(const JSHandle<TSType> &type, int tableId) const; 646 647 GlobalTSTypeRef FindUnionInTypeTable(JSHandle<TSTypeTable> table, JSHandle<TSUnionType> unionType) const; 648 649 GlobalTSTypeRef FindIteratorInstanceInInferTable(GlobalTSTypeRef kindGt, GlobalTSTypeRef elementGt) const; 650 651 TSTypeKind PUBLIC_API GetTypeKind(const GlobalTSTypeRef >) const; 652 653 std::string GetClassTypeStr(GlobalTSTypeRef gt) const; 654 655 std::string GetClassInstanceTypeStr(GlobalTSTypeRef gt) const; 656 657 std::string GetFunctionTypeStr(GlobalTSTypeRef gt) const; 658 659 std::string GetArrayTypeStr(GlobalTSTypeRef gt) const; 660 661 std::string GetPrimitiveStr(const GlobalTSTypeRef >) const; 662 663 int GetHClassIndex(GlobalTSTypeRef classGT); 664 665 uint32_t RecordIhcToVecAndIndexMap(IHClassData &ihcData); 666 667 uint32_t GetBuiltinIndex(GlobalTSTypeRef builtinGT) const; 668 669 std::string GetBuiltinsName(uint32_t index) const; 670 671 void CollectLiteralInfo(JSHandle<TaggedArray> array, uint32_t constantPoolIndex, 672 JSHandle<ConstantPool> snapshotConstantPool, 673 kungfu::BytecodeInfoCollector *bcInfoCollector); 674 SetBuiltinPandaFile(JSPandaFile * jsPandaFile)675 inline void SetBuiltinPandaFile(JSPandaFile *jsPandaFile) 676 { 677 builtinPandaFile_ = jsPandaFile; 678 } 679 SetBuiltinRecordName(CString & builtinsRecordName)680 inline void SetBuiltinRecordName(CString &builtinsRecordName) 681 { 682 builtinsRecordName_ = builtinsRecordName; 683 } 684 685 // for snapshot 686 int32_t GetOldConstantPoolIDByMethodOffset(const JSPandaFile *jsPandaFile, uint32_t methodOffset); 687 688 void GenerateSnapshotConstantPoolList(std::map<int32_t, uint32_t> &cpListIndexMap, 689 const CMap<int32_t, JSTaggedValue> &oldCPValues); 690 691 void FillSnapshotConstantPoolList(const std::map<int32_t, uint32_t> &cpListIndexMap, 692 kungfu::BytecodeInfoCollector *bcInfoCollector); 693 694 void AddHClassToSnapshotConstantPoolList(const std::map<int32_t, uint32_t> &cpListIndexMap, 695 kungfu::BytecodeInfoCollector *bcInfoCollector); 696 697 JSHandle<ConstantPool> GetSnapshotConstantPool(uint32_t cpListIndex); 698 699 EcmaVM *vm_ {nullptr}; 700 JSThread *thread_ {nullptr}; 701 ObjectFactory *factory_ {nullptr}; 702 JSTaggedValue globalModuleTable_ {JSTaggedValue::Hole()}; 703 std::map<GlobalTSTypeRef, IHClassData> gtIhcMap_ {}; 704 bool assertTypes_ {false}; 705 bool printAnyTypes_ {false}; 706 707 // when the passmanager iterates each method, the curCP_ and curCPID_ should be updated 708 // so that subsequent passes (type_infer, ts_type_lowering) can obtain the correct constpool. 709 JSTaggedValue curCP_ {JSTaggedValue::Hole()}; 710 int32_t curCPID_ {0}; 711 712 // for snapshot 713 SnapshotData snapshotData_ {}; 714 715 std::map<std::pair<const JSPandaFile *, uint32_t>, GlobalTSTypeRef> literalOffsetGTMap_ {}; 716 std::map<GlobalTSTypeRef, std::pair<CString, uint32_t>> gtLiteralOffsetMap_ {}; 717 std::vector<uint32_t> builtinOffsets_ {}; 718 JSPandaFile *builtinPandaFile_ {nullptr}; 719 CString builtinsRecordName_ {""}; 720 std::map<LocalModuleInfo, GlobalTSTypeRef> localModuleVarGtMap_{}; 721 kungfu::CompilationDriver *cmpDriver_ {nullptr}; 722 std::set<GlobalTSTypeRef> collectedTypeOffsets_ {}; // use for storing types that need to generate hclasses 723 724 friend class EcmaVM; 725 726 std::map<std::pair<const JSPandaFile *, uint32_t>, std::string> literalOffsetClassNameMap_ {}; 727 }; 728 } // namespace panda::ecmascript 729 730 #endif // ECMASCRIPT_TS_TYPES_TS_MANAGER_H 731