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 >) 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> ¶s); 234 235 JSHandle<TSFunctionType> InstantiateFuncGenericsType(const JSHandle<TSFunctionType> &genericsType, 236 const std::vector<GlobalTSTypeRef> ¶s); 237 238 JSHandle<TSClassType> InstantiateClassGenericsType(const JSHandle<TSClassType> &genericsType, 239 const std::vector<GlobalTSTypeRef> ¶s); 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> ¶s); 245 246 JSHandle<TSObjectType> InstantiateObjGenericsType(const JSHandle<TSObjectType> &oldObjType, 247 const std::vector<GlobalTSTypeRef> ¶s); 248 249 GlobalTSTypeRef TryReplaceTypePara(GlobalTSTypeRef gt, const std::vector<GlobalTSTypeRef> ¶s); 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