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 >) 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> ¶s); 241 242 JSHandle<TSFunctionType> InstantiateFuncGenericsType(const JSHandle<TSFunctionType> &genericsType, 243 const std::vector<GlobalTSTypeRef> ¶s); 244 245 JSHandle<TSClassType> InstantiateClassGenericsType(const JSHandle<TSClassType> &genericsType, 246 const std::vector<GlobalTSTypeRef> ¶s); 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> ¶s); 252 253 JSHandle<TSObjectType> InstantiateObjGenericsType(const JSHandle<TSObjectType> &oldObjType, 254 const std::vector<GlobalTSTypeRef> ¶s); 255 256 GlobalTSTypeRef TryReplaceTypePara(GlobalTSTypeRef gt, const std::vector<GlobalTSTypeRef> ¶s); 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