• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 &params)
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