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