v8  3.11.10(node0.8.26)
V8 is Google's open source JavaScript engine
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
conversions-inl.h
Go to the documentation of this file.
1 // Copyright 2011 the V8 project authors. All rights reserved.
2 // Redistribution and use in source and binary forms, with or without
3 // modification, are permitted provided that the following conditions are
4 // met:
5 //
6 // * Redistributions of source code must retain the above copyright
7 // notice, this list of conditions and the following disclaimer.
8 // * Redistributions in binary form must reproduce the above
9 // copyright notice, this list of conditions and the following
10 // disclaimer in the documentation and/or other materials provided
11 // with the distribution.
12 // * Neither the name of Google Inc. nor the names of its
13 // contributors may be used to endorse or promote products derived
14 // from this software without specific prior written permission.
15 //
16 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
17 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
18 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
19 // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
20 // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
21 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
22 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
26 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 
28 #ifndef V8_CONVERSIONS_INL_H_
29 #define V8_CONVERSIONS_INL_H_
30 
31 #include <limits.h> // Required for INT_MAX etc.
32 #include <math.h>
33 #include <float.h> // Required for DBL_MAX and on Win32 for finite()
34 #include <stdarg.h>
35 #include "globals.h" // Required for V8_INFINITY
36 
37 // ----------------------------------------------------------------------------
38 // Extra POSIX/ANSI functions for Win32/MSVC.
39 
40 #include "conversions.h"
41 #include "double.h"
42 #include "platform.h"
43 #include "scanner.h"
44 #include "strtod.h"
45 
46 namespace v8 {
47 namespace internal {
48 
49 inline double JunkStringValue() {
50  return BitCast<double, uint64_t>(kQuietNaNMask);
51 }
52 
53 
54 // The fast double-to-unsigned-int conversion routine does not guarantee
55 // rounding towards zero, or any reasonable value if the argument is larger
56 // than what fits in an unsigned 32-bit integer.
57 inline unsigned int FastD2UI(double x) {
58  // There is no unsigned version of lrint, so there is no fast path
59  // in this function as there is in FastD2I. Using lrint doesn't work
60  // for values of 2^31 and above.
61 
62  // Convert "small enough" doubles to uint32_t by fixing the 32
63  // least significant non-fractional bits in the low 32 bits of the
64  // double, and reading them from there.
65  const double k2Pow52 = 4503599627370496.0;
66  bool negative = x < 0;
67  if (negative) {
68  x = -x;
69  }
70  if (x < k2Pow52) {
71  x += k2Pow52;
72  uint32_t result;
73  Address mantissa_ptr = reinterpret_cast<Address>(&x);
74  // Copy least significant 32 bits of mantissa.
75  memcpy(&result, mantissa_ptr, sizeof(result));
76  return negative ? ~result + 1 : result;
77  }
78  // Large number (outside uint32 range), Infinity or NaN.
79  return 0x80000000u; // Return integer indefinite.
80 }
81 
82 
83 inline double DoubleToInteger(double x) {
84  if (isnan(x)) return 0;
85  if (!isfinite(x) || x == 0) return x;
86  return (x >= 0) ? floor(x) : ceil(x);
87 }
88 
89 
91  int32_t i = FastD2I(x);
92  if (FastI2D(i) == x) return i;
93  Double d(x);
94  int exponent = d.Exponent();
95  if (exponent < 0) {
96  if (exponent <= -Double::kSignificandSize) return 0;
97  return d.Sign() * static_cast<int32_t>(d.Significand() >> -exponent);
98  } else {
99  if (exponent > 31) return 0;
100  return d.Sign() * static_cast<int32_t>(d.Significand() << exponent);
101  }
102 }
103 
104 
105 template <class Iterator, class EndMark>
106 bool SubStringEquals(Iterator* current,
107  EndMark end,
108  const char* substring) {
109  ASSERT(**current == *substring);
110  for (substring++; *substring != '\0'; substring++) {
111  ++*current;
112  if (*current == end || **current != *substring) return false;
113  }
114  ++*current;
115  return true;
116 }
117 
118 
119 // Returns true if a nonspace character has been found and false if the
120 // end was been reached before finding a nonspace character.
121 template <class Iterator, class EndMark>
122 inline bool AdvanceToNonspace(UnicodeCache* unicode_cache,
123  Iterator* current,
124  EndMark end) {
125  while (*current != end) {
126  if (!unicode_cache->IsWhiteSpace(**current)) return true;
127  ++*current;
128  }
129  return false;
130 }
131 
132 
133 // Parsing integers with radix 2, 4, 8, 16, 32. Assumes current != end.
134 template <int radix_log_2, class Iterator, class EndMark>
136  Iterator current,
137  EndMark end,
138  bool negative,
139  bool allow_trailing_junk) {
140  ASSERT(current != end);
141 
142  // Skip leading 0s.
143  while (*current == '0') {
144  ++current;
145  if (current == end) return SignedZero(negative);
146  }
147 
148  int64_t number = 0;
149  int exponent = 0;
150  const int radix = (1 << radix_log_2);
151 
152  do {
153  int digit;
154  if (*current >= '0' && *current <= '9' && *current < '0' + radix) {
155  digit = static_cast<char>(*current) - '0';
156  } else if (radix > 10 && *current >= 'a' && *current < 'a' + radix - 10) {
157  digit = static_cast<char>(*current) - 'a' + 10;
158  } else if (radix > 10 && *current >= 'A' && *current < 'A' + radix - 10) {
159  digit = static_cast<char>(*current) - 'A' + 10;
160  } else {
161  if (allow_trailing_junk ||
162  !AdvanceToNonspace(unicode_cache, &current, end)) {
163  break;
164  } else {
165  return JunkStringValue();
166  }
167  }
168 
169  number = number * radix + digit;
170  int overflow = static_cast<int>(number >> 53);
171  if (overflow != 0) {
172  // Overflow occurred. Need to determine which direction to round the
173  // result.
174  int overflow_bits_count = 1;
175  while (overflow > 1) {
176  overflow_bits_count++;
177  overflow >>= 1;
178  }
179 
180  int dropped_bits_mask = ((1 << overflow_bits_count) - 1);
181  int dropped_bits = static_cast<int>(number) & dropped_bits_mask;
182  number >>= overflow_bits_count;
183  exponent = overflow_bits_count;
184 
185  bool zero_tail = true;
186  while (true) {
187  ++current;
188  if (current == end || !isDigit(*current, radix)) break;
189  zero_tail = zero_tail && *current == '0';
190  exponent += radix_log_2;
191  }
192 
193  if (!allow_trailing_junk &&
194  AdvanceToNonspace(unicode_cache, &current, end)) {
195  return JunkStringValue();
196  }
197 
198  int middle_value = (1 << (overflow_bits_count - 1));
199  if (dropped_bits > middle_value) {
200  number++; // Rounding up.
201  } else if (dropped_bits == middle_value) {
202  // Rounding to even to consistency with decimals: half-way case rounds
203  // up if significant part is odd and down otherwise.
204  if ((number & 1) != 0 || !zero_tail) {
205  number++; // Rounding up.
206  }
207  }
208 
209  // Rounding up may cause overflow.
210  if ((number & ((int64_t)1 << 53)) != 0) {
211  exponent++;
212  number >>= 1;
213  }
214  break;
215  }
216  ++current;
217  } while (current != end);
218 
219  ASSERT(number < ((int64_t)1 << 53));
220  ASSERT(static_cast<int64_t>(static_cast<double>(number)) == number);
221 
222  if (exponent == 0) {
223  if (negative) {
224  if (number == 0) return -0.0;
225  number = -number;
226  }
227  return static_cast<double>(number);
228  }
229 
230  ASSERT(number != 0);
231  return ldexp(static_cast<double>(negative ? -number : number), exponent);
232 }
233 
234 
235 template <class Iterator, class EndMark>
236 double InternalStringToInt(UnicodeCache* unicode_cache,
237  Iterator current,
238  EndMark end,
239  int radix) {
240  const bool allow_trailing_junk = true;
241  const double empty_string_val = JunkStringValue();
242 
243  if (!AdvanceToNonspace(unicode_cache, &current, end)) {
244  return empty_string_val;
245  }
246 
247  bool negative = false;
248  bool leading_zero = false;
249 
250  if (*current == '+') {
251  // Ignore leading sign; skip following spaces.
252  ++current;
253  if (current == end) {
254  return JunkStringValue();
255  }
256  } else if (*current == '-') {
257  ++current;
258  if (current == end) {
259  return JunkStringValue();
260  }
261  negative = true;
262  }
263 
264  if (radix == 0) {
265  // Radix detection.
266  if (*current == '0') {
267  ++current;
268  if (current == end) return SignedZero(negative);
269  if (*current == 'x' || *current == 'X') {
270  radix = 16;
271  ++current;
272  if (current == end) return JunkStringValue();
273  } else {
274  radix = 8;
275  leading_zero = true;
276  }
277  } else {
278  radix = 10;
279  }
280  } else if (radix == 16) {
281  if (*current == '0') {
282  // Allow "0x" prefix.
283  ++current;
284  if (current == end) return SignedZero(negative);
285  if (*current == 'x' || *current == 'X') {
286  ++current;
287  if (current == end) return JunkStringValue();
288  } else {
289  leading_zero = true;
290  }
291  }
292  }
293 
294  if (radix < 2 || radix > 36) return JunkStringValue();
295 
296  // Skip leading zeros.
297  while (*current == '0') {
298  leading_zero = true;
299  ++current;
300  if (current == end) return SignedZero(negative);
301  }
302 
303  if (!leading_zero && !isDigit(*current, radix)) {
304  return JunkStringValue();
305  }
306 
307  if (IsPowerOf2(radix)) {
308  switch (radix) {
309  case 2:
310  return InternalStringToIntDouble<1>(
311  unicode_cache, current, end, negative, allow_trailing_junk);
312  case 4:
313  return InternalStringToIntDouble<2>(
314  unicode_cache, current, end, negative, allow_trailing_junk);
315  case 8:
316  return InternalStringToIntDouble<3>(
317  unicode_cache, current, end, negative, allow_trailing_junk);
318 
319  case 16:
320  return InternalStringToIntDouble<4>(
321  unicode_cache, current, end, negative, allow_trailing_junk);
322 
323  case 32:
324  return InternalStringToIntDouble<5>(
325  unicode_cache, current, end, negative, allow_trailing_junk);
326  default:
327  UNREACHABLE();
328  }
329  }
330 
331  if (radix == 10) {
332  // Parsing with strtod.
333  const int kMaxSignificantDigits = 309; // Doubles are less than 1.8e308.
334  // The buffer may contain up to kMaxSignificantDigits + 1 digits and a zero
335  // end.
336  const int kBufferSize = kMaxSignificantDigits + 2;
337  char buffer[kBufferSize];
338  int buffer_pos = 0;
339  while (*current >= '0' && *current <= '9') {
340  if (buffer_pos <= kMaxSignificantDigits) {
341  // If the number has more than kMaxSignificantDigits it will be parsed
342  // as infinity.
343  ASSERT(buffer_pos < kBufferSize);
344  buffer[buffer_pos++] = static_cast<char>(*current);
345  }
346  ++current;
347  if (current == end) break;
348  }
349 
350  if (!allow_trailing_junk &&
351  AdvanceToNonspace(unicode_cache, &current, end)) {
352  return JunkStringValue();
353  }
354 
355  ASSERT(buffer_pos < kBufferSize);
356  buffer[buffer_pos] = '\0';
357  Vector<const char> buffer_vector(buffer, buffer_pos);
358  return negative ? -Strtod(buffer_vector, 0) : Strtod(buffer_vector, 0);
359  }
360 
361  // The following code causes accumulating rounding error for numbers greater
362  // than ~2^56. It's explicitly allowed in the spec: "if R is not 2, 4, 8, 10,
363  // 16, or 32, then mathInt may be an implementation-dependent approximation to
364  // the mathematical integer value" (15.1.2.2).
365 
366  int lim_0 = '0' + (radix < 10 ? radix : 10);
367  int lim_a = 'a' + (radix - 10);
368  int lim_A = 'A' + (radix - 10);
369 
370  // NOTE: The code for computing the value may seem a bit complex at
371  // first glance. It is structured to use 32-bit multiply-and-add
372  // loops as long as possible to avoid loosing precision.
373 
374  double v = 0.0;
375  bool done = false;
376  do {
377  // Parse the longest part of the string starting at index j
378  // possible while keeping the multiplier, and thus the part
379  // itself, within 32 bits.
380  unsigned int part = 0, multiplier = 1;
381  while (true) {
382  int d;
383  if (*current >= '0' && *current < lim_0) {
384  d = *current - '0';
385  } else if (*current >= 'a' && *current < lim_a) {
386  d = *current - 'a' + 10;
387  } else if (*current >= 'A' && *current < lim_A) {
388  d = *current - 'A' + 10;
389  } else {
390  done = true;
391  break;
392  }
393 
394  // Update the value of the part as long as the multiplier fits
395  // in 32 bits. When we can't guarantee that the next iteration
396  // will not overflow the multiplier, we stop parsing the part
397  // by leaving the loop.
398  const unsigned int kMaximumMultiplier = 0xffffffffU / 36;
399  uint32_t m = multiplier * radix;
400  if (m > kMaximumMultiplier) break;
401  part = part * radix + d;
402  multiplier = m;
403  ASSERT(multiplier > part);
404 
405  ++current;
406  if (current == end) {
407  done = true;
408  break;
409  }
410  }
411 
412  // Update the value and skip the part in the string.
413  v = v * multiplier + part;
414  } while (!done);
415 
416  if (!allow_trailing_junk &&
417  AdvanceToNonspace(unicode_cache, &current, end)) {
418  return JunkStringValue();
419  }
420 
421  return negative ? -v : v;
422 }
423 
424 
425 // Converts a string to a double value. Assumes the Iterator supports
426 // the following operations:
427 // 1. current == end (other ops are not allowed), current != end.
428 // 2. *current - gets the current character in the sequence.
429 // 3. ++current (advances the position).
430 template <class Iterator, class EndMark>
431 double InternalStringToDouble(UnicodeCache* unicode_cache,
432  Iterator current,
433  EndMark end,
434  int flags,
435  double empty_string_val) {
436  // To make sure that iterator dereferencing is valid the following
437  // convention is used:
438  // 1. Each '++current' statement is followed by check for equality to 'end'.
439  // 2. If AdvanceToNonspace returned false then current == end.
440  // 3. If 'current' becomes be equal to 'end' the function returns or goes to
441  // 'parsing_done'.
442  // 4. 'current' is not dereferenced after the 'parsing_done' label.
443  // 5. Code before 'parsing_done' may rely on 'current != end'.
444  if (!AdvanceToNonspace(unicode_cache, &current, end)) {
445  return empty_string_val;
446  }
447 
448  const bool allow_trailing_junk = (flags & ALLOW_TRAILING_JUNK) != 0;
449 
450  // The longest form of simplified number is: "-<significant digits>'.1eXXX\0".
451  const int kBufferSize = kMaxSignificantDigits + 10;
452  char buffer[kBufferSize]; // NOLINT: size is known at compile time.
453  int buffer_pos = 0;
454 
455  // Exponent will be adjusted if insignificant digits of the integer part
456  // or insignificant leading zeros of the fractional part are dropped.
457  int exponent = 0;
458  int significant_digits = 0;
459  int insignificant_digits = 0;
460  bool nonzero_digit_dropped = false;
461 
462  bool negative = false;
463 
464  if (*current == '+') {
465  // Ignore leading sign.
466  ++current;
467  if (current == end) return JunkStringValue();
468  } else if (*current == '-') {
469  ++current;
470  if (current == end) return JunkStringValue();
471  negative = true;
472  }
473 
474  static const char kInfinitySymbol[] = "Infinity";
475  if (*current == kInfinitySymbol[0]) {
476  if (!SubStringEquals(&current, end, kInfinitySymbol)) {
477  return JunkStringValue();
478  }
479 
480  if (!allow_trailing_junk &&
481  AdvanceToNonspace(unicode_cache, &current, end)) {
482  return JunkStringValue();
483  }
484 
485  ASSERT(buffer_pos == 0);
486  return negative ? -V8_INFINITY : V8_INFINITY;
487  }
488 
489  bool leading_zero = false;
490  if (*current == '0') {
491  ++current;
492  if (current == end) return SignedZero(negative);
493 
494  leading_zero = true;
495 
496  // It could be hexadecimal value.
497  if ((flags & ALLOW_HEX) && (*current == 'x' || *current == 'X')) {
498  ++current;
499  if (current == end || !isDigit(*current, 16)) {
500  return JunkStringValue(); // "0x".
501  }
502 
503  return InternalStringToIntDouble<4>(unicode_cache,
504  current,
505  end,
506  negative,
507  allow_trailing_junk);
508  }
509 
510  // Ignore leading zeros in the integer part.
511  while (*current == '0') {
512  ++current;
513  if (current == end) return SignedZero(negative);
514  }
515  }
516 
517  bool octal = leading_zero && (flags & ALLOW_OCTALS) != 0;
518 
519  // Copy significant digits of the integer part (if any) to the buffer.
520  while (*current >= '0' && *current <= '9') {
521  if (significant_digits < kMaxSignificantDigits) {
522  ASSERT(buffer_pos < kBufferSize);
523  buffer[buffer_pos++] = static_cast<char>(*current);
524  significant_digits++;
525  // Will later check if it's an octal in the buffer.
526  } else {
527  insignificant_digits++; // Move the digit into the exponential part.
528  nonzero_digit_dropped = nonzero_digit_dropped || *current != '0';
529  }
530  octal = octal && *current < '8';
531  ++current;
532  if (current == end) goto parsing_done;
533  }
534 
535  if (significant_digits == 0) {
536  octal = false;
537  }
538 
539  if (*current == '.') {
540  if (octal && !allow_trailing_junk) return JunkStringValue();
541  if (octal) goto parsing_done;
542 
543  ++current;
544  if (current == end) {
545  if (significant_digits == 0 && !leading_zero) {
546  return JunkStringValue();
547  } else {
548  goto parsing_done;
549  }
550  }
551 
552  if (significant_digits == 0) {
553  // octal = false;
554  // Integer part consists of 0 or is absent. Significant digits start after
555  // leading zeros (if any).
556  while (*current == '0') {
557  ++current;
558  if (current == end) return SignedZero(negative);
559  exponent--; // Move this 0 into the exponent.
560  }
561  }
562 
563  // There is a fractional part. We don't emit a '.', but adjust the exponent
564  // instead.
565  while (*current >= '0' && *current <= '9') {
566  if (significant_digits < kMaxSignificantDigits) {
567  ASSERT(buffer_pos < kBufferSize);
568  buffer[buffer_pos++] = static_cast<char>(*current);
569  significant_digits++;
570  exponent--;
571  } else {
572  // Ignore insignificant digits in the fractional part.
573  nonzero_digit_dropped = nonzero_digit_dropped || *current != '0';
574  }
575  ++current;
576  if (current == end) goto parsing_done;
577  }
578  }
579 
580  if (!leading_zero && exponent == 0 && significant_digits == 0) {
581  // If leading_zeros is true then the string contains zeros.
582  // If exponent < 0 then string was [+-]\.0*...
583  // If significant_digits != 0 the string is not equal to 0.
584  // Otherwise there are no digits in the string.
585  return JunkStringValue();
586  }
587 
588  // Parse exponential part.
589  if (*current == 'e' || *current == 'E') {
590  if (octal) return JunkStringValue();
591  ++current;
592  if (current == end) {
593  if (allow_trailing_junk) {
594  goto parsing_done;
595  } else {
596  return JunkStringValue();
597  }
598  }
599  char sign = '+';
600  if (*current == '+' || *current == '-') {
601  sign = static_cast<char>(*current);
602  ++current;
603  if (current == end) {
604  if (allow_trailing_junk) {
605  goto parsing_done;
606  } else {
607  return JunkStringValue();
608  }
609  }
610  }
611 
612  if (current == end || *current < '0' || *current > '9') {
613  if (allow_trailing_junk) {
614  goto parsing_done;
615  } else {
616  return JunkStringValue();
617  }
618  }
619 
620  const int max_exponent = INT_MAX / 2;
621  ASSERT(-max_exponent / 2 <= exponent && exponent <= max_exponent / 2);
622  int num = 0;
623  do {
624  // Check overflow.
625  int digit = *current - '0';
626  if (num >= max_exponent / 10
627  && !(num == max_exponent / 10 && digit <= max_exponent % 10)) {
628  num = max_exponent;
629  } else {
630  num = num * 10 + digit;
631  }
632  ++current;
633  } while (current != end && *current >= '0' && *current <= '9');
634 
635  exponent += (sign == '-' ? -num : num);
636  }
637 
638  if (!allow_trailing_junk &&
639  AdvanceToNonspace(unicode_cache, &current, end)) {
640  return JunkStringValue();
641  }
642 
643  parsing_done:
644  exponent += insignificant_digits;
645 
646  if (octal) {
647  return InternalStringToIntDouble<3>(unicode_cache,
648  buffer,
649  buffer + buffer_pos,
650  negative,
651  allow_trailing_junk);
652  }
653 
654  if (nonzero_digit_dropped) {
655  buffer[buffer_pos++] = '1';
656  exponent--;
657  }
658 
659  ASSERT(buffer_pos < kBufferSize);
660  buffer[buffer_pos] = '\0';
661 
662  double converted = Strtod(Vector<const char>(buffer, buffer_pos), exponent);
663  return negative ? -converted : converted;
664 }
665 
666 } } // namespace v8::internal
667 
668 #endif // V8_CONVERSIONS_INL_H_
byte * Address
Definition: globals.h:172
uint64_t Significand() const
Definition: double.h:110
double InternalStringToDouble(UnicodeCache *unicode_cache, Iterator current, EndMark end, int flags, double empty_string_val)
double DoubleToInteger(double x)
bool SubStringEquals(Iterator *current, EndMark end, const char *substring)
const uint64_t kQuietNaNMask
Definition: globals.h:268
Flag flags[]
Definition: flags.cc:1467
int int32_t
Definition: unicode.cc:47
int Exponent() const
Definition: double.h:101
bool isDigit(int x, int radix)
Definition: conversions.h:48
bool IsWhiteSpace(unibrow::uchar c)
Definition: scanner.h:157
double InternalStringToInt(UnicodeCache *unicode_cache, Iterator current, EndMark end, int radix)
#define ASSERT(condition)
Definition: checks.h:270
static const int kSignificandSize
Definition: double.h:49
int isnan(double x)
#define V8_INFINITY
Definition: globals.h:32
double Strtod(Vector< const char > buffer, int exponent)
Definition: strtod.cc:417
double SignedZero(bool negative)
Definition: conversions.h:55
#define UNREACHABLE()
Definition: checks.h:50
unsigned int FastD2UI(double x)
double JunkStringValue()
double InternalStringToIntDouble(UnicodeCache *unicode_cache, Iterator current, EndMark end, bool negative, bool allow_trailing_junk)
bool IsPowerOf2(T x)
Definition: utils.h:50
bool AdvanceToNonspace(UnicodeCache *unicode_cache, Iterator *current, EndMark end)
const int kMaxSignificantDigits
Definition: conversions.h:45
int32_t DoubleToInt32(double x)
double FastI2D(int x)
Definition: conversions.h:73
int isfinite(double x)
int FastD2I(double x)
Definition: conversions.h:64
int Sign() const
Definition: double.h:139