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