conversions.h 7.12 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
#ifndef V8_NUMBERS_CONVERSIONS_H_
#define V8_NUMBERS_CONVERSIONS_H_
7

8
#include "src/base/export-template.h"
9
#include "src/base/logging.h"
10
#include "src/base/optional.h"
11
#include "src/base/strings.h"
12
#include "src/base/vector.h"
13
#include "src/common/globals.h"
14

15 16
namespace v8 {
namespace internal {
17

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

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

26 27
// The fast double-to-(unsigned-)int conversion routine does not guarantee
// rounding towards zero.
28 29
// 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.
30 31 32 33 34 35
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);
}

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

46
inline unsigned int FastD2UI(double x);
47

48
inline double FastI2D(int x) {
49 50 51 52 53 54
  // 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);
}

55
inline double FastUI2D(unsigned x) {
56 57 58 59 60 61
  // 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);
}

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

65
// This function should match the exact semantics of ECMA-262 9.4.
66
inline double DoubleToInteger(double x);
67 68

// This function should match the exact semantics of ECMA-262 9.5.
69
inline int32_t DoubleToInt32(double x);
70 71

// This function should match the exact semantics of ECMA-262 9.6.
72
inline uint32_t DoubleToUint32(double x);
73

74 75 76 77 78
// These functions have similar semantics as the ones above, but are
// added for 64-bit integer types.
inline int64_t DoubleToInt64(double x);
inline uint64_t DoubleToUint64(double x);

79 80 81
// Enumeration for allowing octals and ignoring junk when converting
// strings to numbers.
enum ConversionFlags {
82
  NO_CONVERSION_FLAGS = 0,
83
  ALLOW_HEX = 1,
84 85 86 87
  ALLOW_OCTAL = 2,
  ALLOW_IMPLICIT_OCTAL = 4,
  ALLOW_BINARY = 8,
  ALLOW_TRAILING_JUNK = 16
88 89 90
};

// Converts a string into a double value according to ECMA-262 9.3.1
91
double StringToDouble(base::Vector<const uint8_t> str, int flags,
92
                      double empty_string_val = 0);
93
double StringToDouble(base::Vector<const base::uc16> str, int flags,
94
                      double empty_string_val = 0);
95
// This version expects a zero-terminated character array.
96 97
double V8_EXPORT_PRIVATE StringToDouble(const char* str, int flags,
                                        double empty_string_val = 0);
98

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

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

105 106 107 108 109
// This version expects a zero-terminated character array. Radix will
// be inferred from string prefix (case-insensitive):
//   0x -> hex
//   0o -> octal
//   0b -> binary
110
template <typename IsolateT>
111
EXPORT_TEMPLATE_DECLARE(V8_EXPORT_PRIVATE)
112
MaybeHandle<BigInt> BigIntLiteral(IsolateT* isolate, const char* string);
113

114 115
const int kDoubleToCStringMinBufferSize = 100;

116 117 118
// 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.
119
V8_EXPORT_PRIVATE const char* DoubleToCString(double value,
120
                                              base::Vector<char> buffer);
121

122 123
V8_EXPORT_PRIVATE std::unique_ptr<char[]> BigIntLiteralToDecimal(
    LocalIsolate* isolate, base::Vector<const uint8_t> literal);
124 125
// Convert an int to a null-terminated string. The returned string is
// located inside the buffer, but not necessarily at the start.
126
V8_EXPORT_PRIVATE const char* IntToCString(int n, base::Vector<char> buffer);
127 128 129 130 131

// 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);
132
char* DoubleToPrecisionCString(double value, int f);
133 134
char* DoubleToRadixCString(double value, int radix);

135
static inline bool IsMinusZero(double value) {
136
  return base::bit_cast<int64_t>(value) == base::bit_cast<int64_t>(-0.0);
137 138
}

139 140 141
// 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);
142

143
inline bool IsSmiDouble(double value);
144

145 146 147
// 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.
148
inline bool IsInt32Double(double value);
149

150 151 152
// 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.
153
inline bool IsUint32Double(double value);
154

155 156 157 158 159 160 161
// 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);

162
// Convert from Number object to C integer.
163 164 165 166 167
inline uint32_t PositiveNumberToUint32(Object number);
inline int32_t NumberToInt32(Object number);
inline uint32_t NumberToUint32(Object number);
inline int64_t NumberToInt64(Object number);
inline uint64_t PositiveNumberToUint64(Object number);
168

169
double StringToDouble(Isolate* isolate, Handle<String> string, int flags,
170
                      double empty_string_val = 0.0);
171

172 173 174 175
// String to double helper without heap allocation.
// Returns base::nullopt if the string is longer than
// {max_length_for_conversion}. 23 was chosen because any representable double
// can be represented using a string of length 23.
176
V8_EXPORT_PRIVATE base::Optional<double> TryStringToDouble(
177 178
    LocalIsolate* isolate, Handle<String> object,
    int max_length_for_conversion = 23);
179

180
inline bool TryNumberToSize(Object number, size_t* result);
181 182

// Converts a number into size_t.
183
inline size_t NumberToSize(Object number);
184

dcarney's avatar
dcarney committed
185
// returns DoubleToString(StringToDouble(string)) == string
186
V8_EXPORT_PRIVATE bool IsSpecialIndex(String string);
187 188 189

}  // namespace internal
}  // namespace v8
190

191
#endif  // V8_NUMBERS_CONVERSIONS_H_