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