5 #ifndef V8_CONVERSIONS_INL_H_ 6 #define V8_CONVERSIONS_INL_H_ 12 #include "src/globals.h" 17 #include "src/base/bits.h" 18 #include "src/base/platform/platform.h" 19 #include "src/conversions.h" 20 #include "src/double.h" 21 #include "src/objects-inl.h" 29 inline unsigned int FastD2UI(
double x) {
37 const double k2Pow52 = 4503599627370496.0;
38 bool negative = x < 0;
45 #ifndef V8_TARGET_BIG_ENDIAN 46 void* mantissa_ptr =
reinterpret_cast<void*
>(&x);
49 reinterpret_cast<void*
>(
reinterpret_cast<Address
>(&x) + kInt32Size);
52 memcpy(&result, mantissa_ptr,
sizeof(result));
53 return negative ? ~result + 1 : result;
60 inline float DoubleToFloat32(
double x) {
63 volatile float f =
static_cast<float>(x);
68 inline double DoubleToInteger(
double x) {
69 if (std::isnan(x))
return 0;
70 if (!std::isfinite(x) || x == 0)
return x;
71 return (x >= 0) ? std::floor(x) :
std::ceil(x);
75 int32_t DoubleToInt32(
double x) {
76 if ((std::isfinite(x)) && (x <= INT_MAX) && (x >= INT_MIN)) {
77 int32_t
i =
static_cast<int32_t
>(x);
78 if (FastI2D(
i) == x)
return i;
81 int exponent = d.Exponent();
83 if (exponent <= -Double::kSignificandSize)
return 0;
84 return d.Sign() *
static_cast<int32_t
>(d.Significand() >> -exponent);
86 if (exponent > 31)
return 0;
87 return d.Sign() *
static_cast<int32_t
>(d.Significand() << exponent);
91 bool DoubleToSmiInteger(
double value,
int* smi_int_value) {
92 if (!IsSmiDouble(value))
return false;
93 *smi_int_value = FastD2I(value);
94 DCHECK(Smi::IsValid(*smi_int_value));
98 bool IsSmiDouble(
double value) {
99 return value >= Smi::kMinValue && value <= Smi::kMaxValue &&
100 !IsMinusZero(value) && value == FastI2D(FastD2I(value));
104 bool IsInt32Double(
double value) {
105 return value >= kMinInt && value <= kMaxInt && !IsMinusZero(value) &&
106 value == FastI2D(FastD2I(value));
110 bool IsUint32Double(
double value) {
111 return !IsMinusZero(value) && value >= 0 && value <= kMaxUInt32 &&
112 value == FastUI2D(FastD2UI(value));
115 bool DoubleToUint32IfEqualToSelf(
double value,
uint32_t* uint32_value) {
116 const double k2Pow52 = 4503599627370496.0;
117 const uint32_t kValidTopBits = 0x43300000;
118 const uint64_t kBottomBitMask = V8_2PART_UINT64_C(0x00000000, FFFFFFFF);
123 double shifted_value = value + k2Pow52;
137 uint64_t result = bit_cast<uint64_t>(shifted_value);
138 if ((result >> 32) == kValidTopBits) {
139 *uint32_value = result & kBottomBitMask;
140 return FastUI2D(result & kBottomBitMask) == value;
145 int32_t NumberToInt32(Object* number) {
146 if (number->IsSmi())
return Smi::ToInt(number);
147 return DoubleToInt32(number->Number());
150 uint32_t NumberToUint32(Object* number) {
151 if (number->IsSmi())
return Smi::ToInt(number);
152 return DoubleToUint32(number->Number());
155 uint32_t PositiveNumberToUint32(Object* number) {
156 if (number->IsSmi()) {
157 int value = Smi::ToInt(number);
158 if (value <= 0)
return 0;
161 DCHECK(number->IsHeapNumber());
162 double value = number->Number();
164 if (!(value >= 1))
return 0;
165 uint32_t max = std::numeric_limits<uint32_t>::max();
166 if (value < max)
return static_cast<uint32_t>(value);
170 int64_t NumberToInt64(Object* number) {
171 if (number->IsSmi())
return Smi::ToInt(number);
172 double d = number->Number();
173 if (std::isnan(d))
return 0;
174 if (d >= static_cast<double>(std::numeric_limits<int64_t>::max())) {
175 return std::numeric_limits<int64_t>::max();
177 if (d <= static_cast<double>(std::numeric_limits<int64_t>::min())) {
178 return std::numeric_limits<int64_t>::min();
180 return static_cast<int64_t>(d);
183 uint64_t PositiveNumberToUint64(Object* number) {
184 if (number->IsSmi()) {
185 int value = Smi::ToInt(number);
186 if (value <= 0)
return 0;
189 DCHECK(number->IsHeapNumber());
190 double value = number->Number();
192 if (!(value >= 1))
return 0;
193 uint64_t max = std::numeric_limits<uint64_t>::max();
194 if (value < max)
return static_cast<uint64_t
>(value);
198 bool TryNumberToSize(Object* number,
size_t* result) {
201 if (number->IsSmi()) {
202 int value = Smi::ToInt(number);
203 DCHECK(static_cast<unsigned>(Smi::kMaxValue) <=
204 std::numeric_limits<size_t>::max());
206 *result =
static_cast<size_t>(value);
211 DCHECK(number->IsHeapNumber());
212 double value = HeapNumber::cast(number)->value();
217 double maxSize =
static_cast<double>(std::numeric_limits<size_t>::max());
218 if (value >= 0 && value < maxSize) {
219 *result =
static_cast<size_t>(value);
227 size_t NumberToSize(Object* number) {
229 bool is_valid = TryNumberToSize(number, &result);
236 return static_cast<uint32_t>(DoubleToInt32(x));
242 #endif // V8_CONVERSIONS_INL_H_