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_INL_H_
6#define V8_CONVERSIONS_INL_H_
7
8#include <float.h>         // Required for DBL_MAX and on Win32 for finite()
9#include <limits.h>        // Required for INT_MAX etc.
10#include <stdarg.h>
11#include <cmath>
12#include "src/globals.h"       // Required for V8_INFINITY
13#include "src/unicode-cache-inl.h"
14
15// ----------------------------------------------------------------------------
16// Extra POSIX/ANSI functions for Win32/MSVC.
17
18#include "src/base/bits.h"
19#include "src/base/platform/platform.h"
20#include "src/conversions.h"
21#include "src/double.h"
22#include "src/objects-inl.h"
23#include "src/strtod.h"
24
25namespace v8 {
26namespace internal {
27
28inline double JunkStringValue() {
29  return bit_cast<double, uint64_t>(kQuietNaNMask);
30}
31
32
33inline double SignedZero(bool negative) {
34  return negative ? uint64_to_double(Double::kSignMask) : 0.0;
35}
36
37
38// The fast double-to-unsigned-int conversion routine does not guarantee
39// rounding towards zero, or any reasonable value if the argument is larger
40// than what fits in an unsigned 32-bit integer.
41inline unsigned int FastD2UI(double x) {
42  // There is no unsigned version of lrint, so there is no fast path
43  // in this function as there is in FastD2I. Using lrint doesn't work
44  // for values of 2^31 and above.
45
46  // Convert "small enough" doubles to uint32_t by fixing the 32
47  // least significant non-fractional bits in the low 32 bits of the
48  // double, and reading them from there.
49  const double k2Pow52 = 4503599627370496.0;
50  bool negative = x < 0;
51  if (negative) {
52    x = -x;
53  }
54  if (x < k2Pow52) {
55    x += k2Pow52;
56    uint32_t result;
57#ifndef V8_TARGET_BIG_ENDIAN
58    Address mantissa_ptr = reinterpret_cast<Address>(&x);
59#else
60    Address mantissa_ptr = reinterpret_cast<Address>(&x) + kInt32Size;
61#endif
62    // Copy least significant 32 bits of mantissa.
63    memcpy(&result, mantissa_ptr, sizeof(result));
64    return negative ? ~result + 1 : result;
65  }
66  // Large number (outside uint32 range), Infinity or NaN.
67  return 0x80000000u;  // Return integer indefinite.
68}
69
70
71inline float DoubleToFloat32(double x) {
72  // TODO(yangguo): This static_cast is implementation-defined behaviour in C++,
73  // so we may need to do the conversion manually instead to match the spec.
74  volatile float f = static_cast<float>(x);
75  return f;
76}
77
78
79inline double DoubleToInteger(double x) {
80  if (std::isnan(x)) return 0;
81  if (!std::isfinite(x) || x == 0) return x;
82  return (x >= 0) ? std::floor(x) : std::ceil(x);
83}
84
85
86int32_t DoubleToInt32(double x) {
87  int32_t i = FastD2I(x);
88  if (FastI2D(i) == x) return i;
89  Double d(x);
90  int exponent = d.Exponent();
91  if (exponent < 0) {
92    if (exponent <= -Double::kSignificandSize) return 0;
93    return d.Sign() * static_cast<int32_t>(d.Significand() >> -exponent);
94  } else {
95    if (exponent > 31) return 0;
96    return d.Sign() * static_cast<int32_t>(d.Significand() << exponent);
97  }
98}
99
100bool DoubleToSmiInteger(double value, int* smi_int_value) {
101  if (IsMinusZero(value)) return false;
102  int i = FastD2IChecked(value);
103  if (value != i || !Smi::IsValid(i)) return false;
104  *smi_int_value = i;
105  return true;
106}
107
108bool IsSmiDouble(double value) {
109  return !IsMinusZero(value) && value >= Smi::kMinValue &&
110         value <= Smi::kMaxValue && value == FastI2D(FastD2I(value));
111}
112
113
114bool IsInt32Double(double value) {
115  return !IsMinusZero(value) && value >= kMinInt && value <= kMaxInt &&
116         value == FastI2D(FastD2I(value));
117}
118
119
120bool IsUint32Double(double value) {
121  return !IsMinusZero(value) && value >= 0 && value <= kMaxUInt32 &&
122         value == FastUI2D(FastD2UI(value));
123}
124
125bool DoubleToUint32IfEqualToSelf(double value, uint32_t* uint32_value) {
126  const double k2Pow52 = 4503599627370496.0;
127  const uint32_t kValidTopBits = 0x43300000;
128  const uint64_t kBottomBitMask = V8_2PART_UINT64_C(0x00000000, FFFFFFFF);
129
130  // Add 2^52 to the double, to place valid uint32 values in the low-significant
131  // bits of the exponent, by effectively setting the (implicit) top bit of the
132  // significand. Note that this addition also normalises 0.0 and -0.0.
133  double shifted_value = value + k2Pow52;
134
135  // At this point, a valid uint32 valued double will be represented as:
136  //
137  // sign = 0
138  // exponent = 52
139  // significand = 1. 00...00 <value>
140  //       implicit^          ^^^^^^^ 32 bits
141  //                  ^^^^^^^^^^^^^^^ 52 bits
142  //
143  // Therefore, we can first check the top 32 bits to make sure that the sign,
144  // exponent and remaining significand bits are valid, and only then check the
145  // value in the bottom 32 bits.
146
147  uint64_t result = bit_cast<uint64_t>(shifted_value);
148  if ((result >> 32) == kValidTopBits) {
149    *uint32_value = result & kBottomBitMask;
150    return FastUI2D(result & kBottomBitMask) == value;
151  }
152  return false;
153}
154
155int32_t NumberToInt32(Object* number) {
156  if (number->IsSmi()) return Smi::cast(number)->value();
157  return DoubleToInt32(number->Number());
158}
159
160uint32_t NumberToUint32(Object* number) {
161  if (number->IsSmi()) return Smi::cast(number)->value();
162  return DoubleToUint32(number->Number());
163}
164
165uint32_t PositiveNumberToUint32(Object* number) {
166  if (number->IsSmi()) {
167    int value = Smi::cast(number)->value();
168    if (value <= 0) return 0;
169    return value;
170  }
171  DCHECK(number->IsHeapNumber());
172  double value = number->Number();
173  // Catch all values smaller than 1 and use the double-negation trick for NANs.
174  if (!(value >= 1)) return 0;
175  uint32_t max = std::numeric_limits<uint32_t>::max();
176  if (value < max) return static_cast<uint32_t>(value);
177  return max;
178}
179
180int64_t NumberToInt64(Object* number) {
181  if (number->IsSmi()) return Smi::cast(number)->value();
182  return static_cast<int64_t>(number->Number());
183}
184
185bool TryNumberToSize(Object* number, size_t* result) {
186  // Do not create handles in this function! Don't use SealHandleScope because
187  // the function can be used concurrently.
188  if (number->IsSmi()) {
189    int value = Smi::cast(number)->value();
190    DCHECK(static_cast<unsigned>(Smi::kMaxValue) <=
191           std::numeric_limits<size_t>::max());
192    if (value >= 0) {
193      *result = static_cast<size_t>(value);
194      return true;
195    }
196    return false;
197  } else {
198    DCHECK(number->IsHeapNumber());
199    double value = HeapNumber::cast(number)->value();
200    // If value is compared directly to the limit, the limit will be
201    // casted to a double and could end up as limit + 1,
202    // because a double might not have enough mantissa bits for it.
203    // So we might as well cast the limit first, and use < instead of <=.
204    double maxSize = static_cast<double>(std::numeric_limits<size_t>::max());
205    if (value >= 0 && value < maxSize) {
206      *result = static_cast<size_t>(value);
207      return true;
208    } else {
209      return false;
210    }
211  }
212}
213
214size_t NumberToSize(Object* number) {
215  size_t result = 0;
216  bool is_valid = TryNumberToSize(number, &result);
217  CHECK(is_valid);
218  return result;
219}
220
221
222uint32_t DoubleToUint32(double x) {
223  return static_cast<uint32_t>(DoubleToInt32(x));
224}
225
226
227template <class Iterator, class EndMark>
228bool SubStringEquals(Iterator* current,
229                     EndMark end,
230                     const char* substring) {
231  DCHECK(**current == *substring);
232  for (substring++; *substring != '\0'; substring++) {
233    ++*current;
234    if (*current == end || **current != *substring) return false;
235  }
236  ++*current;
237  return true;
238}
239
240
241// Returns true if a nonspace character has been found and false if the
242// end was been reached before finding a nonspace character.
243template <class Iterator, class EndMark>
244inline bool AdvanceToNonspace(UnicodeCache* unicode_cache,
245                              Iterator* current,
246                              EndMark end) {
247  while (*current != end) {
248    if (!unicode_cache->IsWhiteSpaceOrLineTerminator(**current)) return true;
249    ++*current;
250  }
251  return false;
252}
253
254
255// Parsing integers with radix 2, 4, 8, 16, 32. Assumes current != end.
256template <int radix_log_2, class Iterator, class EndMark>
257double InternalStringToIntDouble(UnicodeCache* unicode_cache,
258                                 Iterator current,
259                                 EndMark end,
260                                 bool negative,
261                                 bool allow_trailing_junk) {
262  DCHECK(current != end);
263
264  // Skip leading 0s.
265  while (*current == '0') {
266    ++current;
267    if (current == end) return SignedZero(negative);
268  }
269
270  int64_t number = 0;
271  int exponent = 0;
272  const int radix = (1 << radix_log_2);
273
274  do {
275    int digit;
276    if (*current >= '0' && *current <= '9' && *current < '0' + radix) {
277      digit = static_cast<char>(*current) - '0';
278    } else if (radix > 10 && *current >= 'a' && *current < 'a' + radix - 10) {
279      digit = static_cast<char>(*current) - 'a' + 10;
280    } else if (radix > 10 && *current >= 'A' && *current < 'A' + radix - 10) {
281      digit = static_cast<char>(*current) - 'A' + 10;
282    } else {
283      if (allow_trailing_junk ||
284          !AdvanceToNonspace(unicode_cache, &current, end)) {
285        break;
286      } else {
287        return JunkStringValue();
288      }
289    }
290
291    number = number * radix + digit;
292    int overflow = static_cast<int>(number >> 53);
293    if (overflow != 0) {
294      // Overflow occurred. Need to determine which direction to round the
295      // result.
296      int overflow_bits_count = 1;
297      while (overflow > 1) {
298        overflow_bits_count++;
299        overflow >>= 1;
300      }
301
302      int dropped_bits_mask = ((1 << overflow_bits_count) - 1);
303      int dropped_bits = static_cast<int>(number) & dropped_bits_mask;
304      number >>= overflow_bits_count;
305      exponent = overflow_bits_count;
306
307      bool zero_tail = true;
308      while (true) {
309        ++current;
310        if (current == end || !isDigit(*current, radix)) break;
311        zero_tail = zero_tail && *current == '0';
312        exponent += radix_log_2;
313      }
314
315      if (!allow_trailing_junk &&
316          AdvanceToNonspace(unicode_cache, &current, end)) {
317        return JunkStringValue();
318      }
319
320      int middle_value = (1 << (overflow_bits_count - 1));
321      if (dropped_bits > middle_value) {
322        number++;  // Rounding up.
323      } else if (dropped_bits == middle_value) {
324        // Rounding to even to consistency with decimals: half-way case rounds
325        // up if significant part is odd and down otherwise.
326        if ((number & 1) != 0 || !zero_tail) {
327          number++;  // Rounding up.
328        }
329      }
330
331      // Rounding up may cause overflow.
332      if ((number & (static_cast<int64_t>(1) << 53)) != 0) {
333        exponent++;
334        number >>= 1;
335      }
336      break;
337    }
338    ++current;
339  } while (current != end);
340
341  DCHECK(number < ((int64_t)1 << 53));
342  DCHECK(static_cast<int64_t>(static_cast<double>(number)) == number);
343
344  if (exponent == 0) {
345    if (negative) {
346      if (number == 0) return -0.0;
347      number = -number;
348    }
349    return static_cast<double>(number);
350  }
351
352  DCHECK(number != 0);
353  return std::ldexp(static_cast<double>(negative ? -number : number), exponent);
354}
355
356// ES6 18.2.5 parseInt(string, radix)
357template <class Iterator, class EndMark>
358double InternalStringToInt(UnicodeCache* unicode_cache,
359                           Iterator current,
360                           EndMark end,
361                           int radix) {
362  const bool allow_trailing_junk = true;
363  const double empty_string_val = JunkStringValue();
364
365  if (!AdvanceToNonspace(unicode_cache, &current, end)) {
366    return empty_string_val;
367  }
368
369  bool negative = false;
370  bool leading_zero = false;
371
372  if (*current == '+') {
373    // Ignore leading sign; skip following spaces.
374    ++current;
375    if (current == end) {
376      return JunkStringValue();
377    }
378  } else if (*current == '-') {
379    ++current;
380    if (current == end) {
381      return JunkStringValue();
382    }
383    negative = true;
384  }
385
386  if (radix == 0) {
387    // Radix detection.
388    radix = 10;
389    if (*current == '0') {
390      ++current;
391      if (current == end) return SignedZero(negative);
392      if (*current == 'x' || *current == 'X') {
393        radix = 16;
394        ++current;
395        if (current == end) return JunkStringValue();
396      } else {
397        leading_zero = true;
398      }
399    }
400  } else if (radix == 16) {
401    if (*current == '0') {
402      // Allow "0x" prefix.
403      ++current;
404      if (current == end) return SignedZero(negative);
405      if (*current == 'x' || *current == 'X') {
406        ++current;
407        if (current == end) return JunkStringValue();
408      } else {
409        leading_zero = true;
410      }
411    }
412  }
413
414  if (radix < 2 || radix > 36) return JunkStringValue();
415
416  // Skip leading zeros.
417  while (*current == '0') {
418    leading_zero = true;
419    ++current;
420    if (current == end) return SignedZero(negative);
421  }
422
423  if (!leading_zero && !isDigit(*current, radix)) {
424    return JunkStringValue();
425  }
426
427  if (base::bits::IsPowerOfTwo32(radix)) {
428    switch (radix) {
429      case 2:
430        return InternalStringToIntDouble<1>(
431            unicode_cache, current, end, negative, allow_trailing_junk);
432      case 4:
433        return InternalStringToIntDouble<2>(
434            unicode_cache, current, end, negative, allow_trailing_junk);
435      case 8:
436        return InternalStringToIntDouble<3>(
437            unicode_cache, current, end, negative, allow_trailing_junk);
438
439      case 16:
440        return InternalStringToIntDouble<4>(
441            unicode_cache, current, end, negative, allow_trailing_junk);
442
443      case 32:
444        return InternalStringToIntDouble<5>(
445            unicode_cache, current, end, negative, allow_trailing_junk);
446      default:
447        UNREACHABLE();
448    }
449  }
450
451  if (radix == 10) {
452    // Parsing with strtod.
453    const int kMaxSignificantDigits = 309;  // Doubles are less than 1.8e308.
454    // The buffer may contain up to kMaxSignificantDigits + 1 digits and a zero
455    // end.
456    const int kBufferSize = kMaxSignificantDigits + 2;
457    char buffer[kBufferSize];
458    int buffer_pos = 0;
459    while (*current >= '0' && *current <= '9') {
460      if (buffer_pos <= kMaxSignificantDigits) {
461        // If the number has more than kMaxSignificantDigits it will be parsed
462        // as infinity.
463        DCHECK(buffer_pos < kBufferSize);
464        buffer[buffer_pos++] = static_cast<char>(*current);
465      }
466      ++current;
467      if (current == end) break;
468    }
469
470    if (!allow_trailing_junk &&
471        AdvanceToNonspace(unicode_cache, &current, end)) {
472      return JunkStringValue();
473    }
474
475    SLOW_DCHECK(buffer_pos < kBufferSize);
476    buffer[buffer_pos] = '\0';
477    Vector<const char> buffer_vector(buffer, buffer_pos);
478    return negative ? -Strtod(buffer_vector, 0) : Strtod(buffer_vector, 0);
479  }
480
481  // The following code causes accumulating rounding error for numbers greater
482  // than ~2^56. It's explicitly allowed in the spec: "if R is not 2, 4, 8, 10,
483  // 16, or 32, then mathInt may be an implementation-dependent approximation to
484  // the mathematical integer value" (15.1.2.2).
485
486  int lim_0 = '0' + (radix < 10 ? radix : 10);
487  int lim_a = 'a' + (radix - 10);
488  int lim_A = 'A' + (radix - 10);
489
490  // NOTE: The code for computing the value may seem a bit complex at
491  // first glance. It is structured to use 32-bit multiply-and-add
492  // loops as long as possible to avoid loosing precision.
493
494  double v = 0.0;
495  bool done = false;
496  do {
497    // Parse the longest part of the string starting at index j
498    // possible while keeping the multiplier, and thus the part
499    // itself, within 32 bits.
500    unsigned int part = 0, multiplier = 1;
501    while (true) {
502      int d;
503      if (*current >= '0' && *current < lim_0) {
504        d = *current - '0';
505      } else if (*current >= 'a' && *current < lim_a) {
506        d = *current - 'a' + 10;
507      } else if (*current >= 'A' && *current < lim_A) {
508        d = *current - 'A' + 10;
509      } else {
510        done = true;
511        break;
512      }
513
514      // Update the value of the part as long as the multiplier fits
515      // in 32 bits. When we can't guarantee that the next iteration
516      // will not overflow the multiplier, we stop parsing the part
517      // by leaving the loop.
518      const unsigned int kMaximumMultiplier = 0xffffffffU / 36;
519      uint32_t m = multiplier * radix;
520      if (m > kMaximumMultiplier) break;
521      part = part * radix + d;
522      multiplier = m;
523      DCHECK(multiplier > part);
524
525      ++current;
526      if (current == end) {
527        done = true;
528        break;
529      }
530    }
531
532    // Update the value and skip the part in the string.
533    v = v * multiplier + part;
534  } while (!done);
535
536  if (!allow_trailing_junk &&
537      AdvanceToNonspace(unicode_cache, &current, end)) {
538    return JunkStringValue();
539  }
540
541  return negative ? -v : v;
542}
543
544
545// Converts a string to a double value. Assumes the Iterator supports
546// the following operations:
547// 1. current == end (other ops are not allowed), current != end.
548// 2. *current - gets the current character in the sequence.
549// 3. ++current (advances the position).
550template <class Iterator, class EndMark>
551double InternalStringToDouble(UnicodeCache* unicode_cache,
552                              Iterator current,
553                              EndMark end,
554                              int flags,
555                              double empty_string_val) {
556  // To make sure that iterator dereferencing is valid the following
557  // convention is used:
558  // 1. Each '++current' statement is followed by check for equality to 'end'.
559  // 2. If AdvanceToNonspace returned false then current == end.
560  // 3. If 'current' becomes be equal to 'end' the function returns or goes to
561  // 'parsing_done'.
562  // 4. 'current' is not dereferenced after the 'parsing_done' label.
563  // 5. Code before 'parsing_done' may rely on 'current != end'.
564  if (!AdvanceToNonspace(unicode_cache, &current, end)) {
565    return empty_string_val;
566  }
567
568  const bool allow_trailing_junk = (flags & ALLOW_TRAILING_JUNK) != 0;
569
570  // The longest form of simplified number is: "-<significant digits>'.1eXXX\0".
571  const int kBufferSize = kMaxSignificantDigits + 10;
572  char buffer[kBufferSize];  // NOLINT: size is known at compile time.
573  int buffer_pos = 0;
574
575  // Exponent will be adjusted if insignificant digits of the integer part
576  // or insignificant leading zeros of the fractional part are dropped.
577  int exponent = 0;
578  int significant_digits = 0;
579  int insignificant_digits = 0;
580  bool nonzero_digit_dropped = false;
581
582  enum Sign {
583    NONE,
584    NEGATIVE,
585    POSITIVE
586  };
587
588  Sign sign = NONE;
589
590  if (*current == '+') {
591    // Ignore leading sign.
592    ++current;
593    if (current == end) return JunkStringValue();
594    sign = POSITIVE;
595  } else if (*current == '-') {
596    ++current;
597    if (current == end) return JunkStringValue();
598    sign = NEGATIVE;
599  }
600
601  static const char kInfinityString[] = "Infinity";
602  if (*current == kInfinityString[0]) {
603    if (!SubStringEquals(&current, end, kInfinityString)) {
604      return JunkStringValue();
605    }
606
607    if (!allow_trailing_junk &&
608        AdvanceToNonspace(unicode_cache, &current, end)) {
609      return JunkStringValue();
610    }
611
612    DCHECK(buffer_pos == 0);
613    return (sign == NEGATIVE) ? -V8_INFINITY : V8_INFINITY;
614  }
615
616  bool leading_zero = false;
617  if (*current == '0') {
618    ++current;
619    if (current == end) return SignedZero(sign == NEGATIVE);
620
621    leading_zero = true;
622
623    // It could be hexadecimal value.
624    if ((flags & ALLOW_HEX) && (*current == 'x' || *current == 'X')) {
625      ++current;
626      if (current == end || !isDigit(*current, 16) || sign != NONE) {
627        return JunkStringValue();  // "0x".
628      }
629
630      return InternalStringToIntDouble<4>(unicode_cache,
631                                          current,
632                                          end,
633                                          false,
634                                          allow_trailing_junk);
635
636    // It could be an explicit octal value.
637    } else if ((flags & ALLOW_OCTAL) && (*current == 'o' || *current == 'O')) {
638      ++current;
639      if (current == end || !isDigit(*current, 8) || sign != NONE) {
640        return JunkStringValue();  // "0o".
641      }
642
643      return InternalStringToIntDouble<3>(unicode_cache,
644                                          current,
645                                          end,
646                                          false,
647                                          allow_trailing_junk);
648
649    // It could be a binary value.
650    } else if ((flags & ALLOW_BINARY) && (*current == 'b' || *current == 'B')) {
651      ++current;
652      if (current == end || !isBinaryDigit(*current) || sign != NONE) {
653        return JunkStringValue();  // "0b".
654      }
655
656      return InternalStringToIntDouble<1>(unicode_cache,
657                                          current,
658                                          end,
659                                          false,
660                                          allow_trailing_junk);
661    }
662
663    // Ignore leading zeros in the integer part.
664    while (*current == '0') {
665      ++current;
666      if (current == end) return SignedZero(sign == NEGATIVE);
667    }
668  }
669
670  bool octal = leading_zero && (flags & ALLOW_IMPLICIT_OCTAL) != 0;
671
672  // Copy significant digits of the integer part (if any) to the buffer.
673  while (*current >= '0' && *current <= '9') {
674    if (significant_digits < kMaxSignificantDigits) {
675      DCHECK(buffer_pos < kBufferSize);
676      buffer[buffer_pos++] = static_cast<char>(*current);
677      significant_digits++;
678      // Will later check if it's an octal in the buffer.
679    } else {
680      insignificant_digits++;  // Move the digit into the exponential part.
681      nonzero_digit_dropped = nonzero_digit_dropped || *current != '0';
682    }
683    octal = octal && *current < '8';
684    ++current;
685    if (current == end) goto parsing_done;
686  }
687
688  if (significant_digits == 0) {
689    octal = false;
690  }
691
692  if (*current == '.') {
693    if (octal && !allow_trailing_junk) return JunkStringValue();
694    if (octal) goto parsing_done;
695
696    ++current;
697    if (current == end) {
698      if (significant_digits == 0 && !leading_zero) {
699        return JunkStringValue();
700      } else {
701        goto parsing_done;
702      }
703    }
704
705    if (significant_digits == 0) {
706      // octal = false;
707      // Integer part consists of 0 or is absent. Significant digits start after
708      // leading zeros (if any).
709      while (*current == '0') {
710        ++current;
711        if (current == end) return SignedZero(sign == NEGATIVE);
712        exponent--;  // Move this 0 into the exponent.
713      }
714    }
715
716    // There is a fractional part.  We don't emit a '.', but adjust the exponent
717    // instead.
718    while (*current >= '0' && *current <= '9') {
719      if (significant_digits < kMaxSignificantDigits) {
720        DCHECK(buffer_pos < kBufferSize);
721        buffer[buffer_pos++] = static_cast<char>(*current);
722        significant_digits++;
723        exponent--;
724      } else {
725        // Ignore insignificant digits in the fractional part.
726        nonzero_digit_dropped = nonzero_digit_dropped || *current != '0';
727      }
728      ++current;
729      if (current == end) goto parsing_done;
730    }
731  }
732
733  if (!leading_zero && exponent == 0 && significant_digits == 0) {
734    // If leading_zeros is true then the string contains zeros.
735    // If exponent < 0 then string was [+-]\.0*...
736    // If significant_digits != 0 the string is not equal to 0.
737    // Otherwise there are no digits in the string.
738    return JunkStringValue();
739  }
740
741  // Parse exponential part.
742  if (*current == 'e' || *current == 'E') {
743    if (octal) return JunkStringValue();
744    ++current;
745    if (current == end) {
746      if (allow_trailing_junk) {
747        goto parsing_done;
748      } else {
749        return JunkStringValue();
750      }
751    }
752    char sign = '+';
753    if (*current == '+' || *current == '-') {
754      sign = static_cast<char>(*current);
755      ++current;
756      if (current == end) {
757        if (allow_trailing_junk) {
758          goto parsing_done;
759        } else {
760          return JunkStringValue();
761        }
762      }
763    }
764
765    if (current == end || *current < '0' || *current > '9') {
766      if (allow_trailing_junk) {
767        goto parsing_done;
768      } else {
769        return JunkStringValue();
770      }
771    }
772
773    const int max_exponent = INT_MAX / 2;
774    DCHECK(-max_exponent / 2 <= exponent && exponent <= max_exponent / 2);
775    int num = 0;
776    do {
777      // Check overflow.
778      int digit = *current - '0';
779      if (num >= max_exponent / 10
780          && !(num == max_exponent / 10 && digit <= max_exponent % 10)) {
781        num = max_exponent;
782      } else {
783        num = num * 10 + digit;
784      }
785      ++current;
786    } while (current != end && *current >= '0' && *current <= '9');
787
788    exponent += (sign == '-' ? -num : num);
789  }
790
791  if (!allow_trailing_junk &&
792      AdvanceToNonspace(unicode_cache, &current, end)) {
793    return JunkStringValue();
794  }
795
796  parsing_done:
797  exponent += insignificant_digits;
798
799  if (octal) {
800    return InternalStringToIntDouble<3>(unicode_cache,
801                                        buffer,
802                                        buffer + buffer_pos,
803                                        sign == NEGATIVE,
804                                        allow_trailing_junk);
805  }
806
807  if (nonzero_digit_dropped) {
808    buffer[buffer_pos++] = '1';
809    exponent--;
810  }
811
812  SLOW_DCHECK(buffer_pos < kBufferSize);
813  buffer[buffer_pos] = '\0';
814
815  double converted = Strtod(Vector<const char>(buffer, buffer_pos), exponent);
816  return (sign == NEGATIVE) ? -converted : converted;
817}
818
819}  // namespace internal
820}  // namespace v8
821
822#endif  // V8_CONVERSIONS_INL_H_
823