1 /** 2 * Copyright (c) 2021-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 _PANDA_VERIFIER_PANDA_TYPES_HPP 17 #define _PANDA_VERIFIER_PANDA_TYPES_HPP 18 19 #include "runtime/include/method.h" 20 #include "runtime/include/class.h" 21 22 #include "verification/type/type_systems.h" 23 #include "verification/type/type_system.h" 24 #include "verification/type/type_sort.h" 25 #include "verification/type/type_tags.h" 26 #include "verification/type/type_type_inl.h" 27 28 #include "verification/util/synchronized.h" 29 #include "verification/util/callable.h" 30 #include "verification/jobs/cache.h" 31 32 #include "runtime/include/mem/panda_containers.h" 33 #include "runtime/include/mem/panda_string.h" 34 35 #include "libpandabase/os/mutex.h" 36 #include "plugins.h" 37 38 namespace panda::verifier { 39 class PandaTypes { 40 public: 41 // TODO(vdyadov): change Id to hash from filename_id and entity id 42 using Id = LibCache::Id; 43 using TypeId = panda_file::Type::TypeId; 44 45 // TODO(vdyadov): solve problem with cycles 46 // (todo: mutual recursive types) 47 ClassNameOfId(Id id)48 const PandaString &ClassNameOfId(Id id) 49 { 50 return ClassNameOfId_[id]; 51 } 52 MethodNameOfId(Id id)53 const PandaString &MethodNameOfId(Id id) 54 { 55 return MethodNameOfId_[id]; 56 } 57 58 Type NormalizedTypeOf(Type type); 59 TypeParams NormalizeMethodSignature(const TypeParams &sig); 60 61 const TypeParams &MethodSignature(const CachedMethod &method); 62 const TypeParams &NormalizedMethodSignature(const CachedMethod &method); 63 64 TypeId TypeIdOf(const Type &type) const; 65 66 Type TypeOf(const CachedMethod &method); 67 Type TypeOf(const CachedClass &klass); 68 Type TypeOf(TypeId id) const; 69 TypeOf(const TypeParamIdx & idx)70 Type TypeOf(const TypeParamIdx &idx) const 71 { 72 return {TypeSystemKind::JAVA, threadnum_, idx}; 73 } 74 CloseAccumulatedSubtypingRelation()75 void CloseAccumulatedSubtypingRelation() 76 { 77 TypeSystem_.CloseAccumulatedSubtypingRelation(); 78 }; 79 GetSort(const PandaString & name)80 SortIdx GetSort(const PandaString &name) const 81 { 82 return TypeSystems::GetSort(TypeSystemKind::JAVA, threadnum_, name); 83 } 84 GetKind()85 TypeSystemKind GetKind() const 86 { 87 return TypeSystemKind::JAVA; 88 } 89 GetThreadNum()90 ThreadNum GetThreadNum() const 91 { 92 return threadnum_; 93 } 94 95 explicit PandaTypes(ThreadNum threadnum); 96 NO_COPY_SEMANTIC(PandaTypes); 97 98 ~PandaTypes() = default; Bot()99 Type Bot() const 100 { 101 return TypeSystem_.Bot(); 102 } Top()103 Type Top() const 104 { 105 return TypeSystem_.Top(); 106 } Array()107 const ParametricType &Array() 108 { 109 return Array_; 110 } Method()111 const ParametricType &Method() 112 { 113 return Method_; 114 } NormalizedMethod()115 const ParametricType &NormalizedMethod() 116 { 117 return NormalizedMethod_; 118 } Normalize()119 const ParametricType &Normalize() 120 { 121 return Normalize_; 122 } Abstract()123 const ParametricType &Abstract() 124 { 125 return Abstract_; 126 } Interface()127 const ParametricType &Interface() 128 { 129 return Interface_; 130 } TypeClass()131 const ParametricType &TypeClass() 132 { 133 return TypeClass_; 134 } 135 U1()136 const Type &U1() const 137 { 138 return U1_; 139 } I8()140 const Type &I8() const 141 { 142 return I8_; 143 } U8()144 const Type &U8() const 145 { 146 return U8_; 147 } I16()148 const Type &I16() const 149 { 150 return I16_; 151 } U16()152 const Type &U16() const 153 { 154 return U16_; 155 } I32()156 const Type &I32() const 157 { 158 return I32_; 159 } U32()160 const Type &U32() const 161 { 162 return U32_; 163 } I64()164 const Type &I64() const 165 { 166 return I64_; 167 } U64()168 const Type &U64() const 169 { 170 return U64_; 171 } F32()172 const Type &F32() const 173 { 174 return F32_; 175 } F64()176 const Type &F64() const 177 { 178 return F64_; 179 } 180 RefType()181 const Type &RefType() const 182 { 183 return RefType_; 184 } ObjectType()185 const Type &ObjectType() const 186 { 187 return ObjectType_; 188 } StringType()189 const Type &StringType() const 190 { 191 return StringType_; 192 } PrimitiveType()193 const Type &PrimitiveType() const 194 { 195 return PrimitiveType_; 196 } AbstractType()197 const Type &AbstractType() const 198 { 199 return AbstractType_; 200 } InterfaceType()201 const Type &InterfaceType() const 202 { 203 return InterfaceType_; 204 } TypeClassType()205 const Type &TypeClassType() const 206 { 207 return TypeClassType_; 208 } InstantiableType()209 const Type &InstantiableType() const 210 { 211 return InstantiableType_; 212 } ArrayType()213 const Type &ArrayType() const 214 { 215 return ArrayType_; 216 } ObjectArrayType()217 const Type &ObjectArrayType() const 218 { 219 return ObjectArrayType_; 220 } MethodType()221 const Type &MethodType() const 222 { 223 return MethodType_; 224 } StaticMethodType()225 const Type &StaticMethodType() const 226 { 227 return StaticMethodType_; 228 } NonStaticMethodType()229 const Type &NonStaticMethodType() const 230 { 231 return NonStaticMethodType_; 232 } VirtualMethodType()233 const Type &VirtualMethodType() const 234 { 235 return VirtualMethodType_; 236 } NullRefType()237 const Type &NullRefType() const 238 { 239 return NullRefType_; 240 } Bits32Type()241 const Type &Bits32Type() const 242 { 243 return Bits32Type_; 244 } Bits64Type()245 const Type &Bits64Type() const 246 { 247 return Bits64Type_; 248 } Integral8Type()249 const Type &Integral8Type() const 250 { 251 return Integral8Type_; 252 } Integral16Type()253 const Type &Integral16Type() const 254 { 255 return Integral16Type_; 256 } Integral32Type()257 const Type &Integral32Type() const 258 { 259 return Integral32Type_; 260 } Integral64Type()261 const Type &Integral64Type() const 262 { 263 return Integral64Type_; 264 } Float32Type()265 const Type &Float32Type() const 266 { 267 return Float32Type_; 268 } Float64Type()269 const Type &Float64Type() const 270 { 271 return Float64Type_; 272 } Object(panda::panda_file::SourceLang lang)273 const Type &Object(panda::panda_file::SourceLang lang) const 274 { 275 return LangContextTypesObjects_.at(lang); 276 } Class(panda::panda_file::SourceLang lang)277 const Type &Class(panda::panda_file::SourceLang lang) const 278 { 279 return LangContextTypesClass_.at(lang); 280 } Throwable(panda::panda_file::SourceLang lang)281 const Type &Throwable(panda::panda_file::SourceLang lang) const 282 { 283 return LangContextTypesThrowables_.at(lang); 284 } 285 ImageOf(const Type & type)286 const PandaString &ImageOf(const Type &type) 287 { 288 return TypeSystems::ImageOfType(type); 289 } ImageOf(const TypeParams & params)290 PandaString ImageOf(const TypeParams ¶ms) 291 { 292 return TypeSystems::ImageOfTypeParams(params); 293 } 294 template <typename Handler> ForSubtypesOf(const Type & type,Handler && handler)295 void ForSubtypesOf(const Type &type, Handler &&handler) const 296 { 297 type.ForAllSubtypes(std::forward<Handler>(handler)); 298 } 299 template <typename Handler> ForSupertypesOf(const Type & type,Handler && handler)300 void ForSupertypesOf(const Type &type, Handler &&handler) const 301 { 302 type.ForAllSupertypes(std::forward<Handler>(handler)); 303 } SubtypesOf(const Type & type)304 PandaVector<Type> SubtypesOf(const Type &type) const 305 { 306 PandaVector<Type> result; 307 type.ForAllSubtypes([&result](const auto &t) { 308 result.push_back(t); 309 return true; 310 }); 311 return result; 312 } SupertypesOf(const Type & type)313 PandaVector<Type> SupertypesOf(const Type &type) const 314 { 315 PandaVector<Type> result; 316 type.ForAllSupertypes([&result](const auto &t) { 317 result.push_back(t); 318 return true; 319 }); 320 return result; 321 } 322 template <typename Handler> DisplayMethods(Handler handler)323 void DisplayMethods(Handler handler) 324 { 325 if (DoNotCalculateMethodType_) { 326 for (const auto &item : SigOfMethod_) { 327 handler(MethodNameOfId(item.first), ImageOf(item.second)); 328 } 329 } else { 330 for (const auto &item : TypeOfMethod_) { 331 handler(MethodNameOfId(item.first), ImageOf(item.second)); 332 } 333 } 334 } 335 template <typename Handler> DisplayClasses(Handler handler)336 void DisplayClasses(Handler handler) 337 { 338 for (const auto &item : TypeOfClass_) { 339 handler(ClassNameOfId(item.first), ImageOf(item.second)); 340 } 341 } 342 template <typename Handler> DisplaySubtyping(Handler handler)343 void DisplaySubtyping(Handler handler) 344 { 345 TypeSystem_.ForAllTypes([this, &handler](const Type &type) { 346 type.ForAllSupertypes([this, &handler, &type](const Type &supertype) { 347 handler(ImageOf(type), ImageOf(supertype)); 348 return true; 349 }); 350 return true; 351 }); 352 } 353 template <typename Handler> DisplayTypeSystem(Handler handler)354 void DisplayTypeSystem(Handler handler) 355 { 356 handler(PandaString {"Classes:"}); 357 DisplayClasses([&handler](const auto &name, const auto &type) { handler(name + " : " + type); }); 358 handler(PandaString {"Methods:"}); 359 DisplayMethods([&handler](const auto &name, const auto &type) { handler(name + " : " + type); }); 360 handler(PandaString {"Subtyping (type <: supertype):"}); 361 DisplaySubtyping([&handler](const auto &type, const auto &supertype) { handler(type + " <: " + supertype); }); 362 } 363 DoNotCalculateMethodType()364 bool DoNotCalculateMethodType() const 365 { 366 return DoNotCalculateMethodType_; 367 } 368 NewVar()369 Variables::Var NewVar() 370 { 371 return Variables_.NewVar(); 372 } 373 374 private: 375 ThreadNum threadnum_; 376 PandaUnorderedMap<Id, Type> TypeOfClass_; 377 PandaUnorderedMap<Id, Type> TypeOfMethod_; 378 PandaUnorderedMap<Id, TypeParams> SigOfMethod_; 379 PandaUnorderedMap<Id, TypeParams> NormalizedSigOfMethod_; 380 PandaUnorderedMap<Id, PandaString> ClassNameOfId_; 381 PandaUnorderedMap<Id, PandaString> MethodNameOfId_; 382 PandaUnorderedMap<Type, Type> NormalizedTypeOf_; 383 TypeSystem &TypeSystem_; 384 Variables Variables_; 385 386 // base sorts 387 const ParametricType Array_; 388 const ParametricType Method_; 389 const ParametricType NormalizedMethod_; 390 const ParametricType Normalize_; 391 const ParametricType Abstract_; 392 const ParametricType Interface_; 393 const ParametricType TypeClass_; 394 395 const Type U1_; 396 const Type I8_; 397 const Type U8_; 398 const Type I16_; 399 const Type U16_; 400 const Type I32_; 401 const Type U32_; 402 const Type I64_; 403 const Type U64_; 404 const Type F32_; 405 const Type F64_; 406 407 const Type RefType_; 408 const Type ObjectType_; 409 const Type StringType_; 410 const Type PrimitiveType_; 411 const Type AbstractType_; 412 const Type InterfaceType_; 413 const Type TypeClassType_; 414 const Type InstantiableType_; 415 const Type ArrayType_; 416 const Type ObjectArrayType_; 417 const Type MethodType_; 418 const Type StaticMethodType_; 419 const Type NonStaticMethodType_; 420 const Type VirtualMethodType_; 421 const Type NullRefType_; 422 const Type Bits32Type_; 423 const Type Bits64Type_; 424 const Type Integral8Type_; 425 const Type Integral16Type_; 426 const Type Integral32Type_; 427 const Type Integral64Type_; 428 const Type Float32Type_; 429 const Type Float64Type_; 430 431 std::map<panda::panda_file::SourceLang, const Type> LangContextTypesClass_; 432 std::map<panda::panda_file::SourceLang, const Type> LangContextTypesObjects_; 433 std::map<panda::panda_file::SourceLang, const Type> LangContextTypesThrowables_; 434 435 bool DoNotCalculateMethodType_ {true}; 436 437 void SetArraySubtyping(const Type &t); 438 439 Type TypeOfArray(const CachedClass &klass); 440 ParametricTypeForName(const PandaString & name)441 ParametricType ParametricTypeForName(const PandaString &name) 442 { 443 return TypeSystem_.Parametric(GetSort(name)); 444 } 445 TypeForName(const PandaString & name)446 Type TypeForName(const PandaString &name) 447 { 448 return ParametricTypeForName(name)(); 449 } 450 }; 451 } // namespace panda::verifier 452 453 #endif // !_PANDA_VERIFIER_PANDA_TYPES_HPP 454