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