Line data Source code
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 1246392 : if (!(x >= INT_MIN)) return INT_MIN; // Negation to catch NaNs.
29 1246378 : if (x > INT_MAX) return INT_MAX;
30 1246360 : 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 42313341 : 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 29940222 : 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 335005 : 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 StringToDouble(const char* str, int flags, double empty_string_val = 0);
97 :
98 : double StringToInt(Isolate* isolate, Handle<String> string, int radix);
99 :
100 : // This follows https://tc39.github.io/proposal-bigint/#sec-string-to-bigint
101 : // semantics: "" => 0n.
102 : MaybeHandle<BigInt> StringToBigInt(Isolate* isolate, Handle<String> string);
103 :
104 : // This version expects a zero-terminated character array. Radix will
105 : // be inferred from string prefix (case-insensitive):
106 : // 0x -> hex
107 : // 0o -> octal
108 : // 0b -> binary
109 : V8_EXPORT_PRIVATE MaybeHandle<BigInt> BigIntLiteral(Isolate* isolate,
110 : const char* string);
111 :
112 : const int kDoubleToCStringMinBufferSize = 100;
113 :
114 : // Converts a double to a string value according to ECMA-262 9.8.1.
115 : // The buffer should be large enough for any floating point number.
116 : // 100 characters is enough.
117 : V8_EXPORT_PRIVATE const char* DoubleToCString(double value,
118 : Vector<char> buffer);
119 :
120 : // Convert an int to a null-terminated string. The returned string is
121 : // located inside the buffer, but not necessarily at the start.
122 : V8_EXPORT_PRIVATE const char* IntToCString(int n, Vector<char> buffer);
123 :
124 : // Additional number to string conversions for the number type.
125 : // The caller is responsible for calling free on the returned pointer.
126 : char* DoubleToFixedCString(double value, int f);
127 : char* DoubleToExponentialCString(double value, int f);
128 : char* DoubleToPrecisionCString(double value, int f);
129 : char* DoubleToRadixCString(double value, int radix);
130 :
131 : static inline bool IsMinusZero(double value) {
132 : return bit_cast<int64_t>(value) == bit_cast<int64_t>(-0.0);
133 : }
134 :
135 : // Returns true if value can be converted to a SMI, and returns the resulting
136 : // integer value of the SMI in |smi_int_value|.
137 : inline bool DoubleToSmiInteger(double value, int* smi_int_value);
138 :
139 : inline bool IsSmiDouble(double value);
140 :
141 : // Integer32 is an integer that can be represented as a signed 32-bit
142 : // integer. It has to be in the range [-2^31, 2^31 - 1].
143 : // We also have to check for negative 0 as it is not an Integer32.
144 : inline bool IsInt32Double(double value);
145 :
146 : // UInteger32 is an integer that can be represented as an unsigned 32-bit
147 : // integer. It has to be in the range [0, 2^32 - 1].
148 : // We also have to check for negative 0 as it is not a UInteger32.
149 : inline bool IsUint32Double(double value);
150 :
151 : // Tries to convert |value| to a uint32, setting the result in |uint32_value|.
152 : // If the output does not compare equal to the input, returns false and the
153 : // value in |uint32_value| is left unspecified.
154 : // Used for conversions such as in ECMA-262 15.4.2.2, which check "ToUint32(len)
155 : // is equal to len".
156 : inline bool DoubleToUint32IfEqualToSelf(double value, uint32_t* uint32_value);
157 :
158 : // Convert from Number object to C integer.
159 : inline uint32_t PositiveNumberToUint32(Object number);
160 : inline int32_t NumberToInt32(Object number);
161 : inline uint32_t NumberToUint32(Object number);
162 : inline int64_t NumberToInt64(Object number);
163 : inline uint64_t PositiveNumberToUint64(Object number);
164 :
165 : double StringToDouble(Isolate* isolate, Handle<String> string, int flags,
166 : double empty_string_val = 0.0);
167 :
168 : inline bool TryNumberToSize(Object number, size_t* result);
169 :
170 : // Converts a number into size_t.
171 : inline size_t NumberToSize(Object number);
172 :
173 : // returns DoubleToString(StringToDouble(string)) == string
174 : bool IsSpecialIndex(String string);
175 :
176 : } // namespace internal
177 : } // namespace v8
178 :
179 : #endif // V8_CONVERSIONS_H_
|