1 // Copyright 2018 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 #include "src/torque/type-oracle.h"
6 #include "src/base/optional.h"
7 #include "src/torque/type-visitor.h"
8 #include "src/torque/types.h"
9 
10 namespace v8 {
11 namespace internal {
12 namespace torque {
13 
DEFINE_CONTEXTUAL_VARIABLE(TypeOracle) const14 DEFINE_CONTEXTUAL_VARIABLE(TypeOracle)
15 
16 // static
17 const std::vector<std::unique_ptr<AggregateType>>&
18 TypeOracle::GetAggregateTypes() {
19   return Get().aggregate_types_;
20 }
21 
22 // static
23 const std::vector<std::unique_ptr<BitFieldStructType>>&
GetBitFieldStructTypes()24 TypeOracle::GetBitFieldStructTypes() {
25   return Get().bit_field_struct_types_;
26 }
27 
28 // static
FinalizeAggregateTypes()29 void TypeOracle::FinalizeAggregateTypes() {
30   size_t current = 0;
31   while (current != Get().aggregate_types_.size()) {
32     auto& p = Get().aggregate_types_[current++];
33     p->Finalize();
34   }
35 }
36 
37 // static
GetGenericTypeInstance(GenericType * generic_type,TypeVector arg_types)38 const Type* TypeOracle::GetGenericTypeInstance(GenericType* generic_type,
39                                                TypeVector arg_types) {
40   auto& params = generic_type->generic_parameters();
41 
42   if (params.size() != arg_types.size()) {
43     ReportError("Generic struct takes ", params.size(), " parameters, but ",
44                 arg_types.size(), " were given");
45   }
46 
47   if (auto specialization = generic_type->GetSpecialization(arg_types)) {
48     return *specialization;
49   } else {
50     const Type* type = nullptr;
51     // AddSpecialization can raise an error, which should be reported in the
52     // scope of the code requesting the specialization, not the generic type's
53     // parent scope, hence the following block.
54     {
55       v8::internal::torque::Scope* requester_scope = CurrentScope::Get();
56       CurrentScope::Scope generic_scope(generic_type->ParentScope());
57       type = TypeVisitor::ComputeType(generic_type->declaration(),
58                                       {{generic_type, arg_types}},
59                                       requester_scope);
60     }
61     generic_type->AddSpecialization(arg_types, type);
62     return type;
63   }
64 }
65 
66 // static
CreateGenericTypeInstantiationNamespace()67 Namespace* TypeOracle::CreateGenericTypeInstantiationNamespace() {
68   Get().generic_type_instantiation_namespaces_.push_back(
69       std::make_unique<Namespace>(GENERIC_TYPE_INSTANTIATION_NAMESPACE_STRING));
70   return Get().generic_type_instantiation_namespaces_.back().get();
71 }
72 
73 // static
GetClasses()74 std::vector<const ClassType*> TypeOracle::GetClasses() {
75   std::vector<const ClassType*> result;
76   for (const std::unique_ptr<AggregateType>& t : Get().aggregate_types_) {
77     if (auto* class_type = ClassType::DynamicCast(t.get())) {
78       result.push_back(class_type);
79     }
80   }
81   return result;
82 }
83 
MatchReferenceGeneric(const Type * reference_type,bool * is_const)84 base::Optional<const Type*> TypeOracle::MatchReferenceGeneric(
85     const Type* reference_type, bool* is_const) {
86   if (auto type = Type::MatchUnaryGeneric(reference_type,
87                                           GetMutableReferenceGeneric())) {
88     if (is_const) *is_const = false;
89     return type;
90   }
91   if (auto type =
92           Type::MatchUnaryGeneric(reference_type, GetConstReferenceGeneric())) {
93     if (is_const) *is_const = true;
94     return type;
95   }
96   return base::nullopt;
97 }
98 
99 }  // namespace torque
100 }  // namespace internal
101 }  // namespace v8
102