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