Home | History | Annotate | Download | only in src
      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 <float.h>         // Required for DBL_MAX and on Win32 for finite()
     33 #include <stdarg.h>
     34 #include <cmath>
     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 inline double SignedZero(bool negative) {
     55   return negative ? uint64_to_double(Double::kSignMask) : 0.0;
     56 }
     57 
     58 
     59 // The fast double-to-unsigned-int conversion routine does not guarantee
     60 // rounding towards zero, or any reasonable value if the argument is larger
     61 // than what fits in an unsigned 32-bit integer.
     62 inline unsigned int FastD2UI(double x) {
     63   // There is no unsigned version of lrint, so there is no fast path
     64   // in this function as there is in FastD2I. Using lrint doesn't work
     65   // for values of 2^31 and above.
     66 
     67   // Convert "small enough" doubles to uint32_t by fixing the 32
     68   // least significant non-fractional bits in the low 32 bits of the
     69   // double, and reading them from there.
     70   const double k2Pow52 = 4503599627370496.0;
     71   bool negative = x < 0;
     72   if (negative) {
     73     x = -x;
     74   }
     75   if (x < k2Pow52) {
     76     x += k2Pow52;
     77     uint32_t result;
     78     Address mantissa_ptr = reinterpret_cast<Address>(&x);
     79     // Copy least significant 32 bits of mantissa.
     80     OS::MemCopy(&result, mantissa_ptr, sizeof(result));
     81     return negative ? ~result + 1 : result;
     82   }
     83   // Large number (outside uint32 range), Infinity or NaN.
     84   return 0x80000000u;  // Return integer indefinite.
     85 }
     86 
     87 
     88 inline double DoubleToInteger(double x) {
     89   if (std::isnan(x)) return 0;
     90   if (!std::isfinite(x) || x == 0) return x;
     91   return (x >= 0) ? floor(x) : ceil(x);
     92 }
     93 
     94 
     95 int32_t DoubleToInt32(double x) {
     96   int32_t i = FastD2I(x);
     97   if (FastI2D(i) == x) return i;
     98   Double d(x);
     99   int exponent = d.Exponent();
    100   if (exponent < 0) {
    101     if (exponent <= -Double::kSignificandSize) return 0;
    102     return d.Sign() * static_cast<int32_t>(d.Significand() >> -exponent);
    103   } else {
    104     if (exponent > 31) return 0;
    105     return d.Sign() * static_cast<int32_t>(d.Significand() << exponent);
    106   }
    107 }
    108 
    109 
    110 template <class Iterator, class EndMark>
    111 bool SubStringEquals(Iterator* current,
    112                      EndMark end,
    113                      const char* substring) {
    114   ASSERT(**current == *substring);
    115   for (substring++; *substring != '\0'; substring++) {
    116     ++*current;
    117     if (*current == end || **current != *substring) return false;
    118   }
    119   ++*current;
    120   return true;
    121 }
    122 
    123 
    124 // Returns true if a nonspace character has been found and false if the
    125 // end was been reached before finding a nonspace character.
    126 template <class Iterator, class EndMark>
    127 inline bool AdvanceToNonspace(UnicodeCache* unicode_cache,
    128                               Iterator* current,
    129                               EndMark end) {
    130   while (*current != end) {
    131     if (!unicode_cache->IsWhiteSpace(**current)) return true;
    132     ++*current;
    133   }
    134   return false;
    135 }
    136 
    137 
    138 // Parsing integers with radix 2, 4, 8, 16, 32. Assumes current != end.
    139 template <int radix_log_2, class Iterator, class EndMark>
    140 double InternalStringToIntDouble(UnicodeCache* unicode_cache,
    141                                  Iterator current,
    142                                  EndMark end,
    143                                  bool negative,
    144                                  bool allow_trailing_junk) {
    145   ASSERT(current != end);
    146 
    147   // Skip leading 0s.
    148   while (*current == '0') {
    149     ++current;
    150     if (current == end) return SignedZero(negative);
    151   }
    152 
    153   int64_t number = 0;
    154   int exponent = 0;
    155   const int radix = (1 << radix_log_2);
    156 
    157   do {
    158     int digit;
    159     if (*current >= '0' && *current <= '9' && *current < '0' + radix) {
    160       digit = static_cast<char>(*current) - '0';
    161     } else if (radix > 10 && *current >= 'a' && *current < 'a' + radix - 10) {
    162       digit = static_cast<char>(*current) - 'a' + 10;
    163     } else if (radix > 10 && *current >= 'A' && *current < 'A' + radix - 10) {
    164       digit = static_cast<char>(*current) - 'A' + 10;
    165     } else {
    166       if (allow_trailing_junk ||
    167           !AdvanceToNonspace(unicode_cache, &current, end)) {
    168         break;
    169       } else {
    170         return JunkStringValue();
    171       }
    172     }
    173 
    174     number = number * radix + digit;
    175     int overflow = static_cast<int>(number >> 53);
    176     if (overflow != 0) {
    177       // Overflow occurred. Need to determine which direction to round the
    178       // result.
    179       int overflow_bits_count = 1;
    180       while (overflow > 1) {
    181         overflow_bits_count++;
    182         overflow >>= 1;
    183       }
    184 
    185       int dropped_bits_mask = ((1 << overflow_bits_count) - 1);
    186       int dropped_bits = static_cast<int>(number) & dropped_bits_mask;
    187       number >>= overflow_bits_count;
    188       exponent = overflow_bits_count;
    189 
    190       bool zero_tail = true;
    191       while (true) {
    192         ++current;
    193         if (current == end || !isDigit(*current, radix)) break;
    194         zero_tail = zero_tail && *current == '0';
    195         exponent += radix_log_2;
    196       }
    197 
    198       if (!allow_trailing_junk &&
    199           AdvanceToNonspace(unicode_cache, &current, end)) {
    200         return JunkStringValue();
    201       }
    202 
    203       int middle_value = (1 << (overflow_bits_count - 1));
    204       if (dropped_bits > middle_value) {
    205         number++;  // Rounding up.
    206       } else if (dropped_bits == middle_value) {
    207         // Rounding to even to consistency with decimals: half-way case rounds
    208         // up if significant part is odd and down otherwise.
    209         if ((number & 1) != 0 || !zero_tail) {
    210           number++;  // Rounding up.
    211         }
    212       }
    213 
    214       // Rounding up may cause overflow.
    215       if ((number & (static_cast<int64_t>(1) << 53)) != 0) {
    216         exponent++;
    217         number >>= 1;
    218       }
    219       break;
    220     }
    221     ++current;
    222   } while (current != end);
    223 
    224   ASSERT(number < ((int64_t)1 << 53));
    225   ASSERT(static_cast<int64_t>(static_cast<double>(number)) == number);
    226 
    227   if (exponent == 0) {
    228     if (negative) {
    229       if (number == 0) return -0.0;
    230       number = -number;
    231     }
    232     return static_cast<double>(number);
    233   }
    234 
    235   ASSERT(number != 0);
    236   return ldexp(static_cast<double>(negative ? -number : number), exponent);
    237 }
    238 
    239 
    240 template <class Iterator, class EndMark>
    241 double InternalStringToInt(UnicodeCache* unicode_cache,
    242                            Iterator current,
    243                            EndMark end,
    244                            int radix) {
    245   const bool allow_trailing_junk = true;
    246   const double empty_string_val = JunkStringValue();
    247 
    248   if (!AdvanceToNonspace(unicode_cache, &current, end)) {
    249     return empty_string_val;
    250   }
    251 
    252   bool negative = false;
    253   bool leading_zero = false;
    254 
    255   if (*current == '+') {
    256     // Ignore leading sign; skip following spaces.
    257     ++current;
    258     if (current == end) {
    259       return JunkStringValue();
    260     }
    261   } else if (*current == '-') {
    262     ++current;
    263     if (current == end) {
    264       return JunkStringValue();
    265     }
    266     negative = true;
    267   }
    268 
    269   if (radix == 0) {
    270     // Radix detection.
    271     radix = 10;
    272     if (*current == '0') {
    273       ++current;
    274       if (current == end) return SignedZero(negative);
    275       if (*current == 'x' || *current == 'X') {
    276         radix = 16;
    277         ++current;
    278         if (current == end) return JunkStringValue();
    279       } else {
    280         leading_zero = true;
    281       }
    282     }
    283   } else if (radix == 16) {
    284     if (*current == '0') {
    285       // Allow "0x" prefix.
    286       ++current;
    287       if (current == end) return SignedZero(negative);
    288       if (*current == 'x' || *current == 'X') {
    289         ++current;
    290         if (current == end) return JunkStringValue();
    291       } else {
    292         leading_zero = true;
    293       }
    294     }
    295   }
    296 
    297   if (radix < 2 || radix > 36) return JunkStringValue();
    298 
    299   // Skip leading zeros.
    300   while (*current == '0') {
    301     leading_zero = true;
    302     ++current;
    303     if (current == end) return SignedZero(negative);
    304   }
    305 
    306   if (!leading_zero && !isDigit(*current, radix)) {
    307     return JunkStringValue();
    308   }
    309 
    310   if (IsPowerOf2(radix)) {
    311     switch (radix) {
    312       case 2:
    313         return InternalStringToIntDouble<1>(
    314             unicode_cache, current, end, negative, allow_trailing_junk);
    315       case 4:
    316         return InternalStringToIntDouble<2>(
    317             unicode_cache, current, end, negative, allow_trailing_junk);
    318       case 8:
    319         return InternalStringToIntDouble<3>(
    320             unicode_cache, current, end, negative, allow_trailing_junk);
    321 
    322       case 16:
    323         return InternalStringToIntDouble<4>(
    324             unicode_cache, current, end, negative, allow_trailing_junk);
    325 
    326       case 32:
    327         return InternalStringToIntDouble<5>(
    328             unicode_cache, current, end, negative, allow_trailing_junk);
    329       default:
    330         UNREACHABLE();
    331     }
    332   }
    333 
    334   if (radix == 10) {
    335     // Parsing with strtod.
    336     const int kMaxSignificantDigits = 309;  // Doubles are less than 1.8e308.
    337     // The buffer may contain up to kMaxSignificantDigits + 1 digits and a zero
    338     // end.
    339     const int kBufferSize = kMaxSignificantDigits + 2;
    340     char buffer[kBufferSize];
    341     int buffer_pos = 0;
    342     while (*current >= '0' && *current <= '9') {
    343       if (buffer_pos <= kMaxSignificantDigits) {
    344         // If the number has more than kMaxSignificantDigits it will be parsed
    345         // as infinity.
    346         ASSERT(buffer_pos < kBufferSize);
    347         buffer[buffer_pos++] = static_cast<char>(*current);
    348       }
    349       ++current;
    350       if (current == end) break;
    351     }
    352 
    353     if (!allow_trailing_junk &&
    354         AdvanceToNonspace(unicode_cache, &current, end)) {
    355       return JunkStringValue();
    356     }
    357 
    358     ASSERT(buffer_pos < kBufferSize);
    359     buffer[buffer_pos] = '\0';
    360     Vector<const char> buffer_vector(buffer, buffer_pos);
    361     return negative ? -Strtod(buffer_vector, 0) : Strtod(buffer_vector, 0);
    362   }
    363 
    364   // The following code causes accumulating rounding error for numbers greater
    365   // than ~2^56. It's explicitly allowed in the spec: "if R is not 2, 4, 8, 10,
    366   // 16, or 32, then mathInt may be an implementation-dependent approximation to
    367   // the mathematical integer value" (15.1.2.2).
    368 
    369   int lim_0 = '0' + (radix < 10 ? radix : 10);
    370   int lim_a = 'a' + (radix - 10);
    371   int lim_A = 'A' + (radix - 10);
    372 
    373   // NOTE: The code for computing the value may seem a bit complex at
    374   // first glance. It is structured to use 32-bit multiply-and-add
    375   // loops as long as possible to avoid loosing precision.
    376 
    377   double v = 0.0;
    378   bool done = false;
    379   do {
    380     // Parse the longest part of the string starting at index j
    381     // possible while keeping the multiplier, and thus the part
    382     // itself, within 32 bits.
    383     unsigned int part = 0, multiplier = 1;
    384     while (true) {
    385       int d;
    386       if (*current >= '0' && *current < lim_0) {
    387         d = *current - '0';
    388       } else if (*current >= 'a' && *current < lim_a) {
    389         d = *current - 'a' + 10;
    390       } else if (*current >= 'A' && *current < lim_A) {
    391         d = *current - 'A' + 10;
    392       } else {
    393         done = true;
    394         break;
    395       }
    396 
    397       // Update the value of the part as long as the multiplier fits
    398       // in 32 bits. When we can't guarantee that the next iteration
    399       // will not overflow the multiplier, we stop parsing the part
    400       // by leaving the loop.
    401       const unsigned int kMaximumMultiplier = 0xffffffffU / 36;
    402       uint32_t m = multiplier * radix;
    403       if (m > kMaximumMultiplier) break;
    404       part = part * radix + d;
    405       multiplier = m;
    406       ASSERT(multiplier > part);
    407 
    408       ++current;
    409       if (current == end) {
    410         done = true;
    411         break;
    412       }
    413     }
    414 
    415     // Update the value and skip the part in the string.
    416     v = v * multiplier + part;
    417   } while (!done);
    418 
    419   if (!allow_trailing_junk &&
    420       AdvanceToNonspace(unicode_cache, &current, end)) {
    421     return JunkStringValue();
    422   }
    423 
    424   return negative ? -v : v;
    425 }
    426 
    427 
    428 // Converts a string to a double value. Assumes the Iterator supports
    429 // the following operations:
    430 // 1. current == end (other ops are not allowed), current != end.
    431 // 2. *current - gets the current character in the sequence.
    432 // 3. ++current (advances the position).
    433 template <class Iterator, class EndMark>
    434 double InternalStringToDouble(UnicodeCache* unicode_cache,
    435                               Iterator current,
    436                               EndMark end,
    437                               int flags,
    438                               double empty_string_val) {
    439   // To make sure that iterator dereferencing is valid the following
    440   // convention is used:
    441   // 1. Each '++current' statement is followed by check for equality to 'end'.
    442   // 2. If AdvanceToNonspace returned false then current == end.
    443   // 3. If 'current' becomes be equal to 'end' the function returns or goes to
    444   // 'parsing_done'.
    445   // 4. 'current' is not dereferenced after the 'parsing_done' label.
    446   // 5. Code before 'parsing_done' may rely on 'current != end'.
    447   if (!AdvanceToNonspace(unicode_cache, &current, end)) {
    448     return empty_string_val;
    449   }
    450 
    451   const bool allow_trailing_junk = (flags & ALLOW_TRAILING_JUNK) != 0;
    452 
    453   // The longest form of simplified number is: "-<significant digits>'.1eXXX\0".
    454   const int kBufferSize = kMaxSignificantDigits + 10;
    455   char buffer[kBufferSize];  // NOLINT: size is known at compile time.
    456   int buffer_pos = 0;
    457 
    458   // Exponent will be adjusted if insignificant digits of the integer part
    459   // or insignificant leading zeros of the fractional part are dropped.
    460   int exponent = 0;
    461   int significant_digits = 0;
    462   int insignificant_digits = 0;
    463   bool nonzero_digit_dropped = false;
    464 
    465   enum Sign {
    466     NONE,
    467     NEGATIVE,
    468     POSITIVE
    469   };
    470 
    471   Sign sign = NONE;
    472 
    473   if (*current == '+') {
    474     // Ignore leading sign.
    475     ++current;
    476     if (current == end) return JunkStringValue();
    477     sign = POSITIVE;
    478   } else if (*current == '-') {
    479     ++current;
    480     if (current == end) return JunkStringValue();
    481     sign = NEGATIVE;
    482   }
    483 
    484   static const char kInfinityString[] = "Infinity";
    485   if (*current == kInfinityString[0]) {
    486     if (!SubStringEquals(&current, end, kInfinityString)) {
    487       return JunkStringValue();
    488     }
    489 
    490     if (!allow_trailing_junk &&
    491         AdvanceToNonspace(unicode_cache, &current, end)) {
    492       return JunkStringValue();
    493     }
    494 
    495     ASSERT(buffer_pos == 0);
    496     return (sign == NEGATIVE) ? -V8_INFINITY : V8_INFINITY;
    497   }
    498 
    499   bool leading_zero = false;
    500   if (*current == '0') {
    501     ++current;
    502     if (current == end) return SignedZero(sign == NEGATIVE);
    503 
    504     leading_zero = true;
    505 
    506     // It could be hexadecimal value.
    507     if ((flags & ALLOW_HEX) && (*current == 'x' || *current == 'X')) {
    508       ++current;
    509       if (current == end || !isDigit(*current, 16) || sign != NONE) {
    510         return JunkStringValue();  // "0x".
    511       }
    512 
    513       return InternalStringToIntDouble<4>(unicode_cache,
    514                                           current,
    515                                           end,
    516                                           false,
    517                                           allow_trailing_junk);
    518 
    519     // It could be an explicit octal value.
    520     } else if ((flags & ALLOW_OCTAL) && (*current == 'o' || *current == 'O')) {
    521       ++current;
    522       if (current == end || !isDigit(*current, 8) || sign != NONE) {
    523         return JunkStringValue();  // "0o".
    524       }
    525 
    526       return InternalStringToIntDouble<3>(unicode_cache,
    527                                           current,
    528                                           end,
    529                                           false,
    530                                           allow_trailing_junk);
    531 
    532     // It could be a binary value.
    533     } else if ((flags & ALLOW_BINARY) && (*current == 'b' || *current == 'B')) {
    534       ++current;
    535       if (current == end || !isBinaryDigit(*current) || sign != NONE) {
    536         return JunkStringValue();  // "0b".
    537       }
    538 
    539       return InternalStringToIntDouble<1>(unicode_cache,
    540                                           current,
    541                                           end,
    542                                           false,
    543                                           allow_trailing_junk);
    544     }
    545 
    546     // Ignore leading zeros in the integer part.
    547     while (*current == '0') {
    548       ++current;
    549       if (current == end) return SignedZero(sign == NEGATIVE);
    550     }
    551   }
    552 
    553   bool octal = leading_zero && (flags & ALLOW_IMPLICIT_OCTAL) != 0;
    554 
    555   // Copy significant digits of the integer part (if any) to the buffer.
    556   while (*current >= '0' && *current <= '9') {
    557     if (significant_digits < kMaxSignificantDigits) {
    558       ASSERT(buffer_pos < kBufferSize);
    559       buffer[buffer_pos++] = static_cast<char>(*current);
    560       significant_digits++;
    561       // Will later check if it's an octal in the buffer.
    562     } else {
    563       insignificant_digits++;  // Move the digit into the exponential part.
    564       nonzero_digit_dropped = nonzero_digit_dropped || *current != '0';
    565     }
    566     octal = octal && *current < '8';
    567     ++current;
    568     if (current == end) goto parsing_done;
    569   }
    570 
    571   if (significant_digits == 0) {
    572     octal = false;
    573   }
    574 
    575   if (*current == '.') {
    576     if (octal && !allow_trailing_junk) return JunkStringValue();
    577     if (octal) goto parsing_done;
    578 
    579     ++current;
    580     if (current == end) {
    581       if (significant_digits == 0 && !leading_zero) {
    582         return JunkStringValue();
    583       } else {
    584         goto parsing_done;
    585       }
    586     }
    587 
    588     if (significant_digits == 0) {
    589       // octal = false;
    590       // Integer part consists of 0 or is absent. Significant digits start after
    591       // leading zeros (if any).
    592       while (*current == '0') {
    593         ++current;
    594         if (current == end) return SignedZero(sign == NEGATIVE);
    595         exponent--;  // Move this 0 into the exponent.
    596       }
    597     }
    598 
    599     // There is a fractional part.  We don't emit a '.', but adjust the exponent
    600     // instead.
    601     while (*current >= '0' && *current <= '9') {
    602       if (significant_digits < kMaxSignificantDigits) {
    603         ASSERT(buffer_pos < kBufferSize);
    604         buffer[buffer_pos++] = static_cast<char>(*current);
    605         significant_digits++;
    606         exponent--;
    607       } else {
    608         // Ignore insignificant digits in the fractional part.
    609         nonzero_digit_dropped = nonzero_digit_dropped || *current != '0';
    610       }
    611       ++current;
    612       if (current == end) goto parsing_done;
    613     }
    614   }
    615 
    616   if (!leading_zero && exponent == 0 && significant_digits == 0) {
    617     // If leading_zeros is true then the string contains zeros.
    618     // If exponent < 0 then string was [+-]\.0*...
    619     // If significant_digits != 0 the string is not equal to 0.
    620     // Otherwise there are no digits in the string.
    621     return JunkStringValue();
    622   }
    623 
    624   // Parse exponential part.
    625   if (*current == 'e' || *current == 'E') {
    626     if (octal) return JunkStringValue();
    627     ++current;
    628     if (current == end) {
    629       if (allow_trailing_junk) {
    630         goto parsing_done;
    631       } else {
    632         return JunkStringValue();
    633       }
    634     }
    635     char sign = '+';
    636     if (*current == '+' || *current == '-') {
    637       sign = static_cast<char>(*current);
    638       ++current;
    639       if (current == end) {
    640         if (allow_trailing_junk) {
    641           goto parsing_done;
    642         } else {
    643           return JunkStringValue();
    644         }
    645       }
    646     }
    647 
    648     if (current == end || *current < '0' || *current > '9') {
    649       if (allow_trailing_junk) {
    650         goto parsing_done;
    651       } else {
    652         return JunkStringValue();
    653       }
    654     }
    655 
    656     const int max_exponent = INT_MAX / 2;
    657     ASSERT(-max_exponent / 2 <= exponent && exponent <= max_exponent / 2);
    658     int num = 0;
    659     do {
    660       // Check overflow.
    661       int digit = *current - '0';
    662       if (num >= max_exponent / 10
    663           && !(num == max_exponent / 10 && digit <= max_exponent % 10)) {
    664         num = max_exponent;
    665       } else {
    666         num = num * 10 + digit;
    667       }
    668       ++current;
    669     } while (current != end && *current >= '0' && *current <= '9');
    670 
    671     exponent += (sign == '-' ? -num : num);
    672   }
    673 
    674   if (!allow_trailing_junk &&
    675       AdvanceToNonspace(unicode_cache, &current, end)) {
    676     return JunkStringValue();
    677   }
    678 
    679   parsing_done:
    680   exponent += insignificant_digits;
    681 
    682   if (octal) {
    683     return InternalStringToIntDouble<3>(unicode_cache,
    684                                         buffer,
    685                                         buffer + buffer_pos,
    686                                         sign == NEGATIVE,
    687                                         allow_trailing_junk);
    688   }
    689 
    690   if (nonzero_digit_dropped) {
    691     buffer[buffer_pos++] = '1';
    692     exponent--;
    693   }
    694 
    695   ASSERT(buffer_pos < kBufferSize);
    696   buffer[buffer_pos] = '\0';
    697 
    698   double converted = Strtod(Vector<const char>(buffer, buffer_pos), exponent);
    699   return (sign == NEGATIVE) ? -converted : converted;
    700 }
    701 
    702 } }  // namespace v8::internal
    703 
    704 #endif  // V8_CONVERSIONS_INL_H_
    705