• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2022 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_TYPE_PARSER_H
17 #define ECMASCRIPT_TS_TYPES_TS_TYPE_PARSER_H
18 
19 #include "ecmascript/jspandafile/type_literal_extractor.h"
20 #include "ecmascript/pgo_profiler/pgo_profiler_decoder.h"
21 #include "ecmascript/ts_types/ts_type_table_generator.h"
22 
23 namespace panda::ecmascript {
24 using PGOProfilerDecoder = pgo::PGOProfilerDecoder;
25 /* TSTypeParser parses types recorded in abc files into TSTypes. VM uses TSTypeTables to
26  * store TSTypes. Each TSTypeTable is used to store all types from the same record.
27  * Since VM can only record types in GlobalTSTypeRef::MAX_MODULE_ID records and
28  * can only record GlobalTSTypeRef::MAX_LOCAL_ID types in one record, all types outside
29  * this range will not be parsed and will be treated as any.
30  * In addition to this, in the following case, types will not be parsed and will be treated as any.
31  * 1. Import types with module request that does not point to one abc file
32  * 2. Import types with module request that point to one abc file which is generated by JS
33  * 3. Types with kind that are not supported temporarily
34  */
35 class TSTypeParser {
36 public:
37     struct PGOInfo {
38         const JSPandaFile *jsPandaFile;
39         const CString &recordName;
40         uint32_t methodOffset;
41         uint32_t cpIdx;
42         PGOSampleType pgoType;
43         kungfu::PGOBCInfo::Type type;
44         PGOProfilerDecoder *decoder;
45         bool enableOptTrackField;
46     };
47 
48     explicit TSTypeParser(TSManager *tsManager);
49     ~TSTypeParser() = default;
50 
51     GlobalTSTypeRef PUBLIC_API CreateGT(const JSPandaFile *jsPandaFile, const CString &recordName, uint32_t typeId);
52 
53     GlobalTSTypeRef PUBLIC_API CreatePGOGT(PGOInfo info);
54 
IsUserDefinedType(const uint32_t typeId)55     inline static bool IsUserDefinedType(const uint32_t typeId)
56     {
57         return typeId > USER_DEFINED_TYPE_OFFSET;
58     }
59 
GetMethodList()60     inline const std::unordered_map<uint32_t, kungfu::MethodInfo> &GetMethodList() const
61     {
62         ASSERT(bcInfo_ != nullptr);
63         return bcInfo_->GetMethodList();
64     }
65 
66 private:
67     static constexpr size_t BUILDIN_TYPE_OFFSET = 20;
68     static constexpr size_t USER_DEFINED_TYPE_OFFSET = 100;
69     static constexpr size_t DEFAULT_INDEX = 0;
70     static constexpr size_t NUM_INDEX_SIG_INDEX = 1;
71     static constexpr size_t NUM_GENERICS_PARA_INDEX = 1;
72     static constexpr size_t GENERICS_PARA_OFFSET = BUILDIN_TYPE_OFFSET + 1;
73 
74     inline GlobalTSTypeRef GetAndStoreGT(const JSPandaFile *jsPandaFile, uint32_t typeId, const CString &recordName,
75                                          uint32_t moduleId = 0, uint32_t localId = 0)
76     {
77         GlobalTSTypeRef gt(moduleId, localId);
78         GlobalTypeID gId(jsPandaFile, typeId);
79         tsManager_->AddElementToIdGTMap(gId, gt, recordName);
80         return gt;
81     }
82 
83     inline GlobalTSTypeRef GetAndStoreGT(const JSPandaFile *jsPandaFile, PGOSampleType pgoTypeId,
84                                          uint32_t moduleId = 0, uint32_t localId = 0)
85     {
86         GlobalTSTypeRef gt(moduleId, localId);
87         GlobalTypeID gId(jsPandaFile, pgoTypeId);
88         tsManager_->AddElementToIdGTMap(gId, gt);
89         return gt;
90     }
91 
GetAndStoreImportGT(const JSPandaFile * jsPandaFile,uint32_t typeId,const CString & recordName,GlobalTSTypeRef gt)92     inline GlobalTSTypeRef GetAndStoreImportGT(const JSPandaFile *jsPandaFile, uint32_t typeId,
93                                                const CString &recordName, GlobalTSTypeRef gt)
94     {
95         GlobalTypeID gId(jsPandaFile, typeId);
96         tsManager_->AddElementToIdGTMap(gId, gt, recordName, true);
97         return gt;
98     }
99 
SetTSType(JSHandle<TSTypeTable> table,JSHandle<JSTaggedValue> type,const GlobalTSTypeRef & gt)100     inline void SetTSType(JSHandle<TSTypeTable> table, JSHandle<JSTaggedValue> type,
101                           const GlobalTSTypeRef &gt)
102     {
103         JSHandle<TSType>(type)->SetGT(gt);
104         uint32_t localId = gt.GetLocalId();
105         table->Set(thread_, localId, type);
106     }
107 
TypeNeedResolve(const TypeLiteralExtractor * typeLiteralExtractor)108     inline bool TypeNeedResolve(const TypeLiteralExtractor *typeLiteralExtractor) const
109     {
110         if (typeLiteralExtractor->IsGenerics()) {
111             return true;
112         }
113 
114         TSTypeKind kind = typeLiteralExtractor->GetTypeKind();
115         return kind == TSTypeKind::IMPORT || kind == TSTypeKind::INDEXSIG;
116     }
117 
118     // Primitive typetable does not correspond to a real TSTypeTable.
119     // We use gt with moduleId of ModuleTableIdx::PRIMITIVE to represent some special values.
120     // In particular, localId after GENERICS_PARA_OFFSET is denotes to
121     // the index of type parameters in generics types by subtracting this offset.
EncodeParaType(const uint32_t typeId)122     inline GlobalTSTypeRef EncodeParaType(const uint32_t typeId)
123     {
124         uint32_t absValue = (~typeId);
125         return GlobalTSTypeRef(static_cast<uint32_t>(ModuleTableIdx::PRIMITIVE), absValue + GENERICS_PARA_OFFSET);
126     }
127 
DecodePrarIndex(GlobalTSTypeRef gt)128     inline uint32_t DecodePrarIndex(GlobalTSTypeRef gt)
129     {
130         ASSERT(IsGenericsParaType(gt));
131         return (gt.GetLocalId() - GENERICS_PARA_OFFSET);
132     }
133 
IsGenericsParaType(GlobalTSTypeRef gt)134     inline bool IsGenericsParaType(GlobalTSTypeRef gt) const
135     {
136         return gt.IsPrimitiveModule() && (gt.GetLocalId() >= GENERICS_PARA_OFFSET);
137     }
138 
IsGenericsArrayType(TypeLiteralExtractor * typeLiteralExtractor)139     inline bool IsGenericsArrayType(TypeLiteralExtractor *typeLiteralExtractor) const
140     {
141         return typeLiteralExtractor->GetTypeKind() == TSTypeKind::BUILTIN_INSTANCE &&
142                typeLiteralExtractor->GetIntValue(DEFAULT_INDEX) == static_cast<uint32_t>(BuiltinTypeId::ARRAY);
143     }
144 
145     GlobalTSTypeRef ParseType(const JSPandaFile *jsPandaFile, const CString &recordName, uint32_t typeId);
146 
147     GlobalTSTypeRef ParseBuiltinObjType(uint32_t typeId);
148 
149     GlobalTSTypeRef ResolveType(const JSPandaFile *jsPandaFile, const CString &recordName,
150                                 TypeLiteralExtractor *typeLiteralExtractor);
151 
152     GlobalTSTypeRef ResolveImportType(const JSPandaFile *jsPandaFile, const CString &recordName,
153                                       TypeLiteralExtractor *typeLiteralExtractor);
154 
155     GlobalTSTypeRef ParseIndexSigType(const JSPandaFile *jsPandaFile, const CString &recordName,
156                                       TypeLiteralExtractor *typeLiteralExtractor);
157 
158     JSHandle<JSTaggedValue> ParseNonImportType(const JSPandaFile *jsPandaFile, const CString &recordName,
159                                                TypeLiteralExtractor *typeLiteralExtractor);
160 
161     JSHandle<TSClassType> ParseClassType(const JSPandaFile *jsPandaFile, const CString &recordName,
162                                          TypeLiteralExtractor *typeLiteralExtractor);
163 
164     JSHandle<JSTaggedValue> ParseClassInstanceType(const JSPandaFile *jsPandaFile, const CString &recordName,
165                                                    TypeLiteralExtractor *typeLiteralExtractor);
166 
167     JSHandle<TSInterfaceType> ParseInterfaceType(const JSPandaFile *jsPandaFile, const CString &recordName,
168                                                  TypeLiteralExtractor *typeLiteralExtractor);
169 
170     JSHandle<TSUnionType> ParseUnionType(const JSPandaFile *jsPandaFile, const CString &recordName,
171                                          TypeLiteralExtractor *typeLiteralExtractor);
172 
173     JSHandle<TSFunctionType> ParseFunctionType(const JSPandaFile *jsPandaFile, const CString &recordName,
174                                                TypeLiteralExtractor *typeLiteralExtractor);
175 
176     JSHandle<TSArrayType> ParseArrayType(const JSPandaFile *jsPandaFile, const CString &recordName,
177                                          TypeLiteralExtractor *typeLiteralExtractor);
178 
179     JSHandle<TSObjectType> ParseObjectType(const JSPandaFile *jsPandaFile, const CString &recordName,
180                                            TypeLiteralExtractor *typeLiteralExtractor);
181 
182     GlobalTSTypeRef ParsePGOType(PGOInfo &info);
183 
184     bool GetAbcNameFromProfileType(ProfileType profileType, PGOProfilerDecoder *decoder, CString &abcName);
185 
186     JSHandle<JSTaggedValue> ParseNonImportPGOType(GlobalTSTypeRef gt, PGOInfo &info);
187 
188     JSHandle<JSTaggedValue> ParseObjectPGOType(GlobalTSTypeRef gt, PGOInfo &info);
189 
190     void FillPropTypes(const JSPandaFile *jsPandaFile,
191                        const CString &recordName,
192                        const JSHandle<TSObjectType> &objectType,
193                        TypeLiteralExtractor *typeLiteralExtractor,
194                        const uint32_t numOfFieldIndex,
195                        const uint32_t gap);
196 
197     void FillInterfaceMethodTypes(const JSPandaFile *jsPandaFile,
198                                   const CString &recordName,
199                                   const JSHandle<TSObjectType> &objectType,
200                                   TypeLiteralExtractor *typeLiteralExtractor,
201                                   const uint32_t numExtends);
202 
203     void SetClassName(const JSHandle<TSClassType> &classType,
204                       const JSPandaFile *jsPandaFile,
205                       TypeLiteralExtractor *typeLiteralExtractor);
206 
207     void SetSuperClassType(const JSHandle<TSClassType> &classType,
208                            const JSPandaFile *jsPandaFile,
209                            const CString &recordName,
210                            TypeLiteralExtractor *typeLiteralExtractor);
211 
212     void SetFunctionThisType(const JSHandle<TSFunctionType> &functionType,
213                              const JSPandaFile *jsPandaFile,
214                              const CString &recordName,
215                              TypeLiteralExtractor *typeLiteralExtractor);
216 
217     void StoreMethodOffset(const JSHandle<TSFunctionType> &functionType, TypeLiteralExtractor *typeLiteralExtractor);
218 
219     JSHandle<JSTaggedValue> GenerateExportTableFromRecord(const JSPandaFile *jsPandaFile, const CString &recordName,
220                                                           const JSHandle<TSTypeTable> &table);
221 
222     JSHandle<EcmaString> GenerateImportRelativePath(JSHandle<EcmaString> importRel) const;
223 
224     JSHandle<EcmaString> GenerateImportVar(JSHandle<EcmaString> import) const;
225 
226     GlobalTSTypeRef GetExportGTByName(JSHandle<EcmaString> target, JSHandle<TaggedArray> &exportTable,
227                                       const JSPandaFile *jsPandaFile, const CString &recordName,
228                                       std::unordered_set<CString> &markSet);
229 
230     GlobalTSTypeRef IterateStarExport(JSHandle<EcmaString> target, const JSPandaFile *jsPandaFile,
231                                       const CString &recordName, std::unordered_set<CString> &markSet);
232 
233     GlobalTSTypeRef ParseGenericsType(const JSPandaFile *jsPandaFile, const CString &recordName,
234                                       TypeLiteralExtractor *typeLiteralExtractor);
235 
236     JSHandle<JSTaggedValue> ParseGenericsInstanceType(const JSPandaFile *jsPandaFile, const CString &recordName,
237                                                       TypeLiteralExtractor *typeLiteralExtractor);
238 
239     JSHandle<JSTaggedValue> InstantiateGenericsType(const JSHandle<JSTaggedValue> &genericsType,
240                                                     const std::vector<GlobalTSTypeRef> &paras);
241 
242     JSHandle<TSFunctionType> InstantiateFuncGenericsType(const JSHandle<TSFunctionType> &genericsType,
243                                                          const std::vector<GlobalTSTypeRef> &paras);
244 
245     JSHandle<TSClassType> InstantiateClassGenericsType(const JSHandle<TSClassType> &genericsType,
246                                                        const std::vector<GlobalTSTypeRef> &paras);
247 
248     void CopyClassName(const JSHandle<TSClassType> &genericsType, const JSHandle<TSClassType> &classType);
249 
250     JSHandle<TSInterfaceType> InstantiateInterfaceGenericsType(const JSHandle<TSInterfaceType> &genericsType,
251                                                                const std::vector<GlobalTSTypeRef> &paras);
252 
253     JSHandle<TSObjectType> InstantiateObjGenericsType(const JSHandle<TSObjectType> &oldObjType,
254                                                       const std::vector<GlobalTSTypeRef> &paras);
255 
256     GlobalTSTypeRef TryReplaceTypePara(GlobalTSTypeRef gt, const std::vector<GlobalTSTypeRef> &paras);
257 
258     TSManager *tsManager_ {nullptr};
259     EcmaVM *vm_ {nullptr};
260     JSThread *thread_ {nullptr};
261     ObjectFactory *factory_ {nullptr};
262     TSTypeTableGenerator tableGenerator_;
263     kungfu::BCInfo *bcInfo_ {nullptr};
264 };
265 
266 struct ClassLiteralInfo {
267     explicit ClassLiteralInfo(const TypeLiteralExtractor *typeLiteralExtractor);
268     ~ClassLiteralInfo() = default;
269 
270     static constexpr uint32_t SUPER_CLASS_INDEX = 1;
271     static constexpr uint32_t NUM_IMPLEMENTS_INDEX = 2;
272 
273     uint32_t numNonStaticFieldsIndex {0};
274     uint32_t numNonStaticMethodsIndex {0};
275     uint32_t numStaticFieldsIndex {0};
276     uint32_t numStaticMethodsIndex {0};
277 };
278 
279 struct InterfaceLiteralInfo {
280     explicit InterfaceLiteralInfo(const TypeLiteralExtractor *typeLiteralExtractor);
281     ~InterfaceLiteralInfo() = default;
282 
283     static constexpr uint32_t NUM_EXTENDS_INDEX = 0;
284 
285     uint32_t numFieldsIndex {0};
286     uint32_t numMethodsIndex {0};
287 };
288 
289 struct FunctionLiteralInfo {
290     explicit FunctionLiteralInfo(const TypeLiteralExtractor *typeLiteralExtractor);
291     ~FunctionLiteralInfo() = default;
292 
293     static constexpr uint32_t BITFIELD_INDEX = 0;
294     static constexpr uint32_t NAME_INDEX = 1;
295     static constexpr uint32_t HAS_THIS_TYPE_INDEX = 2;
296 
297     uint32_t numParasIndex {0};
298     uint32_t returnTypeIndex {0};
299 };
300 }  // panda::ecmascript
301 #endif  // ECMASCRIPT_TS_TYPES_TS_TYPE_PARSER_H
302