Line data Source code
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 : #ifndef V8_TORQUE_PARAMETER_DIFFERENCE_H_
6 : #define V8_TORQUE_PARAMETER_DIFFERENCE_H_
7 :
8 : #include <vector>
9 :
10 : #include "src/torque/types.h"
11 :
12 : namespace v8 {
13 : namespace internal {
14 : namespace torque {
15 :
16 3416 : class ParameterDifference {
17 : public:
18 3416 : ParameterDifference(const TypeVector& to, const TypeVector& from) {
19 : DCHECK_EQ(to.size(), from.size());
20 16632 : for (size_t i = 0; i < to.size(); ++i) {
21 13216 : AddParameter(to[i], from[i]);
22 : }
23 3416 : }
24 :
25 : // An overload is selected if it is strictly better than all alternatives.
26 : // This means that it has to be strictly better in at least one parameter,
27 : // and better or equally good in all others.
28 : //
29 : // When comparing a pair of corresponding parameters of two overloads...
30 : // ... they are considered equally good if:
31 : // - They are equal.
32 : // - Both require some implicit conversion.
33 : // ... one is considered better if:
34 : // - It is a strict subtype of the other.
35 : // - It doesn't require an implicit conversion, while the other does.
36 1708 : bool StrictlyBetterThan(const ParameterDifference& other) const {
37 : DCHECK_EQ(difference_.size(), other.difference_.size());
38 : bool better_parameter_found = false;
39 5656 : for (size_t i = 0; i < difference_.size(); ++i) {
40 2672 : base::Optional<const Type*> a = difference_[i];
41 2672 : base::Optional<const Type*> b = other.difference_[i];
42 2672 : if (a == b) {
43 : continue;
44 3567 : } else if (a && b && a != b && (*a)->IsSubtypeOf(*b)) {
45 : DCHECK(!(*b)->IsSubtypeOf(*a));
46 : better_parameter_found = true;
47 973 : } else if (a && !b) {
48 : better_parameter_found = true;
49 : } else {
50 : return false;
51 : }
52 : }
53 : return better_parameter_found;
54 : }
55 :
56 : private:
57 : // Pointwise difference between call arguments and a signature.
58 : // {base::nullopt} means that an implicit conversion was necessary,
59 : // otherwise we store the supertype found in the signature.
60 : std::vector<base::Optional<const Type*>> difference_;
61 :
62 6608 : void AddParameter(const Type* to, const Type* from) {
63 6608 : if (from->IsSubtypeOf(to)) {
64 9538 : difference_.push_back(to);
65 1839 : } else if (IsAssignableFrom(to, from)) {
66 3678 : difference_.push_back(base::nullopt);
67 : } else {
68 0 : UNREACHABLE();
69 : }
70 6608 : }
71 : };
72 :
73 : } // namespace torque
74 : } // namespace internal
75 : } // namespace v8
76 :
77 : #endif // V8_TORQUE_PARAMETER_DIFFERENCE_H_
|