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 class ParameterDifference { 17 public: ParameterDifference(const TypeVector & to,const TypeVector & from)18 ParameterDifference(const TypeVector& to, const TypeVector& from) { 19 DCHECK_EQ(to.size(), from.size()); 20 for (size_t i = 0; i < to.size(); ++i) { 21 AddParameter(to[i], from[i]); 22 } 23 } 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. StrictlyBetterThan(const ParameterDifference & other)36 bool StrictlyBetterThan(const ParameterDifference& other) const { 37 DCHECK_EQ(difference_.size(), other.difference_.size()); 38 bool better_parameter_found = false; 39 for (size_t i = 0; i < difference_.size(); ++i) { 40 base::Optional<const Type*> a = difference_[i]; 41 base::Optional<const Type*> b = other.difference_[i]; 42 if (a == b) { 43 continue; 44 } else if (a && b && a != b && (*a)->IsSubtypeOf(*b)) { 45 DCHECK(!(*b)->IsSubtypeOf(*a)); 46 better_parameter_found = true; 47 } 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 AddParameter(const Type * to,const Type * from)62 void AddParameter(const Type* to, const Type* from) { 63 if (from->IsSubtypeOf(to)) { 64 difference_.push_back(to); 65 } else if (IsAssignableFrom(to, from)) { 66 difference_.push_back(base::nullopt); 67 } else { 68 UNREACHABLE(); 69 } 70 } 71 }; 72 73 } // namespace torque 74 } // namespace internal 75 } // namespace v8 76 77 #endif // V8_TORQUE_PARAMETER_DIFFERENCE_H_ 78