• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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/aot_snapshot/aot_snapshot.h"
20 #include "ecmascript/compiler/bytecode_info_collector.h"
21 #include "ecmascript/compiler/compilation_driver.h"
22 #include "ecmascript/compiler/pgo_type/pgo_type_manager.h"
23 #include "ecmascript/js_handle.h"
24 #include "ecmascript/js_tagged_value-inl.h"
25 #include "ecmascript/ts_types/builtin_type_id.h"
26 #include "ecmascript/ts_types/global_ts_type_ref.h"
27 #include "ecmascript/ts_types/global_type_info.h"
28 #include "ecmascript/ts_types/ts_obj_layout_info.h"
29 
30 namespace panda::ecmascript {
31 using ProfileType = pgo::ProfileType;
32 using SnapshotGlobalData = kungfu::SnapshotGlobalData;
33 enum class PropertyType : uint8_t {
34     NORMAL = 0,
35     STATIC,
36     OTHERS,
37 };
38 
39 struct ModuleInfo {
40     const JSPandaFile *jsPandaFile {nullptr}; // there may be serval merged abc files.
41     const CString recordName {""}; // distinguish different files which are all merged to one abc file.
42     uint32_t index {0}; // bytecode "stmoudlevar index", exportVar index is unique in the same record.
43     bool operator < (const ModuleInfo &moduleInfo) const
44     {
45         if (index < moduleInfo.index) {
46             return true;
47         }
48         if (index == moduleInfo.index && recordName < moduleInfo.recordName) {
49             return true;
50         }
51         if (index == moduleInfo.index && recordName == moduleInfo.recordName &&
52             jsPandaFile < moduleInfo.jsPandaFile) {
53             return true;
54         }
55         return false;
56     }
57 };
58 
59 class TSModuleTable : public TaggedArray {
60 public:
61     // Each TSTypeTable occupies three positions
62     static constexpr int ELEMENTS_LENGTH = 4;
63     static constexpr int MODULE_REQUEST_OFFSET = 1;
64     static constexpr int SORT_ID_OFFSET = 2;
65     static constexpr int TYPE_TABLE_OFFSET = 3;
66     static constexpr int ABC_ID_OFFSET = 4;
67     // Reserve a position which is used to store the number of TSTypeTables and a TSTypeTable storage space
68     static constexpr int INITIAL_CAPACITY = ELEMENTS_LENGTH + 1;
69     static constexpr int NUMBER_OF_TABLES_INDEX = 0;
70     static constexpr int INCREASE_CAPACITY_RATE = 2;
71     static constexpr int NOT_FOUND = -1;
72 
Cast(TaggedObject * object)73     static TSModuleTable *Cast(TaggedObject *object)
74     {
75         ASSERT(JSTaggedValue(object).IsTaggedArray());
76         return static_cast<TSModuleTable *>(object);
77     }
78 
79     JSHandle<EcmaString> GetModuleRequestByModuleId(JSThread *thread, int entry) const;
80 
81     JSHandle<EcmaString> GetAbcRequestByModuleId(JSThread *thread, int entry) const;
82 
83     int GetGlobalModuleID(JSThread *thread, JSHandle<EcmaString> amiPath, JSHandle<EcmaString> abcPath) const;
84 
GetNumberOfTSTypeTables()85     inline int GetNumberOfTSTypeTables() const
86     {
87         return Get(NUMBER_OF_TABLES_INDEX).GetInt();
88     }
89 
SetNumberOfTSTypeTables(JSThread * thread,int num)90     inline void SetNumberOfTSTypeTables(JSThread *thread, int num)
91     {
92         Set(thread, NUMBER_OF_TABLES_INDEX, JSTaggedValue(num));
93     }
94 
GetTSTypeTableOffset(int entry)95     static uint32_t GetTSTypeTableOffset(int entry)
96     {
97         return entry * ELEMENTS_LENGTH + TYPE_TABLE_OFFSET;
98     }
99 
GetModuleRequestOffset(int entry)100     static int GetModuleRequestOffset(int entry)
101     {
102         return entry * ELEMENTS_LENGTH + MODULE_REQUEST_OFFSET;
103     }
104 
GetSortIdOffset(int entry)105     static int GetSortIdOffset(int entry)
106     {
107         return entry * ELEMENTS_LENGTH + SORT_ID_OFFSET;
108     }
109 
GetAbcRequestOffset(int entry)110     static uint32_t GetAbcRequestOffset(int entry)
111     {
112         return entry * ELEMENTS_LENGTH + ABC_ID_OFFSET;
113     }
114 };
115 
116 class TSManager {
117 public:
118     explicit TSManager(EcmaVM *vm);
119     ~TSManager() = default;
120 
121     void Initialize();
122 
123     void Dump();
124 
125     void Iterate(const RootVisitor &v);
126 
GetTSModuleTable()127     JSHandle<TSModuleTable> GetTSModuleTable() const
128     {
129         return JSHandle<TSModuleTable>(reinterpret_cast<uintptr_t>(&globalModuleTable_));
130     }
131 
SetTSModuleTable(JSHandle<TSModuleTable> table)132     void SetTSModuleTable(JSHandle<TSModuleTable> table)
133     {
134         globalModuleTable_ = table.GetTaggedValue();
135     }
136 
137     JSHandle<TSTypeTable> GetTSTypeTable(int entry) const;
138 
139     void SetTSTypeTable(const JSHandle<TSTypeTable> &table, int tableId) const;
140 
141     void GenerateBuiltinSummary();
142 
GetBuiltinOffset(uint32_t index)143     inline uint32_t GetBuiltinOffset(uint32_t index) const
144     {
145         if (index == static_cast<uint32_t>(BuiltinTypeId::NUM_INDEX_IN_SUMMARY)) {
146             return builtinOffsets_[index];
147         }
148         return builtinOffsets_[index - static_cast<uint32_t>(BuiltinTypeId::BUILTIN_OFFSET)];
149     }
150 
GetPropType(GlobalTSTypeRef gt,JSTaggedValue propertyName)151     inline GlobalTSTypeRef PUBLIC_API GetPropType(GlobalTSTypeRef gt, JSTaggedValue propertyName) const
152     {
153         return GetPropType(gt, JSHandle<JSTaggedValue>(thread_, propertyName));
154     }
155 
156     GlobalTSTypeRef PUBLIC_API GetPropType(GlobalTSTypeRef gt, const uint64_t key) const;
157 
158     GlobalTSTypeRef PUBLIC_API GetIndexSignType(GlobalTSTypeRef objType, kungfu::GateType indexType) const;
159 
CreateClassInstanceType(kungfu::GateType gateType)160     inline GlobalTSTypeRef PUBLIC_API CreateClassInstanceType(kungfu::GateType gateType)
161     {
162         GlobalTSTypeRef gt = gateType.GetGTRef();
163         return CreateClassInstanceType(gt);
164     }
165 
166     GlobalTSTypeRef PUBLIC_API CreateClassInstanceType(GlobalTSTypeRef gt);
167 
GetClassType(kungfu::GateType gateType)168     inline GlobalTSTypeRef PUBLIC_API GetClassType(kungfu::GateType gateType)
169     {
170         GlobalTSTypeRef gt = gateType.GetGTRef();
171         return GetClassType(gt);
172     }
173 
174     GlobalTSTypeRef PUBLIC_API GetClassType(GlobalTSTypeRef classInstanceGT) const;
175 
176     JSHandle<TSClassType> GetExtendedClassType(JSHandle<TSClassType> classType) const;
177 
178     TSClassType* GetExtendedClassType(const TSClassType *classType) const;
179 
180     uint32_t PUBLIC_API GetUnionTypeLength(GlobalTSTypeRef gt) const;
181 
182     GlobalTSTypeRef PUBLIC_API GetUnionTypeByIndex(GlobalTSTypeRef gt, int index) const;
183 
184     GlobalTSTypeRef PUBLIC_API GetOrCreateUnionType(CVector<GlobalTSTypeRef> unionTypeVec);
185 
186     uint32_t PUBLIC_API GetFunctionTypeLength(GlobalTSTypeRef gt) const;
187 
188     GlobalTSTypeRef PUBLIC_API GetOrCreateTSIteratorInstanceType(TSRuntimeType runtimeType, GlobalTSTypeRef elementGt);
189 
190     GlobalTSTypeRef PUBLIC_API GetIteratorInstanceElementGt(GlobalTSTypeRef gt) const;
191 
GetIteratorInstanceElementGt(kungfu::GateType gateType)192     inline GlobalTSTypeRef PUBLIC_API GetIteratorInstanceElementGt(kungfu::GateType gateType) const
193     {
194         GlobalTSTypeRef gt = GlobalTSTypeRef(gateType.GetGTRef());
195         return GetIteratorInstanceElementGt(gt);
196     }
197 
198     bool PUBLIC_API IsStaticFunc(GlobalTSTypeRef gt) const;
199 
200     bool PUBLIC_API IsHotnessFunc(GlobalTSTypeRef gt) const;
201 
202     void PUBLIC_API SetHotnessFunc(GlobalTSTypeRef gt, bool isHotness) const;
203 
204     bool PUBLIC_API GetSuperGateType(kungfu::GateType &gateType) const;
205 
206     GlobalTSTypeRef PUBLIC_API GetSuperPropType(GlobalTSTypeRef gt,
207                                                 JSHandle<JSTaggedValue> propertyName,
208                                                 PropertyType propType) const;
209 
GetSuperPropType(GlobalTSTypeRef gt,JSTaggedValue propertyName,PropertyType propType)210     inline GlobalTSTypeRef PUBLIC_API GetSuperPropType(GlobalTSTypeRef gt,
211                                                        JSTaggedValue propertyName,
212                                                        PropertyType propType) const
213     {
214         return GetSuperPropType(gt, JSHandle<JSTaggedValue>(vm_->GetJSThread(), propertyName),
215                                 propType);
216     }
217 
218     GlobalTSTypeRef PUBLIC_API GetSuperPropType(GlobalTSTypeRef gt,
219                                                 const uint64_t key,
220                                                 PropertyType propType) const;
221 
222     GlobalTSTypeRef PUBLIC_API GetFuncParameterTypeGT(GlobalTSTypeRef gt, int index) const;
223 
224     GlobalTSTypeRef PUBLIC_API GetFuncThisGT(GlobalTSTypeRef gt) const;
225 
226     void PUBLIC_API SetFuncMethodOffset(GlobalTSTypeRef gt, uint32_t methodOffset);
227 
228     uint32_t PUBLIC_API GetFuncMethodOffset(GlobalTSTypeRef gt) const;
229 
230     bool PUBLIC_API IsGetterSetterFunc(GlobalTSTypeRef gt) const;
231 
232     bool IsAbstractMethod(GlobalTSTypeRef gt) const;
233 
234     bool IsMethodSignature(GlobalTSTypeRef gt) const;
235     bool CanFastCall(GlobalTSTypeRef gt) const;
236     bool IsNoGC(GlobalTSTypeRef gt) const;
237     bool MethodOffsetIsVaild(GlobalTSTypeRef gt) const;
238     bool FastCallFlagIsVaild(GlobalTSTypeRef gt) const;
239 
GetFuncReturnValueTypeGT(kungfu::GateType gateType)240     inline GlobalTSTypeRef PUBLIC_API GetFuncReturnValueTypeGT(kungfu::GateType gateType) const
241     {
242         GlobalTSTypeRef gt = gateType.GetGTRef();
243         return GetFuncReturnValueTypeGT(gt);
244     }
245 
246     GlobalTSTypeRef PUBLIC_API GetFuncReturnValueTypeGT(GlobalTSTypeRef gt) const;
247 
248     std::string PUBLIC_API GetFuncName(kungfu::GateType gt) const;
249 
250     int PUBLIC_API GetMethodIndex(GlobalTSTypeRef gt) const;
251 
GetArrayParameterTypeGT(kungfu::GateType gateType)252     inline GlobalTSTypeRef PUBLIC_API GetArrayParameterTypeGT(kungfu::GateType gateType) const
253     {
254         GlobalTSTypeRef gt = gateType.GetGTRef();
255         return GetArrayParameterTypeGT(gt);
256     }
257 
258     GlobalTSTypeRef PUBLIC_API GetArrayParameterTypeGT(GlobalTSTypeRef gt) const;
259 
AssertTypes()260     bool PUBLIC_API AssertTypes() const
261     {
262         return assertTypes_;
263     }
264 
GetTypeThreshold()265     double PUBLIC_API GetTypeThreshold() const
266     {
267         return typeThreshold_;
268     }
269 
IsBuiltinsDTSEnabled()270     bool IsBuiltinsDTSEnabled() const
271     {
272         return vm_->GetJSOptions().WasSetBuiltinsDTS();
273     }
274 
GetBuiltinsDTS()275     CString GetBuiltinsDTS() const
276     {
277         std::string fileName = vm_->GetJSOptions().GetBuiltinsDTS();
278         return CString(fileName);
279     }
280 
281     void AddInstanceTSHClass(GlobalTSTypeRef gt, JSHandle<JSHClass> &ihclass);
282 
283     void AddConstructorTSHClass(GlobalTSTypeRef gt, JSHandle<JSHClass> &constructorHClass);
284 
285     JSTaggedValue GetInstanceTSHClass(const JSHandle<TSClassType> &classType) const;
286 
287     bool HasTSHClass(const JSHandle<TSClassType> &classType) const;
288 
289     bool HasTSHClass(const TSClassType *classType) const;
290 
291     JSHandle<JSTaggedValue> GetTSType(const GlobalTSTypeRef &gt) const;
292 
293     std::string PUBLIC_API GetTypeStr(kungfu::GateType gateType) const;
294 
295     int PUBLIC_API GetHClassIndexByObjectType(const kungfu::GateType &gateType);
296 
297     int PUBLIC_API GetHClassIndexByInstanceGateType(const kungfu::GateType &gateType);
298 
299     int PUBLIC_API GetConstructorHClassIndexByClassGateType(const kungfu::GateType &gateType);
300 
301     int PUBLIC_API GetHClassIndexByClassGateType(const kungfu::GateType &gateType);
302 
303     JSTaggedValue GetTSHClass(const kungfu::GateType &gateType) const;
304 
305     JSTaggedValue PUBLIC_API GetAOTHClassInfoByIndex(uint32_t index);
306 
307     GlobalTSTypeRef PUBLIC_API CreateArrayType();
308 
309     GlobalTSTypeRef PUBLIC_API CreateNamespaceType();
310 
311     bool AddNamespacePropType(kungfu::GateType objType, JSTaggedValue name, kungfu::GateType valueType);
312 
IsUserDefinedClassTypeKind(const kungfu::GateType & gateType)313     inline bool IsUserDefinedClassTypeKind(const kungfu::GateType &gateType) const
314     {
315         GlobalTSTypeRef gt = gateType.GetGTRef();
316         return IsUserDefinedClassTypeKind(gt);
317     }
318 
IsUserDefinedClassTypeKind(const GlobalTSTypeRef & gt)319     inline bool IsUserDefinedClassTypeKind(const GlobalTSTypeRef &gt) const
320     {
321         return IsClassTypeKind(gt) && (!gt.IsBuiltinModule());
322     }
323 
StoreNamespaceType(const uint32_t methodOffset,const kungfu::GateType type)324     inline void StoreNamespaceType(const uint32_t methodOffset, const kungfu::GateType type)
325     {
326         methodOffsetToType_.insert(std::make_pair(methodOffset, type));
327     }
328 
GetNamespaceObjType(const uint32_t methodOffset)329     inline kungfu::GateType GetNamespaceObjType(const uint32_t methodOffset) const
330     {
331         ASSERT(HasInferredNamespaceType(methodOffset));
332         return methodOffsetToType_.at(methodOffset);
333     }
334 
HasInferredNamespaceType(const uint32_t methodOffset)335     inline bool HasInferredNamespaceType(const uint32_t methodOffset) const
336     {
337         return methodOffsetToType_.find(methodOffset) != methodOffsetToType_.end();
338     }
339 
GetEcmaVM()340     EcmaVM *GetEcmaVM() const
341     {
342         return vm_;
343     }
344 
GetThread()345     JSThread *GetThread() const
346     {
347         return thread_;
348     }
349 
350 #define IS_TSTYPEKIND_METHOD_LIST(V)                    \
351     V(Primitive, TSTypeKind::PRIMITIVE)                 \
352     V(Class, TSTypeKind::CLASS)                         \
353     V(ClassInstance, TSTypeKind::CLASS_INSTANCE)        \
354     V(Function, TSTypeKind::FUNCTION)                   \
355     V(Union, TSTypeKind::UNION)                         \
356     V(Array, TSTypeKind::ARRAY)                         \
357     V(Object, TSTypeKind::OBJECT)                       \
358     V(Import, TSTypeKind::IMPORT)                       \
359     V(Interface, TSTypeKind::INTERFACE)                 \
360     V(IteratorInstance, TSTypeKind::ITERATOR_INSTANCE)  \
361     V(Namespace, TSTypeKind::NAMESPACE)
362 
363 #define IS_TSTYPEKIND(NAME, TSTYPEKIND)                                                \
364     inline bool PUBLIC_API Is##NAME##TypeKind(const kungfu::GateType &gateType) const  \
365     {                                                                                  \
366         GlobalTSTypeRef gt = gateType.GetGTRef();                                      \
367         return GetTypeKind(gt) == (TSTYPEKIND);                                        \
368     }                                                                                  \
369                                                                                        \
370     inline bool PUBLIC_API Is##NAME##TypeKind(const GlobalTSTypeRef &gt) const         \
371     {                                                                                  \
372         return GetTypeKind(gt) == (TSTYPEKIND);                                        \
373     }
374 
375     IS_TSTYPEKIND_METHOD_LIST(IS_TSTYPEKIND)
376 #undef IS_TSTYPEKIND
377 
378     bool PUBLIC_API IsBuiltinClassType(BuiltinTypeId id, kungfu::GateType gateType) const;
379 
380     bool PUBLIC_API IsBuiltinInstanceType(BuiltinTypeId id, kungfu::GateType gateType) const;
381 
382     bool PUBLIC_API IsTypedArrayType(kungfu::GateType gateType) const;
383 
384     bool PUBLIC_API IsValidTypedArrayType(kungfu::GateType gateType) const;
385 
IsBuiltinObjectType(kungfu::GateType gateType)386     inline bool PUBLIC_API IsBuiltinObjectType(kungfu::GateType gateType) const
387     {
388         return gateType.GetGTRef().IsBuiltinModule() && IsClassTypeKind(gateType);
389     }
390 
391     bool PUBLIC_API IsIntTypedArrayType(kungfu::GateType gateType) const;
392 
393     bool PUBLIC_API IsDoubleTypedArrayType(kungfu::GateType gateType) const;
394 
395     BuiltinTypeId PUBLIC_API GetTypedArrayBuiltinId(kungfu::GateType gateType) const;
396 
397     static const std::vector<BuiltinTypeId> &GetValidTypedArrayIds();
398 
399     inline void AddElementToIdGTMap(const GlobalTypeID &id, GlobalTSTypeRef gt,
400                                     const CString &recordName = "", bool isImportType = false)
401     {
402         auto it = idGTMap_.find(id);
403         if (it != idGTMap_.end()) {
404             it->second = gt;
405         } else {
406             idGTMap_.emplace(id, gt);
407         }
408         if (!isImportType && !id.IsPGOType()) {
409             auto value = std::make_tuple(id.GetJSPandaFile()->GetNormalizedFileDesc(), recordName, id.GetTypeId());
410             gtLiteralOffsetMap_.emplace(gt, value);
411         }
412     }
413 
HasCreatedGT(const GlobalTypeID & id)414     inline bool HasCreatedGT(const GlobalTypeID &id) const
415     {
416         return idGTMap_.find(id) != idGTMap_.end();
417     }
418 
GetGTByGlobalTypeID(const GlobalTypeID & id)419     inline GlobalTSTypeRef GetGTByGlobalTypeID(const GlobalTypeID &id) const
420     {
421         return idGTMap_.at(id);
422     }
423 
HasOffsetFromGT(GlobalTSTypeRef gt)424     inline bool HasOffsetFromGT(GlobalTSTypeRef gt) const
425     {
426         return gtLiteralOffsetMap_.find(gt) != gtLiteralOffsetMap_.end();
427     }
428 
GetOffsetFromGt(GlobalTSTypeRef gt)429     inline std::tuple<CString, CString, uint32_t> GetOffsetFromGt(GlobalTSTypeRef gt) const
430     {
431         return gtLiteralOffsetMap_.at(gt);
432     }
433 
AddTypeToModuleVarGtMap(const JSPandaFile * jsPandaFile,const CString & recordName,uint32_t index,GlobalTSTypeRef gt)434     inline void AddTypeToModuleVarGtMap(const JSPandaFile *jsPandaFile, const CString &recordName,
435                                         uint32_t index, GlobalTSTypeRef gt)
436     {
437         ModuleInfo key = {jsPandaFile, recordName, index};
438         if (moduleVarGtMap_.find(key) == moduleVarGtMap_.end()) {
439             moduleVarGtMap_.emplace(key, gt);
440         } else {
441             moduleVarGtMap_[key] = gt;
442         }
443     }
444 
HasExportGT(const JSPandaFile * jsPandaFile,const CString & recordName,uint32_t index)445     inline bool HasExportGT(const JSPandaFile *jsPandaFile, const CString &recordName,
446                             uint32_t index) const
447     {
448         ModuleInfo key = {jsPandaFile, recordName, index};
449         return moduleVarGtMap_.find(key) != moduleVarGtMap_.end();
450     }
451 
GetGTFromModuleMap(const JSPandaFile * jsPandaFile,const CString & recordName,uint32_t index)452     inline GlobalTSTypeRef GetGTFromModuleMap(const JSPandaFile *jsPandaFile, const CString &recordName,
453                                               uint32_t index) const
454     {
455         ModuleInfo key = {jsPandaFile, recordName, index};
456         return moduleVarGtMap_.at(key);
457     }
458 
AddResolvedExportTable(const JSPandaFile * jsPandaFile,const CString & recordName,JSTaggedValue exportTable)459     inline void AddResolvedExportTable(const JSPandaFile *jsPandaFile, const CString &recordName,
460                                        JSTaggedValue exportTable)
461     {
462         auto key = std::make_pair(jsPandaFile, recordName);
463         if (resolvedExportTable_.find(key) == resolvedExportTable_.end()) {
464             resolvedExportTable_.emplace(key, exportTable);
465         } else {
466             resolvedExportTable_[key] = exportTable;
467         }
468     }
469 
HasResolvedExportTable(const JSPandaFile * jsPandaFile,const CString & recordName)470     inline bool HasResolvedExportTable(const JSPandaFile *jsPandaFile, const CString &recordName) const
471     {
472         auto key = std::make_pair(jsPandaFile, recordName);
473         return resolvedExportTable_.find(key) != resolvedExportTable_.end();
474     }
475 
GetResolvedExportTable(const JSPandaFile * jsPandaFile,const CString & recordName)476     inline JSTaggedValue GetResolvedExportTable(const JSPandaFile *jsPandaFile, const CString &recordName) const
477     {
478         auto key = std::make_pair(jsPandaFile, recordName);
479         return resolvedExportTable_.at(key);
480     }
481 
IsTSIterator(GlobalTSTypeRef gt)482     bool IsTSIterator(GlobalTSTypeRef gt) const
483     {
484         uint32_t l = gt.GetLocalId();
485         return gt.IsRuntimeModule() && (l == static_cast<uint32_t>(TSRuntimeType::ITERATOR));
486     }
487 
IsTSIteratorResult(GlobalTSTypeRef gt)488     bool IsTSIteratorResult(GlobalTSTypeRef gt) const
489     {
490         uint32_t l = gt.GetLocalId();
491         return gt.IsRuntimeModule() && (l == static_cast<uint32_t>(TSRuntimeType::ITERATOR_RESULT));
492     }
493 
494     void PUBLIC_API SetCurConstantPool(const JSPandaFile *jsPandaFile, uint32_t methodOffset);
495 
496     int32_t PUBLIC_API GetConstantPoolIDByMethodOffset(const JSPandaFile *jsPandaFile, uint32_t methodOffset);
497 
498     uint32_t GetConstantPoolId(uint32_t methodId) const;
499     JSTaggedValue GetConstantPool(uint32_t methodId) const;
500 
GetConstantPool()501     JSHandle<JSTaggedValue> PUBLIC_API GetConstantPool() const
502     {
503         return JSHandle<JSTaggedValue>(uintptr_t(&curCP_));
504     }
505 
506     JSTaggedValue PUBLIC_API GetStringFromConstantPool(uint32_t methodId, const uint16_t stringId) const;
507 
GetStdStringFromConstantPool(uint32_t methodId,const uint16_t stringId)508     inline std::string PUBLIC_API GetStdStringFromConstantPool(uint32_t methodId, const uint16_t stringId) const
509     {
510         JSTaggedValue str = GetStringFromConstantPool(methodId, stringId);
511         return EcmaStringAccessor(str).ToStdString(StringConvertedUsage::LOGICOPERATION);
512     }
513 
514     bool PUBLIC_API IsBuiltinObjectMethod(BuiltinTypeId id, kungfu::GateType funcType) const;
515     bool PUBLIC_API IsBuiltinConstructor(BuiltinTypeId id, GlobalTSTypeRef ctorType) const;
516 
GetBuiltinPandaFile()517     inline const JSPandaFile *GetBuiltinPandaFile() const
518     {
519         return builtinPandaFile_;
520     }
521 
GetBuiltinRecordName()522     inline const CString &GetBuiltinRecordName() const
523     {
524         return builtinsRecordName_;
525     }
526 
GetBytecodeInfoCollector()527     inline kungfu::BytecodeInfoCollector *GetBytecodeInfoCollector() const
528     {
529         return bcInfoCollector_;
530     }
531 
SetBytecodeInfoCollector(kungfu::BytecodeInfoCollector * bcInfoCollector)532     inline void SetBytecodeInfoCollector(kungfu::BytecodeInfoCollector *bcInfoCollector)
533     {
534         bcInfoCollector_ = bcInfoCollector;
535     }
536 
537     class IHClassData {
538     public:
IHClassData(JSTaggedType ihc)539         explicit IHClassData(JSTaggedType ihc) : ihc_(ihc) {}
540 
Iterate(const RootVisitor & v)541         void Iterate(const RootVisitor &v)
542         {
543             v(Root::ROOT_VM, ObjectSlot(reinterpret_cast<uintptr_t>(&ihc_)));
544         }
545 
GetCPIndexMap()546         std::unordered_map<int32_t, uint32_t>& GetCPIndexMap()
547         {
548             return cpIndexMap_;
549         }
550 
GetIHC()551         JSTaggedType GetIHC() const
552         {
553             return ihc_;
554         }
555 
556     private:
557         JSTaggedType ihc_ {0};
558         std::unordered_map<int32_t, uint32_t> cpIndexMap_ {};
559     };
560 
SetCompilationDriver(kungfu::CompilationDriver * cmpDriver)561     void SetCompilationDriver(kungfu::CompilationDriver *cmpDriver)
562     {
563         cmpDriver_ = cmpDriver;
564     }
565 
GetCompilationDriver()566     kungfu::CompilationDriver *GetCompilationDriver() const
567     {
568         return cmpDriver_;
569     }
570 
AddElementToClassNameMap(const JSPandaFile * jsPandaFile,uint32_t offset,std::string className)571     void AddElementToClassNameMap(const JSPandaFile *jsPandaFile, uint32_t offset, std::string className)
572     {
573         literalOffsetClassNameMap_.emplace(std::make_pair(jsPandaFile, offset), className);
574     }
575 
GetClassNameByOffset(const JSPandaFile * jsPandaFile,uint32_t typeId)576     const std::string GetClassNameByOffset(const JSPandaFile *jsPandaFile, uint32_t typeId) const
577     {
578         std::pair<const JSPandaFile *, uint32_t> pair = std::make_pair(jsPandaFile, typeId);
579         std::string name = "";
580         if (literalOffsetClassNameMap_.find(pair) != literalOffsetClassNameMap_.end()) {
581             name = literalOffsetClassNameMap_.at(pair);
582         }
583         return name;
584     }
585 
CollectGT(GlobalTSTypeRef gt)586     inline void CollectGT(GlobalTSTypeRef gt)
587     {
588         if (IsClassTypeKind(gt)) {
589             collectedGT_.insert(gt);
590         }
591     }
592 
GetCollectedGT()593     inline std::set<GlobalTSTypeRef>& GetCollectedGT()
594     {
595         return collectedGT_;
596     }
597 
InsertLiteralGTMap(TypeLocation & loc,GlobalTSTypeRef gt)598     inline void InsertLiteralGTMap(TypeLocation &loc, GlobalTSTypeRef gt)
599     {
600         literalGTMap_[loc] = gt;
601     }
602 
GetLiteralGT(TypeLocation & loc)603     inline GlobalTSTypeRef GetLiteralGT(TypeLocation &loc)
604     {
605         auto it = literalGTMap_.find(loc);
606         if (it != literalGTMap_.end()) {
607             return it->second;
608         }
609         return GlobalTSTypeRef::Default();
610     }
611 
InsertPtToGtMap(ProfileType pgoType,const kungfu::GateType & gateType)612     inline void InsertPtToGtMap(ProfileType pgoType, const kungfu::GateType &gateType)
613     {
614         ptToGtMap_.emplace(pgoType, gateType);
615     }
616 
GetGateTypeByPt(ProfileType pgoType)617     inline const kungfu::GateType GetGateTypeByPt(ProfileType pgoType)
618     {
619         if (pgoType.IsBuiltinsType()) {
620             return GetBuiltinsGateTypeByPt(pgoType);
621         }
622         auto it = ptToGtMap_.find(pgoType);
623         if (it != ptToGtMap_.end()) {
624             return it->second;
625         }
626         return kungfu::GateType::AnyType();
627     }
628 
629     void PrintNumOfTypes() const;
630 
631     void PrintTypeInfo(const JSPandaFile *jsPandaFile) const;
632 
633     kungfu::GateType TryNarrowUnionType(kungfu::GateType gateType);
634 
635     JSHandle<TaggedArray> GetExportTableFromLiteral(const JSPandaFile *jsPandaFile, const CString &recordName);
636 
637     int GetHClassIndex(GlobalTSTypeRef classGT, bool isConstructor = false);
638 
GetPGOGTCountByRecordName(const CString & recordName)639     uint32_t GetPGOGTCountByRecordName(const CString &recordName) const
640     {
641         if (bcInfoCollector_ == nullptr) {
642             return 0;
643         }
644         const kungfu::PGOBCInfo *bcInfo = bcInfoCollector_->GetPGOBCInfo();
645         return bcInfo->GetPGOExtendGTCount(recordName);
646     }
647 
GetBuiltinsName(GlobalTSTypeRef builtinGT)648     inline std::string GetBuiltinsName(GlobalTSTypeRef builtinGT) const
649     {
650         uint32_t index = GetBuiltinIndex(builtinGT);
651         return GetBuiltinsName(index);
652     }
653 
654     TSTypeKind PUBLIC_API GetTypeKind(const GlobalTSTypeRef &gt) const;
655 
656 #define TSTYPETABLE_ACCESSOR_LIST(V)       \
657     V(Builtin, ModuleTableIdx::BUILTIN)    \
658     V(Inferred, ModuleTableIdx::INFERRED)  \
659     V(Runtime, ModuleTableIdx::RUNTIME)    \
660     V(Generics, ModuleTableIdx::GENERICS)
661 
662 #define TSTYPETABLE_ACCESSOR(NAME, MODULEID)                                             \
663     inline GlobalTSTypeRef AddTSTypeTo##NAME##Table(const JSHandle<TSType> &type) const  \
664     {                                                                                    \
665         return AddTSTypeToTypeTable(type, static_cast<uint32_t>(MODULEID));              \
666     }                                                                                    \
667                                                                                          \
668     inline JSHandle<TSTypeTable> Get##NAME##Table() const                                \
669     {                                                                                    \
670         return GetTSTypeTable(static_cast<uint32_t>(MODULEID));                          \
671     }                                                                                    \
672                                                                                          \
673     inline void Set##NAME##Table(const JSHandle<TSTypeTable> &table)                     \
674     {                                                                                    \
675         SetTSTypeTable(table, static_cast<uint32_t>(MODULEID));                          \
676     }
677 
678     TSTYPETABLE_ACCESSOR_LIST(TSTYPETABLE_ACCESSOR)
679 #undef TSTYPETABLE_ACCESSOR
680 
681 private:
682     NO_COPY_SEMANTIC(TSManager);
683     NO_MOVE_SEMANTIC(TSManager);
684 
685     GlobalTSTypeRef AddTSTypeToTypeTable(const JSHandle<TSType> &type, int tableId) const;
686 
687     JSHandle<TaggedArray> GenerateExportTableFromLiteral(const JSPandaFile *jsPandaFile, const CString &recordName);
688 
689     GlobalTSTypeRef FindUnionInTypeTable(JSHandle<TSTypeTable> table, JSHandle<TSUnionType> unionType) const;
690 
691     GlobalTSTypeRef FindIteratorInstanceInInferTable(GlobalTSTypeRef kindGt, GlobalTSTypeRef elementGt) const;
692 
693     GlobalTSTypeRef PUBLIC_API GetPropType(GlobalTSTypeRef gt, JSHandle<JSTaggedValue> propertyName) const;
694 
695     std::string GetClassTypeStr(GlobalTSTypeRef gt) const;
696 
697     std::string GetClassInstanceTypeStr(GlobalTSTypeRef gt) const;
698 
699     std::string GetFunctionTypeStr(GlobalTSTypeRef gt) const;
700 
701     std::string GetArrayTypeStr(GlobalTSTypeRef gt) const;
702 
703     std::string GetPrimitiveStr(const GlobalTSTypeRef &gt) const;
704 
705     uint32_t RecordIhcToVecAndIndexMap(IHClassData &ihcData);
706 
707     uint32_t GetBuiltinIndex(GlobalTSTypeRef builtinGT) const;
708 
709     std::string GetBuiltinsName(uint32_t index) const;
710 
SetBuiltinPandaFile(JSPandaFile * jsPandaFile)711     inline void SetBuiltinPandaFile(JSPandaFile *jsPandaFile)
712     {
713         builtinPandaFile_ = jsPandaFile;
714     }
715 
SetBuiltinRecordName(CString & builtinsRecordName)716     inline void SetBuiltinRecordName(CString &builtinsRecordName)
717     {
718         builtinsRecordName_ = builtinsRecordName;
719     }
720 
721     // for jsarray
722     void TryGetElmsKind(panda_file::File::EntityId id, JSHandle<JSTaggedValue> &ekd);
723 
724     const kungfu::GateType GetBuiltinsGateTypeByPt(ProfileType pgoType);
725 
726     BuiltinTypeId GetBuiltinTypeIdByJSType(JSType jsType);
727 
728     EcmaVM *vm_ {nullptr};
729     JSThread *thread_ {nullptr};
730     ObjectFactory *factory_ {nullptr};
731     // kungfu::PGOTypeManager ptManager_;
732     JSTaggedValue globalModuleTable_ {JSTaggedValue::Hole()};
733     CMap<ProfileType, const kungfu::GateType> ptToGtMap_ {};
734     std::map<GlobalTSTypeRef, IHClassData> gtIhcMap_ {};
735     std::map<GlobalTSTypeRef, IHClassData> gtConstructorhcMap_ {};
736     std::unordered_map<TypeLocation, GlobalTSTypeRef, HashTypeLocation> literalGTMap_ {};
737     std::map<JSType, GlobalTSTypeRef> pgoBuiltinGTCache_ {};
738     bool assertTypes_ {false};
739     double typeThreshold_ {-1};
740 
741     // when the passmanager iterates each method, the curCP_ and curCPID_ should be updated
742     // so that subsequent passes (type_infer, type_bytecode_lowering) can obtain the correct constpool.
743     JSTaggedValue curCP_ {JSTaggedValue::Hole()};
744     int32_t curCPID_ {0};
745     const JSPandaFile *curJSPandaFile_ {nullptr};
746 
747     std::unordered_map<GlobalTypeID, GlobalTSTypeRef, HashGlobalTypeID> idGTMap_ {};
748     std::map<GlobalTSTypeRef, std::tuple<CString, CString, uint32_t>> gtLiteralOffsetMap_ {};
749     std::vector<uint32_t> builtinOffsets_ {};
750     JSPandaFile *builtinPandaFile_ {nullptr};
751     CString builtinsRecordName_ {""};
752     std::map<ModuleInfo, GlobalTSTypeRef> moduleVarGtMap_{};
753     kungfu::CompilationDriver *cmpDriver_ {nullptr};
754     std::set<GlobalTSTypeRef> collectedGT_ {};  // use for storing types that need to generate hclasses
755 
756     friend class EcmaVM;
757     friend class TSTypeAccessor;
758 
759     std::map<std::pair<const JSPandaFile *, uint32_t>, std::string> literalOffsetClassNameMap_ {};
760     kungfu::BytecodeInfoCollector *bcInfoCollector_ {nullptr};
761     // use for collect the literal of export type table.
762     CMap<std::pair<const JSPandaFile *, CString>, JSTaggedValue> resolvedExportTable_ {};
763     CMap<uint32_t, kungfu::GateType> methodOffsetToType_ {};
764 };
765 }  // namespace panda::ecmascript
766 
767 #endif  // ECMASCRIPT_TS_TYPES_TS_MANAGER_H
768