summaryrefslogtreecommitdiff
path: root/deps/v8/src/torque/parameter-difference.h
diff options
context:
space:
mode:
Diffstat (limited to 'deps/v8/src/torque/parameter-difference.h')
-rw-r--r--deps/v8/src/torque/parameter-difference.h77
1 files changed, 77 insertions, 0 deletions
diff --git a/deps/v8/src/torque/parameter-difference.h b/deps/v8/src/torque/parameter-difference.h
new file mode 100644
index 0000000000..aaa1745af2
--- /dev/null
+++ b/deps/v8/src/torque/parameter-difference.h
@@ -0,0 +1,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_