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