summaryrefslogtreecommitdiff
path: root/deps/v8/src/conversions-inl.h
diff options
context:
space:
mode:
Diffstat (limited to 'deps/v8/src/conversions-inl.h')
-rw-r--r--deps/v8/src/conversions-inl.h27
1 files changed, 16 insertions, 11 deletions
diff --git a/deps/v8/src/conversions-inl.h b/deps/v8/src/conversions-inl.h
index f2a6be4227..3bdb2efcb4 100644
--- a/deps/v8/src/conversions-inl.h
+++ b/deps/v8/src/conversions-inl.h
@@ -19,6 +19,7 @@
#include "src/conversions.h"
#include "src/double.h"
#include "src/objects-inl.h"
+#include "src/objects/heap-number-inl.h"
namespace v8 {
namespace internal {
@@ -71,7 +72,7 @@ inline double DoubleToInteger(double x) {
return (x >= 0) ? std::floor(x) : std::ceil(x);
}
-
+// Implements most of https://tc39.github.io/ecma262/#sec-toint32.
int32_t DoubleToInt32(double x) {
if ((std::isfinite(x)) && (x <= INT_MAX) && (x >= INT_MIN)) {
int32_t i = static_cast<int32_t>(x);
@@ -79,13 +80,18 @@ int32_t DoubleToInt32(double x) {
}
Double d(x);
int exponent = d.Exponent();
+ uint64_t bits;
if (exponent < 0) {
if (exponent <= -Double::kSignificandSize) return 0;
- return d.Sign() * static_cast<int32_t>(d.Significand() >> -exponent);
+ bits = d.Significand() >> -exponent;
} else {
if (exponent > 31) return 0;
- return d.Sign() * static_cast<int32_t>(d.Significand() << exponent);
+ // Masking to a 32-bit value ensures that the result of the
+ // static_cast<int64_t> below is not the minimal int64_t value,
+ // which would overflow on multiplication with d.Sign().
+ bits = (d.Significand() << exponent) & 0xFFFFFFFFul;
}
+ return static_cast<int32_t>(d.Sign() * static_cast<int64_t>(bits));
}
bool DoubleToSmiInteger(double value, int* smi_int_value) {
@@ -142,17 +148,17 @@ bool DoubleToUint32IfEqualToSelf(double value, uint32_t* uint32_value) {
return false;
}
-int32_t NumberToInt32(Object* number) {
+int32_t NumberToInt32(Object number) {
if (number->IsSmi()) return Smi::ToInt(number);
return DoubleToInt32(number->Number());
}
-uint32_t NumberToUint32(Object* number) {
+uint32_t NumberToUint32(Object number) {
if (number->IsSmi()) return Smi::ToInt(number);
return DoubleToUint32(number->Number());
}
-uint32_t PositiveNumberToUint32(Object* number) {
+uint32_t PositiveNumberToUint32(Object number) {
if (number->IsSmi()) {
int value = Smi::ToInt(number);
if (value <= 0) return 0;
@@ -167,7 +173,7 @@ uint32_t PositiveNumberToUint32(Object* number) {
return max;
}
-int64_t NumberToInt64(Object* number) {
+int64_t NumberToInt64(Object number) {
if (number->IsSmi()) return Smi::ToInt(number);
double d = number->Number();
if (std::isnan(d)) return 0;
@@ -180,7 +186,7 @@ int64_t NumberToInt64(Object* number) {
return static_cast<int64_t>(d);
}
-uint64_t PositiveNumberToUint64(Object* number) {
+uint64_t PositiveNumberToUint64(Object number) {
if (number->IsSmi()) {
int value = Smi::ToInt(number);
if (value <= 0) return 0;
@@ -195,7 +201,7 @@ uint64_t PositiveNumberToUint64(Object* number) {
return max;
}
-bool TryNumberToSize(Object* number, size_t* result) {
+bool TryNumberToSize(Object number, size_t* result) {
// Do not create handles in this function! Don't use SealHandleScope because
// the function can be used concurrently.
if (number->IsSmi()) {
@@ -224,14 +230,13 @@ bool TryNumberToSize(Object* number, size_t* result) {
}
}
-size_t NumberToSize(Object* number) {
+size_t NumberToSize(Object number) {
size_t result = 0;
bool is_valid = TryNumberToSize(number, &result);
CHECK(is_valid);
return result;
}
-
uint32_t DoubleToUint32(double x) {
return static_cast<uint32_t>(DoubleToInt32(x));
}