conversions.h 6.43 KB
Newer Older
1
// Copyright 2011 the V8 project authors. All rights reserved.
2 3
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
4 5 6 7

#ifndef V8_CONVERSIONS_H_
#define V8_CONVERSIONS_H_

8 9
#include <limits>

10
#include "src/base/logging.h"
11
#include "src/utils.h"
12

13 14
namespace v8 {
namespace internal {
15

16
class BigInt;
marja's avatar
marja committed
17 18
template <typename T>
class Handle;
19 20
class UnicodeCache;

21 22 23
// The limit for the the fractionDigits/precision for toFixed, toPrecision
// and toExponential.
const int kMaxFractionDigits = 100;
24

25 26
// The fast double-to-(unsigned-)int conversion routine does not guarantee
// rounding towards zero.
27 28
// If x is NaN, the result is INT_MIN.  Otherwise the result is the argument x,
// clamped to [INT_MIN, INT_MAX] and then rounded to an integer.
29 30 31 32 33 34
inline int FastD2IChecked(double x) {
  if (!(x >= INT_MIN)) return INT_MIN;  // Negation to catch NaNs.
  if (x > INT_MAX) return INT_MAX;
  return static_cast<int>(x);
}

35
// The fast double-to-(unsigned-)int conversion routine does not guarantee
36
// rounding towards zero.
37
// The result is undefined if x is infinite or NaN, or if the rounded
38
// integer value is outside the range of type int.
39
inline int FastD2I(double x) {
40 41
  DCHECK(x <= INT_MAX);
  DCHECK(x >= INT_MIN);
42
  return static_cast<int32_t>(x);
43 44
}

45
inline unsigned int FastD2UI(double x);
46 47


48
inline double FastI2D(int x) {
49 50 51 52 53 54 55
  // There is no rounding involved in converting an integer to a
  // double, so this code should compile to a few instructions without
  // any FPU pipeline stalls.
  return static_cast<double>(x);
}


56
inline double FastUI2D(unsigned x) {
57 58 59 60 61 62 63
  // There is no rounding involved in converting an unsigned integer to a
  // double, so this code should compile to a few instructions without
  // any FPU pipeline stalls.
  return static_cast<double>(x);
}


64 65 66 67
// This function should match the exact semantics of ECMA-262 20.2.2.17.
inline float DoubleToFloat32(double x);


68
// This function should match the exact semantics of ECMA-262 9.4.
69
inline double DoubleToInteger(double x);
70 71 72


// This function should match the exact semantics of ECMA-262 9.5.
73
inline int32_t DoubleToInt32(double x);
74 75 76


// This function should match the exact semantics of ECMA-262 9.6.
77
inline uint32_t DoubleToUint32(double x);
78 79 80 81 82 83 84


// Enumeration for allowing octals and ignoring junk when converting
// strings to numbers.
enum ConversionFlags {
  NO_FLAGS = 0,
  ALLOW_HEX = 1,
85 86 87 88
  ALLOW_OCTAL = 2,
  ALLOW_IMPLICIT_OCTAL = 4,
  ALLOW_BINARY = 8,
  ALLOW_TRAILING_JUNK = 16
89 90 91 92
};


// Converts a string into a double value according to ECMA-262 9.3.1
93
double StringToDouble(UnicodeCache* unicode_cache,
94
                      Vector<const uint8_t> str,
95 96
                      int flags,
                      double empty_string_val = 0);
97 98 99 100
double StringToDouble(UnicodeCache* unicode_cache,
                      Vector<const uc16> str,
                      int flags,
                      double empty_string_val = 0);
101
// This version expects a zero-terminated character array.
102 103 104 105
double StringToDouble(UnicodeCache* unicode_cache,
                      const char* str,
                      int flags,
                      double empty_string_val = 0);
106

107
double StringToInt(Isolate* isolate, Handle<String> string, int radix);
108

109 110 111
// This follows https://tc39.github.io/proposal-bigint/#sec-string-to-bigint
// semantics: "" => 0n.
MaybeHandle<BigInt> StringToBigInt(Isolate* isolate, Handle<String> string);
112

113 114 115 116 117
// This version expects a zero-terminated character array. Radix will
// be inferred from string prefix (case-insensitive):
//   0x -> hex
//   0o -> octal
//   0b -> binary
118 119
V8_EXPORT_PRIVATE MaybeHandle<BigInt> BigIntLiteral(Isolate* isolate,
                                                    const char* string);
120

121 122
const int kDoubleToCStringMinBufferSize = 100;

123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138
// Converts a double to a string value according to ECMA-262 9.8.1.
// The buffer should be large enough for any floating point number.
// 100 characters is enough.
const char* DoubleToCString(double value, Vector<char> buffer);

// Convert an int to a null-terminated string. The returned string is
// located inside the buffer, but not necessarily at the start.
const char* IntToCString(int n, Vector<char> buffer);

// Additional number to string conversions for the number type.
// The caller is responsible for calling free on the returned pointer.
char* DoubleToFixedCString(double value, int f);
char* DoubleToExponentialCString(double value, int f);
char* DoubleToPrecisionCString(double value, int f);
char* DoubleToRadixCString(double value, int radix);

139
static inline bool IsMinusZero(double value) {
140
  return bit_cast<int64_t>(value) == bit_cast<int64_t>(-0.0);
141 142
}

143 144 145
// Returns true if value can be converted to a SMI, and returns the resulting
// integer value of the SMI in |smi_int_value|.
inline bool DoubleToSmiInteger(double value, int* smi_int_value);
146

147
inline bool IsSmiDouble(double value);
148

149 150 151
// Integer32 is an integer that can be represented as a signed 32-bit
// integer. It has to be in the range [-2^31, 2^31 - 1].
// We also have to check for negative 0 as it is not an Integer32.
152
inline bool IsInt32Double(double value);
153

154 155 156
// UInteger32 is an integer that can be represented as an unsigned 32-bit
// integer. It has to be in the range [0, 2^32 - 1].
// We also have to check for negative 0 as it is not a UInteger32.
157
inline bool IsUint32Double(double value);
158

159 160 161 162 163 164 165
// Tries to convert |value| to a uint32, setting the result in |uint32_value|.
// If the output does not compare equal to the input, returns false and the
// value in |uint32_value| is left unspecified.
// Used for conversions such as in ECMA-262 15.4.2.2, which check "ToUint32(len)
// is equal to len".
inline bool DoubleToUint32IfEqualToSelf(double value, uint32_t* uint32_value);

166
// Convert from Number object to C integer.
167
inline uint32_t PositiveNumberToUint32(Object* number);
168 169
inline int32_t NumberToInt32(Object* number);
inline uint32_t NumberToUint32(Object* number);
170
inline int64_t NumberToInt64(Object* number);
171
inline uint64_t PositiveNumberToUint64(Object* number);
172

173 174 175
double StringToDouble(Isolate* isolate, UnicodeCache* unicode_cache,
                      Handle<String> string, int flags,
                      double empty_string_val = 0.0);
176

177
inline bool TryNumberToSize(Object* number, size_t* result);
178 179

// Converts a number into size_t.
180
inline size_t NumberToSize(Object* number);
181

dcarney's avatar
dcarney committed
182 183
// returns DoubleToString(StringToDouble(string)) == string
bool IsSpecialIndex(UnicodeCache* unicode_cache, String* string);
184 185 186

}  // namespace internal
}  // namespace v8
187 188

#endif  // V8_CONVERSIONS_H_