1 | // Copyright 2011 the V8 project authors. All rights reserved. |
2 | // Use of this source code is governed by a BSD-style license that can be |
3 | // found in the LICENSE file. |
4 | |
5 | #ifndef V8_CONVERSIONS_H_ |
6 | #define V8_CONVERSIONS_H_ |
7 | |
8 | #include "src/base/logging.h" |
9 | #include "src/globals.h" |
10 | #include "src/vector.h" |
11 | |
12 | namespace v8 { |
13 | namespace internal { |
14 | |
15 | class BigInt; |
16 | template <typename T> |
17 | class Handle; |
18 | |
19 | // The limit for the the fractionDigits/precision for toFixed, toPrecision |
20 | // and toExponential. |
21 | const int kMaxFractionDigits = 100; |
22 | |
23 | // The fast double-to-(unsigned-)int conversion routine does not guarantee |
24 | // rounding towards zero. |
25 | // If x is NaN, the result is INT_MIN. Otherwise the result is the argument x, |
26 | // clamped to [INT_MIN, INT_MAX] and then rounded to an integer. |
27 | inline int FastD2IChecked(double x) { |
28 | if (!(x >= INT_MIN)) return INT_MIN; // Negation to catch NaNs. |
29 | if (x > INT_MAX) return INT_MAX; |
30 | return static_cast<int>(x); |
31 | } |
32 | |
33 | // The fast double-to-(unsigned-)int conversion routine does not guarantee |
34 | // rounding towards zero. |
35 | // The result is undefined if x is infinite or NaN, or if the rounded |
36 | // integer value is outside the range of type int. |
37 | inline int FastD2I(double x) { |
38 | DCHECK(x <= INT_MAX); |
39 | DCHECK(x >= INT_MIN); |
40 | return static_cast<int32_t>(x); |
41 | } |
42 | |
43 | inline unsigned int FastD2UI(double x); |
44 | |
45 | |
46 | inline double FastI2D(int x) { |
47 | // There is no rounding involved in converting an integer to a |
48 | // double, so this code should compile to a few instructions without |
49 | // any FPU pipeline stalls. |
50 | return static_cast<double>(x); |
51 | } |
52 | |
53 | |
54 | inline double FastUI2D(unsigned x) { |
55 | // There is no rounding involved in converting an unsigned integer to a |
56 | // double, so this code should compile to a few instructions without |
57 | // any FPU pipeline stalls. |
58 | return static_cast<double>(x); |
59 | } |
60 | |
61 | |
62 | // This function should match the exact semantics of ECMA-262 20.2.2.17. |
63 | inline float DoubleToFloat32(double x); |
64 | |
65 | |
66 | // This function should match the exact semantics of ECMA-262 9.4. |
67 | inline double DoubleToInteger(double x); |
68 | |
69 | |
70 | // This function should match the exact semantics of ECMA-262 9.5. |
71 | inline int32_t DoubleToInt32(double x); |
72 | |
73 | |
74 | // This function should match the exact semantics of ECMA-262 9.6. |
75 | inline uint32_t DoubleToUint32(double x); |
76 | |
77 | |
78 | // Enumeration for allowing octals and ignoring junk when converting |
79 | // strings to numbers. |
80 | enum ConversionFlags { |
81 | NO_FLAGS = 0, |
82 | ALLOW_HEX = 1, |
83 | ALLOW_OCTAL = 2, |
84 | ALLOW_IMPLICIT_OCTAL = 4, |
85 | ALLOW_BINARY = 8, |
86 | ALLOW_TRAILING_JUNK = 16 |
87 | }; |
88 | |
89 | |
90 | // Converts a string into a double value according to ECMA-262 9.3.1 |
91 | double StringToDouble(Vector<const uint8_t> str, int flags, |
92 | double empty_string_val = 0); |
93 | double StringToDouble(Vector<const uc16> str, int flags, |
94 | double empty_string_val = 0); |
95 | // This version expects a zero-terminated character array. |
96 | double V8_EXPORT_PRIVATE StringToDouble(const char* str, int flags, |
97 | double empty_string_val = 0); |
98 | |
99 | double StringToInt(Isolate* isolate, Handle<String> string, int radix); |
100 | |
101 | // This follows https://tc39.github.io/proposal-bigint/#sec-string-to-bigint |
102 | // semantics: "" => 0n. |
103 | MaybeHandle<BigInt> StringToBigInt(Isolate* isolate, Handle<String> string); |
104 | |
105 | // This version expects a zero-terminated character array. Radix will |
106 | // be inferred from string prefix (case-insensitive): |
107 | // 0x -> hex |
108 | // 0o -> octal |
109 | // 0b -> binary |
110 | V8_EXPORT_PRIVATE MaybeHandle<BigInt> BigIntLiteral(Isolate* isolate, |
111 | const char* string); |
112 | |
113 | const int kDoubleToCStringMinBufferSize = 100; |
114 | |
115 | // Converts a double to a string value according to ECMA-262 9.8.1. |
116 | // The buffer should be large enough for any floating point number. |
117 | // 100 characters is enough. |
118 | V8_EXPORT_PRIVATE const char* DoubleToCString(double value, |
119 | Vector<char> buffer); |
120 | |
121 | // Convert an int to a null-terminated string. The returned string is |
122 | // located inside the buffer, but not necessarily at the start. |
123 | V8_EXPORT_PRIVATE const char* IntToCString(int n, Vector<char> buffer); |
124 | |
125 | // Additional number to string conversions for the number type. |
126 | // The caller is responsible for calling free on the returned pointer. |
127 | char* DoubleToFixedCString(double value, int f); |
128 | char* DoubleToExponentialCString(double value, int f); |
129 | char* DoubleToPrecisionCString(double value, int f); |
130 | char* DoubleToRadixCString(double value, int radix); |
131 | |
132 | static inline bool IsMinusZero(double value) { |
133 | return bit_cast<int64_t>(value) == bit_cast<int64_t>(-0.0); |
134 | } |
135 | |
136 | // Returns true if value can be converted to a SMI, and returns the resulting |
137 | // integer value of the SMI in |smi_int_value|. |
138 | inline bool DoubleToSmiInteger(double value, int* smi_int_value); |
139 | |
140 | inline bool IsSmiDouble(double value); |
141 | |
142 | // Integer32 is an integer that can be represented as a signed 32-bit |
143 | // integer. It has to be in the range [-2^31, 2^31 - 1]. |
144 | // We also have to check for negative 0 as it is not an Integer32. |
145 | inline bool IsInt32Double(double value); |
146 | |
147 | // UInteger32 is an integer that can be represented as an unsigned 32-bit |
148 | // integer. It has to be in the range [0, 2^32 - 1]. |
149 | // We also have to check for negative 0 as it is not a UInteger32. |
150 | inline bool IsUint32Double(double value); |
151 | |
152 | // Tries to convert |value| to a uint32, setting the result in |uint32_value|. |
153 | // If the output does not compare equal to the input, returns false and the |
154 | // value in |uint32_value| is left unspecified. |
155 | // Used for conversions such as in ECMA-262 15.4.2.2, which check "ToUint32(len) |
156 | // is equal to len". |
157 | inline bool DoubleToUint32IfEqualToSelf(double value, uint32_t* uint32_value); |
158 | |
159 | // Convert from Number object to C integer. |
160 | inline uint32_t PositiveNumberToUint32(Object number); |
161 | inline int32_t NumberToInt32(Object number); |
162 | inline uint32_t NumberToUint32(Object number); |
163 | inline int64_t NumberToInt64(Object number); |
164 | inline uint64_t PositiveNumberToUint64(Object number); |
165 | |
166 | double StringToDouble(Isolate* isolate, Handle<String> string, int flags, |
167 | double empty_string_val = 0.0); |
168 | |
169 | inline bool TryNumberToSize(Object number, size_t* result); |
170 | |
171 | // Converts a number into size_t. |
172 | inline size_t NumberToSize(Object number); |
173 | |
174 | // returns DoubleToString(StringToDouble(string)) == string |
175 | V8_EXPORT_PRIVATE bool IsSpecialIndex(String string); |
176 | |
177 | } // namespace internal |
178 | } // namespace v8 |
179 | |
180 | #endif // V8_CONVERSIONS_H_ |
181 | |