v8
V8 is Google’s open source high-performance JavaScript and WebAssembly engine, written in C++.
Loading...
Searching...
No Matches
conversions.h
Go to the documentation of this file.
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_NUMBERS_CONVERSIONS_H_
6#define V8_NUMBERS_CONVERSIONS_H_
7
8#include <optional>
9#include <string_view>
10
12#include "src/base/logging.h"
13#include "src/base/macros.h"
14#include "src/base/strings.h"
15#include "src/base/vector.h"
16#include "src/common/globals.h"
17
18namespace v8 {
19namespace internal {
20
21class BigInt;
22class SharedStringAccessGuardIfNeeded;
23
24// uint64_t constants prefixed with kFP64 are bit patterns of doubles.
25// uint64_t constants prefixed with kFP16 are bit patterns of doubles encoding
26// limits of half-precision floating point values.
27constexpr int kFP64ExponentBits = 11;
28constexpr int kFP64MantissaBits = 52;
29constexpr uint64_t kFP64ExponentBias = 1023;
30constexpr uint64_t kFP64SignMask = uint64_t{1}
32constexpr uint64_t kFP64Infinity = uint64_t{2047} << kFP64MantissaBits;
35constexpr uint64_t kFP16MinExponent = kFP64ExponentBias - 14;
38
39constexpr int kFP16MantissaBits = 10;
40constexpr uint16_t kFP16qNaN = 0x7e00;
41constexpr uint16_t kFP16Infinity = 0x7c00;
42
43// A value that, when added, has the effect that if any of the lower 41 bits of
44// the mantissa are set, the 11th mantissa bit from the front becomes set. Used
45// for rounding when converting from double to half-precision.
46constexpr uint64_t kFP64To16RoundingAddend =
47 (uint64_t{1} << ((kFP64MantissaBits - kFP16MantissaBits) - 1)) - 1;
48// A value that, when added, rebiases the exponent of a double to the range of
49// the half precision and performs rounding as described above in
50// kFP64To16RoundingAddend. Note that 15-kFP64ExponentBias overflows into the
51// sign bit, but that bit is implicitly cut off when assigning the 64-bit double
52// to a 16-bit output.
54 ((uint64_t{15} - kFP64ExponentBias) << kFP64MantissaBits) +
56// A magic value that aligns 10 mantissa bits at the bottom of the double when
57// added to a double using floating point addition. Depends on floating point
58// addition being round-to-nearest-even.
59constexpr uint64_t kFP64To16DenormalMagic =
62
63constexpr uint32_t kFP32WithoutSignMask = 0x7fffffff;
64constexpr uint32_t kFP32MinFP16ZeroRepresentable = 0x33000000;
65constexpr uint32_t kFP32MaxFP16Representable = 0x47800000;
66constexpr uint32_t kFP32SubnormalThresholdOfFP16 = 0x38800000;
67
68// The limit for the the fractionDigits/precision for toFixed, toPrecision
69// and toExponential.
70constexpr int kMaxFractionDigits = 100;
72// Leave room in the result for appending a minus and a period.
75// Leave room in the result for appending a minus, for a period, up to 5 zeros
76// padding after the period and a zero in front of the period.
78// Leave room in the result for one digit before the period, a minus, a period,
79// the letter 'e', a minus or a plus depending on the exponent, and a three
80// digit exponent.
82// The algorithm starts with the decimal point in the middle and writes to the
83// left for the integer part and to the right for the fractional part.
84// 1024 characters for the exponent and 52 for the mantissa either way, with
85// additional space for sign and decimal point.
86constexpr int kDoubleToRadixMaxChars = 2200;
87// The fast double-to-(unsigned-)int conversion routine does not guarantee
88// rounding towards zero.
89// If x is NaN, the result is INT_MIN. Otherwise the result is the argument x,
90// clamped to [INT_MIN, INT_MAX] and then rounded to an integer.
91inline int FastD2IChecked(double x) {
92 if (!(x >= INT_MIN)) return INT_MIN; // Negation to catch NaNs.
93 if (x > INT_MAX) return INT_MAX;
94 return static_cast<int>(x);
95}
96
97// The fast double-to-(unsigned-)int conversion routine does not guarantee
98// rounding towards zero.
99// The result is undefined if x is infinite or NaN, or if the rounded
100// integer value is outside the range of type int.
101inline int FastD2I(double x) {
102 DCHECK(x <= INT_MAX);
103 DCHECK(x >= INT_MIN);
104 return static_cast<int32_t>(x);
105}
106
107inline unsigned int FastD2UI(double x);
108
109inline double FastI2D(int x) {
110 // There is no rounding involved in converting an integer to a
111 // double, so this code should compile to a few instructions without
112 // any FPU pipeline stalls.
113 return static_cast<double>(x);
114}
115
116inline double FastUI2D(unsigned x) {
117 // There is no rounding involved in converting an unsigned integer to a
118 // double, so this code should compile to a few instructions without
119 // any FPU pipeline stalls.
120 return static_cast<double>(x);
121}
122
123// This function should match the exact semantics of ECMA-262 20.2.2.17.
124inline float DoubleToFloat32(double x);
126
127// This function should match the exact semantics of truncating x to
128// IEEE 754-2019 binary16 format using roundTiesToEven mode.
129inline uint16_t DoubleToFloat16(double x);
130
131// This function should match the exact semantics of ECMA-262 9.4.
132inline double DoubleToInteger(double x);
133
134// This function should match the exact semantics of ECMA-262 9.5.
135inline int32_t DoubleToInt32(double x);
137
138// This function should match the exact semantics of ECMA-262 9.6.
139inline uint32_t DoubleToUint32(double x);
140
141// These functions have similar semantics as the ones above, but are
142// added for 64-bit integer types.
143inline int64_t DoubleToInt64(double x);
144inline uint64_t DoubleToUint64(double x);
145
146// Enumeration for allowing radix prefixes or ignoring junk when converting
147// strings to numbers. We never need to be able to allow both.
153
154// Converts a string into a double value according to ECMA-262 9.3.1
156 double empty_string_val = 0);
158 double empty_string_val = 0);
159// This version expects a zero-terminated character array.
160double V8_EXPORT_PRIVATE StringToDouble(const char* str, ConversionFlag flag,
161 double empty_string_val = 0);
162
163// Converts a binary string (of the form `0b[0-1]*`) into a double value
164// according to https://tc39.es/ecma262/#sec-numericvalue
166
167// Converts an octal string (of the form `0o[0-8]*`) into a double value
168// according to https://tc39.es/ecma262/#sec-numericvalue
170
171// Converts a hex string (of the form `0x[0-9a-f]*`) into a double value
172// according to https://tc39.es/ecma262/#sec-numericvalue
174
175// Converts an implicit octal string (a.k.a. LegacyOctalIntegerLiteral, of the
176// form `0[0-7]*`) into a double value according to
177// https://tc39.es/ecma262/#sec-numericvalue
180
181double StringToInt(Isolate* isolate, DirectHandle<String> string, int radix);
182
183// This follows https://tc39.github.io/proposal-bigint/#sec-string-to-bigint
184// semantics: "" => 0n.
185MaybeHandle<BigInt> StringToBigInt(Isolate* isolate,
186 DirectHandle<String> string);
187
188// This version expects a zero-terminated character array. Radix will
189// be inferred from string prefix (case-insensitive):
190// 0x -> hex
191// 0o -> octal
192// 0b -> binary
193template <typename IsolateT>
195MaybeHandle<BigInt> BigIntLiteral(IsolateT* isolate, const char* string);
196
198
199// Converts a double to a string value according to ECMA-262 9.8.1.
200// The buffer should be large enough for any floating point number.
201// 100 characters is enough.
202// Note: The returned string_view is not necessarily pointing inside the
203// provided buffer.
205 double value, base::Vector<char> buffer);
206
207V8_EXPORT_PRIVATE std::unique_ptr<char[]> BigIntLiteralToDecimal(
209// Convert an int to string value. The returned string is located inside the
210// buffer, but not necessarily at the start.
211V8_EXPORT_PRIVATE std::string_view IntToStringView(int n,
212 base::Vector<char> buffer);
213
214// Additional number to string conversions for the number type.
215std::string_view DoubleToFixedStringView(double value, int f,
216 base::Vector<char> buffer);
217std::string_view DoubleToExponentialStringView(double value, int f,
218 base::Vector<char> buffer);
219std::string_view DoubleToPrecisionStringView(double value, int f,
220 base::Vector<char> buffer);
221std::string_view DoubleToRadixStringView(double value, int radix,
222 base::Vector<char> buffer);
223
224static inline bool IsMinusZero(double value) {
226}
227
228// Returns true if value can be converted to a SMI, and returns the resulting
229// integer value of the SMI in |smi_int_value|.
230inline bool DoubleToSmiInteger(double value, int* smi_int_value);
231
232inline bool IsSmiDouble(double value);
233
234// Integer32 is an integer that can be represented as a signed 32-bit
235// integer. It has to be in the range [-2^31, 2^31 - 1].
236// We also have to check for negative 0 as it is not an Integer32.
237inline bool IsInt32Double(double value);
238
239// UInteger32 is an integer that can be represented as an unsigned 32-bit
240// integer. It has to be in the range [0, 2^32 - 1].
241// We also have to check for negative 0 as it is not a UInteger32.
242inline bool IsUint32Double(double value);
243
244// Tries to convert |value| to a uint32, setting the result in |uint32_value|.
245// If the output does not compare equal to the input, returns false and the
246// value in |uint32_value| is left unspecified.
247// Used for conversions such as in ECMA-262 15.4.2.2, which check "ToUint32(len)
248// is equal to len".
249inline bool DoubleToUint32IfEqualToSelf(double value, uint32_t* uint32_value);
250
251// Convert from Number object to C integer.
252inline uint32_t PositiveNumberToUint32(Tagged<Object> number);
253inline int32_t NumberToInt32(Tagged<Object> number);
254inline uint32_t NumberToUint32(Tagged<Object> number);
255inline int64_t NumberToInt64(Tagged<Object> number);
256inline uint64_t PositiveNumberToUint64(Tagged<Object> number);
257
258double StringToDouble(Isolate* isolate, DirectHandle<String> string,
259 ConversionFlag flags, double empty_string_val = 0.0);
261 double empty_string_val);
262
263// String to double helper without heap allocation.
264// Returns std::nullopt if the string is longer than
265// {max_length_for_conversion}. 23 was chosen because any representable double
266// can be represented using a string of length 23.
267V8_EXPORT_PRIVATE std::optional<double> TryStringToDouble(
268 LocalIsolate* isolate, DirectHandle<String> object,
269 uint32_t max_length_for_conversion = 23);
270
271// Return std::nullopt if the string is longer than 20.
272V8_EXPORT_PRIVATE std::optional<double> TryStringToInt(
273 LocalIsolate* isolate, DirectHandle<String> object, int radix);
274
275inline bool TryNumberToSize(Tagged<Object> number, size_t* result);
276
277// Converts a number into size_t.
278inline size_t NumberToSize(Tagged<Object> number);
279
280// returns DoubleToString(StringToDouble(string)) == string
282 Tagged<String> string, SharedStringAccessGuardIfNeeded& access_guard);
284
285} // namespace internal
286} // namespace v8
287
288#endif // V8_NUMBERS_CONVERSIONS_H_
#define EXPORT_TEMPLATE_DECLARE(export)
ZoneVector< RpoNumber > & result
int x
FunctionLiteral * literal
Definition liveedit.cc:294
V8_INLINE Dest bit_cast(Source const &source)
Definition macros.h:95
bool IsUint32Double(double value)
uint32_t DoubleToUint32(double x)
int32_t DoubleToInt32_NoInline(double x)
constexpr uint64_t kFP64SignMask
Definition conversions.h:30
std::optional< double > TryStringToDouble(LocalIsolate *isolate, DirectHandle< String > object, uint32_t max_length_for_conversion)
constexpr int kDoubleToPrecisionMaxChars
Definition conversions.h:77
uint32_t PositiveNumberToUint32(Tagged< Object > number)
constexpr uint32_t kFP32SubnormalThresholdOfFP16
Definition conversions.h:66
bool DoubleToUint32IfEqualToSelf(double value, uint32_t *uint32_value)
double OctalStringToDouble(base::Vector< const uint8_t > str)
bool DoubleToSmiInteger(double value, int *smi_int_value)
double FlatStringToDouble(Tagged< String > string, ConversionFlag flag, double empty_string_val)
bool IsSmiDouble(double value)
constexpr uint64_t kFP64ExponentBias
Definition conversions.h:29
double HexStringToDouble(base::Vector< const uint8_t > str)
double StringToInt(Isolate *isolate, DirectHandle< String > string, int radix)
unsigned int FastD2UI(double x)
constexpr uint32_t kFP32MinFP16ZeroRepresentable
Definition conversions.h:64
int64_t NumberToInt64(Tagged< Object > number)
Tagged(T object) -> Tagged< T >
bool IsSpecialIndex(Tagged< String > string)
double DoubleToInteger(double x)
bool IsInt32Double(double value)
std::string_view IntToStringView(int n, base::Vector< char > buffer)
MaybeHandle< BigInt > BigIntLiteral(IsolateT *isolate, const char *string)
double FastI2D(int x)
constexpr int kFP16MantissaBits
Definition conversions.h:39
double ImplicitOctalStringToDouble(base::Vector< const uint8_t > str)
constexpr uint64_t kFP64Infinity
Definition conversions.h:32
double BinaryStringToDouble(base::Vector< const uint8_t > str)
constexpr uint64_t kFP16InfinityAndNaNInfimum
Definition conversions.h:33
std::string_view DoubleToExponentialStringView(double value, int f, base::Vector< char > buffer)
constexpr int kDoubleToRadixMaxChars
Definition conversions.h:86
uint32_t NumberToUint32(Tagged< Object > number)
int64_t DoubleToInt64(double x)
int32_t NumberToInt32(Tagged< Object > number)
constexpr int kDoubleToFixedMaxDigitsBeforePoint
Definition conversions.h:71
constexpr int kFP64ExponentBits
Definition conversions.h:27
constexpr uint16_t kFP16Infinity
Definition conversions.h:41
constexpr uint32_t kFP32MaxFP16Representable
Definition conversions.h:65
int32_t DoubleToInt32(double x)
constexpr uint64_t kFP16DenormalThreshold
Definition conversions.h:36
int FastD2I(double x)
constexpr uint64_t kFP64To16RoundingAddend
Definition conversions.h:46
constexpr uint32_t kFP32WithoutSignMask
Definition conversions.h:63
float DoubleToFloat32_NoInline(double x)
float DoubleToFloat32(double x)
@ ALLOW_NON_DECIMAL_PREFIX
constexpr int kDoubleToStringMinBufferSize
constexpr int kDoubleToFixedMaxChars
Definition conversions.h:73
uint16_t DoubleToFloat16(double value)
double FastUI2D(unsigned x)
static bool IsMinusZero(double value)
constexpr int kFP64MantissaBits
Definition conversions.h:28
std::string_view DoubleToStringView(double v, base::Vector< char > buffer)
std::optional< double > TryStringToInt(LocalIsolate *isolate, DirectHandle< String > object, int radix)
uint64_t PositiveNumberToUint64(Tagged< Object > number)
constexpr uint16_t kFP16qNaN
Definition conversions.h:40
std::string_view DoubleToRadixStringView(double value, int radix, base::Vector< char > buffer)
uint64_t DoubleToUint64(double x)
constexpr int kDoubleToExponentialMaxChars
Definition conversions.h:81
size_t NumberToSize(Tagged< Object > number)
std::string_view DoubleToFixedStringView(double value, int f, base::Vector< char > buffer)
constexpr uint64_t kFP64To16RebiasExponentAndRound
Definition conversions.h:53
bool TryNumberToSize(Tagged< Object > number, size_t *result)
std::string_view DoubleToPrecisionStringView(double value, int p, base::Vector< char > buffer)
int FastD2IChecked(double x)
Definition conversions.h:91
constexpr int kMaxFractionDigits
Definition conversions.h:70
double StringToDouble(const char *str, ConversionFlag flags, double empty_string_val)
constexpr uint64_t kFP16MinExponent
Definition conversions.h:35
MaybeHandle< BigInt > StringToBigInt(Isolate *isolate, DirectHandle< String > string)
std::unique_ptr< char[]> BigIntLiteralToDecimal(LocalIsolate *isolate, base::Vector< const uint8_t > literal)
constexpr uint64_t kFP64To16DenormalMagic
Definition conversions.h:59
#define DCHECK(condition)
Definition logging.h:482
#define V8_EXPORT_PRIVATE
Definition macros.h:460