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/handles.h"
12#include "src/utils.h"
13
14namespace v8 {
15namespace internal {
16
17class UnicodeCache;
18
19// Maximum number of significant digits in decimal representation.
20// The longest possible double in decimal representation is
21// (2^53 - 1) * 2 ^ -1074 that is (2 ^ 53 - 1) * 5 ^ 1074 / 10 ^ 1074
22// (768 digits). If we parse a number whose first digits are equal to a
23// mean of 2 adjacent doubles (that could have up to 769 digits) the result
24// must be rounded to the bigger one unless the tail consists of zeros, so
25// we don't need to preserve all the digits.
26const int kMaxSignificantDigits = 772;
27
28
29inline bool isDigit(int x, int radix) {
30  return (x >= '0' && x <= '9' && x < '0' + radix)
31      || (radix > 10 && x >= 'a' && x < 'a' + radix - 10)
32      || (radix > 10 && x >= 'A' && x < 'A' + radix - 10);
33}
34
35
36inline bool isBinaryDigit(int x) {
37  return x == '0' || x == '1';
38}
39
40
41// The fast double-to-(unsigned-)int conversion routine does not guarantee
42// rounding towards zero.
43// If x is NaN, the result is INT_MIN.  Otherwise the result is the argument x,
44// clamped to [INT_MIN, INT_MAX] and then rounded to an integer.
45inline int FastD2IChecked(double x) {
46  if (!(x >= INT_MIN)) return INT_MIN;  // Negation to catch NaNs.
47  if (x > INT_MAX) return INT_MAX;
48  return static_cast<int>(x);
49}
50
51
52// The fast double-to-(unsigned-)int conversion routine does not guarantee
53// rounding towards zero.
54// The result is unspecified if x is infinite or NaN, or if the rounded
55// integer value is outside the range of type int.
56inline int FastD2I(double x) {
57  return static_cast<int32_t>(x);
58}
59
60inline unsigned int FastD2UI(double x);
61
62
63inline double FastI2D(int x) {
64  // There is no rounding involved in converting an integer to a
65  // double, so this code should compile to a few instructions without
66  // any FPU pipeline stalls.
67  return static_cast<double>(x);
68}
69
70
71inline double FastUI2D(unsigned x) {
72  // There is no rounding involved in converting an unsigned integer to a
73  // double, so this code should compile to a few instructions without
74  // any FPU pipeline stalls.
75  return static_cast<double>(x);
76}
77
78
79// This function should match the exact semantics of ECMA-262 20.2.2.17.
80inline float DoubleToFloat32(double x);
81
82
83// This function should match the exact semantics of ECMA-262 9.4.
84inline double DoubleToInteger(double x);
85
86
87// This function should match the exact semantics of ECMA-262 9.5.
88inline int32_t DoubleToInt32(double x);
89
90
91// This function should match the exact semantics of ECMA-262 9.6.
92inline uint32_t DoubleToUint32(double x);
93
94
95// Enumeration for allowing octals and ignoring junk when converting
96// strings to numbers.
97enum ConversionFlags {
98  NO_FLAGS = 0,
99  ALLOW_HEX = 1,
100  ALLOW_OCTAL = 2,
101  ALLOW_IMPLICIT_OCTAL = 4,
102  ALLOW_BINARY = 8,
103  ALLOW_TRAILING_JUNK = 16
104};
105
106
107// Converts a string into a double value according to ECMA-262 9.3.1
108double StringToDouble(UnicodeCache* unicode_cache,
109                      Vector<const uint8_t> str,
110                      int flags,
111                      double empty_string_val = 0);
112double StringToDouble(UnicodeCache* unicode_cache,
113                      Vector<const uc16> str,
114                      int flags,
115                      double empty_string_val = 0);
116// This version expects a zero-terminated character array.
117double StringToDouble(UnicodeCache* unicode_cache,
118                      const char* str,
119                      int flags,
120                      double empty_string_val = 0);
121
122// Converts a string into an integer.
123double StringToInt(UnicodeCache* unicode_cache,
124                   Vector<const uint8_t> vector,
125                   int radix);
126
127
128double StringToInt(UnicodeCache* unicode_cache,
129                   Vector<const uc16> vector,
130                   int radix);
131
132const int kDoubleToCStringMinBufferSize = 100;
133
134// Converts a double to a string value according to ECMA-262 9.8.1.
135// The buffer should be large enough for any floating point number.
136// 100 characters is enough.
137const char* DoubleToCString(double value, Vector<char> buffer);
138
139// Convert an int to a null-terminated string. The returned string is
140// located inside the buffer, but not necessarily at the start.
141const char* IntToCString(int n, Vector<char> buffer);
142
143// Additional number to string conversions for the number type.
144// The caller is responsible for calling free on the returned pointer.
145char* DoubleToFixedCString(double value, int f);
146char* DoubleToExponentialCString(double value, int f);
147char* DoubleToPrecisionCString(double value, int f);
148char* DoubleToRadixCString(double value, int radix);
149
150static inline bool IsMinusZero(double value) {
151  return bit_cast<int64_t>(value) == bit_cast<int64_t>(-0.0);
152}
153
154// Returns true if value can be converted to a SMI, and returns the resulting
155// integer value of the SMI in |smi_int_value|.
156inline bool DoubleToSmiInteger(double value, int* smi_int_value);
157
158inline bool IsSmiDouble(double value);
159
160// Integer32 is an integer that can be represented as a signed 32-bit
161// integer. It has to be in the range [-2^31, 2^31 - 1].
162// We also have to check for negative 0 as it is not an Integer32.
163inline bool IsInt32Double(double value);
164
165// UInteger32 is an integer that can be represented as an unsigned 32-bit
166// integer. It has to be in the range [0, 2^32 - 1].
167// We also have to check for negative 0 as it is not a UInteger32.
168inline bool IsUint32Double(double value);
169
170// Convert from Number object to C integer.
171inline int32_t NumberToInt32(Object* number);
172inline uint32_t NumberToUint32(Object* number);
173inline int64_t NumberToInt64(Object* number);
174
175double StringToDouble(UnicodeCache* unicode_cache, Handle<String> string,
176                      int flags, double empty_string_val = 0.0);
177
178inline bool TryNumberToSize(Object* number, size_t* result);
179
180// Converts a number into size_t.
181inline size_t NumberToSize(Object* number);
182
183// returns DoubleToString(StringToDouble(string)) == string
184bool IsSpecialIndex(UnicodeCache* unicode_cache, String* string);
185
186}  // namespace internal
187}  // namespace v8
188
189#endif  // V8_CONVERSIONS_H_
190