1 // Copyright 2017 the V8 project authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 
5 #ifndef V8_TORQUE_TYPE_ORACLE_H_
6 #define V8_TORQUE_TYPE_ORACLE_H_
7 
8 #include <memory>
9 
10 #include "src/torque/contextual.h"
11 #include "src/torque/declarable.h"
12 #include "src/torque/declarations.h"
13 #include "src/torque/types.h"
14 #include "src/torque/utils.h"
15 
16 namespace v8 {
17 namespace internal {
18 namespace torque {
19 
20 class TypeOracle : public ContextualClass<TypeOracle> {
21  public:
GetAbstractType(const Type * parent,std::string name,AbstractTypeFlags flags,std::string generated,const Type * non_constexpr_version,MaybeSpecializationKey specialized_from)22   static const AbstractType* GetAbstractType(
23       const Type* parent, std::string name, AbstractTypeFlags flags,
24       std::string generated, const Type* non_constexpr_version,
25       MaybeSpecializationKey specialized_from) {
26     auto ptr = std::unique_ptr<AbstractType>(
27         new AbstractType(parent, flags, std::move(name), std::move(generated),
28                          non_constexpr_version, specialized_from));
29     const AbstractType* result = ptr.get();
30     if (non_constexpr_version) {
31       DCHECK(ptr->IsConstexpr());
32       non_constexpr_version->SetConstexprVersion(result);
33     }
34     Get().nominal_types_.push_back(std::move(ptr));
35     return result;
36   }
37 
GetStructType(const StructDeclaration * decl,MaybeSpecializationKey specialized_from)38   static StructType* GetStructType(const StructDeclaration* decl,
39                                    MaybeSpecializationKey specialized_from) {
40     auto ptr = std::unique_ptr<StructType>(
41         new StructType(CurrentNamespace(), decl, specialized_from));
42     StructType* result = ptr.get();
43     Get().aggregate_types_.push_back(std::move(ptr));
44     return result;
45   }
46 
GetBitFieldStructType(const Type * parent,const BitFieldStructDeclaration * decl)47   static BitFieldStructType* GetBitFieldStructType(
48       const Type* parent, const BitFieldStructDeclaration* decl) {
49     auto ptr = std::unique_ptr<BitFieldStructType>(
50         new BitFieldStructType(CurrentNamespace(), parent, decl));
51     BitFieldStructType* result = ptr.get();
52     Get().bit_field_struct_types_.push_back(std::move(ptr));
53     return result;
54   }
55 
GetClassType(const Type * parent,const std::string & name,ClassFlags flags,const std::string & generates,ClassDeclaration * decl,const TypeAlias * alias)56   static ClassType* GetClassType(const Type* parent, const std::string& name,
57                                  ClassFlags flags, const std::string& generates,
58                                  ClassDeclaration* decl,
59                                  const TypeAlias* alias) {
60     std::unique_ptr<ClassType> type(new ClassType(
61         parent, CurrentNamespace(), name, flags, generates, decl, alias));
62     ClassType* result = type.get();
63     Get().aggregate_types_.push_back(std::move(type));
64     return result;
65   }
66 
GetBuiltinPointerType(TypeVector argument_types,const Type * return_type)67   static const BuiltinPointerType* GetBuiltinPointerType(
68       TypeVector argument_types, const Type* return_type) {
69     TypeOracle& self = Get();
70     const Type* builtin_type = self.GetBuiltinType(BUILTIN_POINTER_TYPE_STRING);
71     const BuiltinPointerType* result = self.function_pointer_types_.Add(
72         BuiltinPointerType(builtin_type, argument_types, return_type,
73                            self.all_builtin_pointer_types_.size()));
74     if (result->function_pointer_type_id() ==
75         self.all_builtin_pointer_types_.size()) {
76       self.all_builtin_pointer_types_.push_back(result);
77     }
78     return result;
79   }
80 
81   static const Type* GetGenericTypeInstance(GenericType* generic_type,
82                                             TypeVector arg_types);
83 
GetReferenceGeneric(bool is_const)84   static GenericType* GetReferenceGeneric(bool is_const) {
85     return Declarations::LookupUniqueGenericType(
86         QualifiedName({TORQUE_INTERNAL_NAMESPACE_STRING},
87                       is_const ? CONST_REFERENCE_TYPE_STRING
88                                : MUTABLE_REFERENCE_TYPE_STRING));
89   }
GetConstReferenceGeneric()90   static GenericType* GetConstReferenceGeneric() {
91     return GetReferenceGeneric(true);
92   }
GetMutableReferenceGeneric()93   static GenericType* GetMutableReferenceGeneric() {
94     return GetReferenceGeneric(false);
95   }
96 
97   static base::Optional<const Type*> MatchReferenceGeneric(
98       const Type* reference_type, bool* is_const = nullptr);
99 
GetMutableSliceGeneric()100   static GenericType* GetMutableSliceGeneric() {
101     return Declarations::LookupUniqueGenericType(
102         QualifiedName(MUTABLE_SLICE_TYPE_STRING));
103   }
GetConstSliceGeneric()104   static GenericType* GetConstSliceGeneric() {
105     return Declarations::LookupUniqueGenericType(
106         QualifiedName(CONST_SLICE_TYPE_STRING));
107   }
108 
GetWeakGeneric()109   static GenericType* GetWeakGeneric() {
110     return Declarations::LookupGlobalUniqueGenericType(WEAK_TYPE_STRING);
111   }
112 
GetSmiTaggedGeneric()113   static GenericType* GetSmiTaggedGeneric() {
114     return Declarations::LookupGlobalUniqueGenericType(SMI_TAGGED_TYPE_STRING);
115   }
116 
GetLazyGeneric()117   static GenericType* GetLazyGeneric() {
118     return Declarations::LookupGlobalUniqueGenericType(LAZY_TYPE_STRING);
119   }
120 
GetReferenceType(const Type * referenced_type,bool is_const)121   static const Type* GetReferenceType(const Type* referenced_type,
122                                       bool is_const) {
123     return GetGenericTypeInstance(GetReferenceGeneric(is_const),
124                                   {referenced_type});
125   }
GetConstReferenceType(const Type * referenced_type)126   static const Type* GetConstReferenceType(const Type* referenced_type) {
127     return GetReferenceType(referenced_type, true);
128   }
GetMutableReferenceType(const Type * referenced_type)129   static const Type* GetMutableReferenceType(const Type* referenced_type) {
130     return GetReferenceType(referenced_type, false);
131   }
132 
GetMutableSliceType(const Type * referenced_type)133   static const Type* GetMutableSliceType(const Type* referenced_type) {
134     return GetGenericTypeInstance(GetMutableSliceGeneric(), {referenced_type});
135   }
GetConstSliceType(const Type * referenced_type)136   static const Type* GetConstSliceType(const Type* referenced_type) {
137     return GetGenericTypeInstance(GetConstSliceGeneric(), {referenced_type});
138   }
139 
140   static const std::vector<const BuiltinPointerType*>&
AllBuiltinPointerTypes()141   AllBuiltinPointerTypes() {
142     return Get().all_builtin_pointer_types_;
143   }
144 
GetUnionType(UnionType type)145   static const Type* GetUnionType(UnionType type) {
146     if (base::Optional<const Type*> single = type.GetSingleMember()) {
147       return *single;
148     }
149     return Get().union_types_.Add(std::move(type));
150   }
151 
GetUnionType(const Type * a,const Type * b)152   static const Type* GetUnionType(const Type* a, const Type* b) {
153     if (a->IsSubtypeOf(b)) return b;
154     if (b->IsSubtypeOf(a)) return a;
155     UnionType result = UnionType::FromType(a);
156     result.Extend(b);
157     return GetUnionType(std::move(result));
158   }
159 
GetTopType(std::string reason,const Type * source_type)160   static const TopType* GetTopType(std::string reason,
161                                    const Type* source_type) {
162     std::unique_ptr<TopType> type(new TopType(std::move(reason), source_type));
163     TopType* result = type.get();
164     Get().top_types_.push_back(std::move(type));
165     return result;
166   }
167 
GetArgumentsType()168   static const Type* GetArgumentsType() {
169     return Get().GetBuiltinType(ARGUMENTS_TYPE_STRING);
170   }
171 
GetBoolType()172   static const Type* GetBoolType() {
173     return Get().GetBuiltinType(BOOL_TYPE_STRING);
174   }
175 
GetConstexprBoolType()176   static const Type* GetConstexprBoolType() {
177     return Get().GetBuiltinType(CONSTEXPR_BOOL_TYPE_STRING);
178   }
179 
GetConstexprStringType()180   static const Type* GetConstexprStringType() {
181     return Get().GetBuiltinType(CONSTEXPR_STRING_TYPE_STRING);
182   }
183 
GetConstexprIntPtrType()184   static const Type* GetConstexprIntPtrType() {
185     return Get().GetBuiltinType(CONSTEXPR_INTPTR_TYPE_STRING);
186   }
187 
GetConstexprInstanceTypeType()188   static const Type* GetConstexprInstanceTypeType() {
189     return Get().GetBuiltinType(CONSTEXPR_INSTANCE_TYPE_TYPE_STRING);
190   }
191 
GetVoidType()192   static const Type* GetVoidType() {
193     return Get().GetBuiltinType(VOID_TYPE_STRING);
194   }
195 
GetRawPtrType()196   static const Type* GetRawPtrType() {
197     return Get().GetBuiltinType(RAWPTR_TYPE_STRING);
198   }
199 
GetExternalPointerType()200   static const Type* GetExternalPointerType() {
201     return Get().GetBuiltinType(EXTERNALPTR_TYPE_STRING);
202   }
203 
GetMapType()204   static const Type* GetMapType() {
205     return Get().GetBuiltinType(MAP_TYPE_STRING);
206   }
207 
GetObjectType()208   static const Type* GetObjectType() {
209     return Get().GetBuiltinType(OBJECT_TYPE_STRING);
210   }
211 
GetHeapObjectType()212   static const Type* GetHeapObjectType() {
213     return Get().GetBuiltinType(HEAP_OBJECT_TYPE_STRING);
214   }
215 
GetTaggedZeroPatternType()216   static const Type* GetTaggedZeroPatternType() {
217     return Get().GetBuiltinType(TAGGED_ZERO_PATTERN_TYPE_STRING);
218   }
219 
GetJSAnyType()220   static const Type* GetJSAnyType() {
221     return Get().GetBuiltinType(JSANY_TYPE_STRING);
222   }
223 
GetJSObjectType()224   static const Type* GetJSObjectType() {
225     return Get().GetBuiltinType(JSOBJECT_TYPE_STRING);
226   }
227 
GetTaggedType()228   static const Type* GetTaggedType() {
229     return Get().GetBuiltinType(TAGGED_TYPE_STRING);
230   }
231 
GetStrongTaggedType()232   static const Type* GetStrongTaggedType() {
233     return Get().GetBuiltinType(STRONG_TAGGED_TYPE_STRING);
234   }
235 
GetUninitializedType()236   static const Type* GetUninitializedType() {
237     return Get().GetBuiltinType(UNINITIALIZED_TYPE_STRING);
238   }
239 
GetUninitializedHeapObjectType()240   static const Type* GetUninitializedHeapObjectType() {
241     return Get().GetBuiltinType(
242         QualifiedName({TORQUE_INTERNAL_NAMESPACE_STRING},
243                       UNINITIALIZED_HEAP_OBJECT_TYPE_STRING));
244   }
245 
GetSmiType()246   static const Type* GetSmiType() {
247     return Get().GetBuiltinType(SMI_TYPE_STRING);
248   }
249 
GetConstStringType()250   static const Type* GetConstStringType() {
251     return Get().GetBuiltinType(CONST_STRING_TYPE_STRING);
252   }
253 
GetStringType()254   static const Type* GetStringType() {
255     return Get().GetBuiltinType(STRING_TYPE_STRING);
256   }
257 
GetNumberType()258   static const Type* GetNumberType() {
259     return Get().GetBuiltinType(NUMBER_TYPE_STRING);
260   }
261 
GetIntPtrType()262   static const Type* GetIntPtrType() {
263     return Get().GetBuiltinType(INTPTR_TYPE_STRING);
264   }
265 
GetUIntPtrType()266   static const Type* GetUIntPtrType() {
267     return Get().GetBuiltinType(UINTPTR_TYPE_STRING);
268   }
269 
GetInt64Type()270   static const Type* GetInt64Type() {
271     return Get().GetBuiltinType(INT64_TYPE_STRING);
272   }
273 
GetUint64Type()274   static const Type* GetUint64Type() {
275     return Get().GetBuiltinType(UINT64_TYPE_STRING);
276   }
277 
GetInt32Type()278   static const Type* GetInt32Type() {
279     return Get().GetBuiltinType(INT32_TYPE_STRING);
280   }
281 
GetUint32Type()282   static const Type* GetUint32Type() {
283     return Get().GetBuiltinType(UINT32_TYPE_STRING);
284   }
285 
GetUint31Type()286   static const Type* GetUint31Type() {
287     return Get().GetBuiltinType(UINT31_TYPE_STRING);
288   }
289 
GetInt16Type()290   static const Type* GetInt16Type() {
291     return Get().GetBuiltinType(INT16_TYPE_STRING);
292   }
293 
GetUint16Type()294   static const Type* GetUint16Type() {
295     return Get().GetBuiltinType(UINT16_TYPE_STRING);
296   }
297 
GetInt8Type()298   static const Type* GetInt8Type() {
299     return Get().GetBuiltinType(INT8_TYPE_STRING);
300   }
301 
GetUint8Type()302   static const Type* GetUint8Type() {
303     return Get().GetBuiltinType(UINT8_TYPE_STRING);
304   }
305 
GetFloat64Type()306   static const Type* GetFloat64Type() {
307     return Get().GetBuiltinType(FLOAT64_TYPE_STRING);
308   }
309 
GetFloat64OrHoleType()310   static const Type* GetFloat64OrHoleType() {
311     return Get().GetBuiltinType(FLOAT64_OR_HOLE_TYPE_STRING);
312   }
313 
GetConstFloat64Type()314   static const Type* GetConstFloat64Type() {
315     return Get().GetBuiltinType(CONST_FLOAT64_TYPE_STRING);
316   }
317 
GetNeverType()318   static const Type* GetNeverType() {
319     return Get().GetBuiltinType(NEVER_TYPE_STRING);
320   }
321 
GetConstInt31Type()322   static const Type* GetConstInt31Type() {
323     return Get().GetBuiltinType(CONST_INT31_TYPE_STRING);
324   }
325 
GetConstInt32Type()326   static const Type* GetConstInt32Type() {
327     return Get().GetBuiltinType(CONST_INT32_TYPE_STRING);
328   }
329 
GetContextType()330   static const Type* GetContextType() {
331     return Get().GetBuiltinType(CONTEXT_TYPE_STRING);
332   }
333 
GetNoContextType()334   static const Type* GetNoContextType() {
335     return Get().GetBuiltinType(NO_CONTEXT_TYPE_STRING);
336   }
337 
GetNativeContextType()338   static const Type* GetNativeContextType() {
339     return Get().GetBuiltinType(NATIVE_CONTEXT_TYPE_STRING);
340   }
341 
GetJSFunctionType()342   static const Type* GetJSFunctionType() {
343     return Get().GetBuiltinType(JS_FUNCTION_TYPE_STRING);
344   }
345 
GetUninitializedIteratorType()346   static const Type* GetUninitializedIteratorType() {
347     return Get().GetBuiltinType(UNINITIALIZED_ITERATOR_TYPE_STRING);
348   }
349 
GetFixedArrayBaseType()350   static const Type* GetFixedArrayBaseType() {
351     return Get().GetBuiltinType(FIXED_ARRAY_BASE_TYPE_STRING);
352   }
353 
ImplicitlyConvertableFrom(const Type * to,const Type * from)354   static base::Optional<const Type*> ImplicitlyConvertableFrom(
355       const Type* to, const Type* from) {
356     while (from != nullptr) {
357       for (GenericCallable* from_constexpr :
358            Declarations::LookupGeneric(kFromConstexprMacroName)) {
359         if (base::Optional<const Callable*> specialization =
360                 from_constexpr->GetSpecialization({to, from})) {
361           if ((*specialization)->signature().GetExplicitTypes() ==
362               TypeVector{from}) {
363             return from;
364           }
365         }
366       }
367       from = from->parent();
368     }
369     return base::nullopt;
370   }
371 
372   static const std::vector<std::unique_ptr<AggregateType>>& GetAggregateTypes();
373   static const std::vector<std::unique_ptr<BitFieldStructType>>&
374   GetBitFieldStructTypes();
375 
376   // By construction, this list of all classes is topologically sorted w.r.t.
377   // inheritance.
378   static std::vector<const ClassType*> GetClasses();
379 
380   static void FinalizeAggregateTypes();
381 
FreshTypeId()382   static size_t FreshTypeId() { return Get().next_type_id_++; }
383 
384   static Namespace* CreateGenericTypeInstantiationNamespace();
385 
386  private:
GetBuiltinType(const QualifiedName & name)387   const Type* GetBuiltinType(const QualifiedName& name) {
388     return Declarations::LookupGlobalType(name);
389   }
GetBuiltinType(const std::string & name)390   const Type* GetBuiltinType(const std::string& name) {
391     return GetBuiltinType(QualifiedName(name));
392   }
393 
394   Deduplicator<BuiltinPointerType> function_pointer_types_;
395   std::vector<const BuiltinPointerType*> all_builtin_pointer_types_;
396   Deduplicator<UnionType> union_types_;
397   std::vector<std::unique_ptr<Type>> nominal_types_;
398   std::vector<std::unique_ptr<AggregateType>> aggregate_types_;
399   std::vector<std::unique_ptr<BitFieldStructType>> bit_field_struct_types_;
400   std::vector<std::unique_ptr<Type>> top_types_;
401   std::vector<std::unique_ptr<Namespace>>
402       generic_type_instantiation_namespaces_;
403   size_t next_type_id_ = 0;
404 };
405 
406 }  // namespace torque
407 }  // namespace internal
408 }  // namespace v8
409 
410 #endif  // V8_TORQUE_TYPE_ORACLE_H_
411