• 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/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 &gt) 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 &gt) 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 &gt) 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 &gt) 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 &gt) 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