Index: src/base/bits.cc |
diff --git a/src/base/bits.cc b/src/base/bits.cc |
index 74d747fc9059f135cc2986b9b73f6ce473391534..9b949cc66f8e380a658fbb33dac8bc1e520622ec 100644 |
--- a/src/base/bits.cc |
+++ b/src/base/bits.cc |
@@ -7,6 +7,7 @@ |
#include <limits> |
#include "src/base/logging.h" |
+#include "src/base/safe_math.h" |
namespace v8 { |
namespace base { |
@@ -48,6 +49,35 @@ int32_t SignedMod32(int32_t lhs, int32_t rhs) { |
return lhs % rhs; |
} |
+ |
+int64_t FromCheckedNumeric(const internal::CheckedNumeric<int64_t> value) { |
+ if (value.IsValid()) |
+ return value.ValueUnsafe(); |
+ |
+ // We could return max/min but we don't really expose what the maximum delta |
+ // is. Instead, return max/(-max), which is something that clients can reason |
+ // about. |
+ // TODO(rvargas) crbug.com/332611: don't use internal values. |
+ int64_t limit = std::numeric_limits<int64_t>::max(); |
+ if (value.validity() == internal::RANGE_UNDERFLOW) |
+ limit = -limit; |
+ return value.ValueOrDefault(limit); |
+} |
+ |
+ |
+int64_t SignedSaturatedAdd64(int64_t lhs, int64_t rhs) { |
+ internal::CheckedNumeric<int64_t> rv(lhs); |
+ rv += rhs; |
+ return FromCheckedNumeric(rv); |
+} |
+ |
+ |
+int64_t SignedSaturatedSub64(int64_t lhs, int64_t rhs) { |
+ internal::CheckedNumeric<int64_t> rv(lhs); |
+ rv -= rhs; |
+ return FromCheckedNumeric(rv); |
+} |
+ |
} // namespace bits |
} // namespace base |
} // namespace v8 |