| OLD | NEW | 
|---|
| 1 // Copyright 2006-2008 the V8 project authors. All rights reserved. | 1 // Copyright 2011 the V8 project authors. All rights reserved. | 
| 2 // Redistribution and use in source and binary forms, with or without | 2 // Redistribution and use in source and binary forms, with or without | 
| 3 // modification, are permitted provided that the following conditions are | 3 // modification, are permitted provided that the following conditions are | 
| 4 // met: | 4 // met: | 
| 5 // | 5 // | 
| 6 //     * Redistributions of source code must retain the above copyright | 6 //     * Redistributions of source code must retain the above copyright | 
| 7 //       notice, this list of conditions and the following disclaimer. | 7 //       notice, this list of conditions and the following disclaimer. | 
| 8 //     * Redistributions in binary form must reproduce the above | 8 //     * Redistributions in binary form must reproduce the above | 
| 9 //       copyright notice, this list of conditions and the following | 9 //       copyright notice, this list of conditions and the following | 
| 10 //       disclaimer in the documentation and/or other materials provided | 10 //       disclaimer in the documentation and/or other materials provided | 
| 11 //       with the distribution. | 11 //       with the distribution. | 
| (...skipping 90 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 102 // must be rounded to the bigger one unless the tail consists of zeros, so | 102 // must be rounded to the bigger one unless the tail consists of zeros, so | 
| 103 // we don't need to preserve all the digits. | 103 // we don't need to preserve all the digits. | 
| 104 const int kMaxSignificantDigits = 772; | 104 const int kMaxSignificantDigits = 772; | 
| 105 | 105 | 
| 106 | 106 | 
| 107 static const double JUNK_STRING_VALUE = OS::nan_value(); | 107 static const double JUNK_STRING_VALUE = OS::nan_value(); | 
| 108 | 108 | 
| 109 | 109 | 
| 110 // Returns true if a nonspace found and false if the end has reached. | 110 // Returns true if a nonspace found and false if the end has reached. | 
| 111 template <class Iterator, class EndMark> | 111 template <class Iterator, class EndMark> | 
| 112 static inline bool AdvanceToNonspace(ScannerConstants* scanner_constants, | 112 static inline bool AdvanceToNonspace(UnicodeCache* unicode_cache, | 
| 113                                      Iterator* current, | 113                                      Iterator* current, | 
| 114                                      EndMark end) { | 114                                      EndMark end) { | 
| 115   while (*current != end) { | 115   while (*current != end) { | 
| 116     if (!scanner_constants->IsWhiteSpace(**current)) return true; | 116     if (!unicode_cache->IsWhiteSpace(**current)) return true; | 
| 117     ++*current; | 117     ++*current; | 
| 118   } | 118   } | 
| 119   return false; | 119   return false; | 
| 120 } | 120 } | 
| 121 | 121 | 
| 122 | 122 | 
| 123 static bool isDigit(int x, int radix) { | 123 static bool isDigit(int x, int radix) { | 
| 124   return (x >= '0' && x <= '9' && x < '0' + radix) | 124   return (x >= '0' && x <= '9' && x < '0' + radix) | 
| 125       || (radix > 10 && x >= 'a' && x < 'a' + radix - 10) | 125       || (radix > 10 && x >= 'a' && x < 'a' + radix - 10) | 
| 126       || (radix > 10 && x >= 'A' && x < 'A' + radix - 10); | 126       || (radix > 10 && x >= 'A' && x < 'A' + radix - 10); | 
| 127 } | 127 } | 
| 128 | 128 | 
| 129 | 129 | 
| 130 static double SignedZero(bool negative) { | 130 static double SignedZero(bool negative) { | 
| 131   return negative ? -0.0 : 0.0; | 131   return negative ? -0.0 : 0.0; | 
| 132 } | 132 } | 
| 133 | 133 | 
| 134 | 134 | 
| 135 // Parsing integers with radix 2, 4, 8, 16, 32. Assumes current != end. | 135 // Parsing integers with radix 2, 4, 8, 16, 32. Assumes current != end. | 
| 136 template <int radix_log_2, class Iterator, class EndMark> | 136 template <int radix_log_2, class Iterator, class EndMark> | 
| 137 static double InternalStringToIntDouble(ScannerConstants* scanner_constants, | 137 static double InternalStringToIntDouble(UnicodeCache* unicode_cache, | 
| 138                                         Iterator current, | 138                                         Iterator current, | 
| 139                                         EndMark end, | 139                                         EndMark end, | 
| 140                                         bool negative, | 140                                         bool negative, | 
| 141                                         bool allow_trailing_junk) { | 141                                         bool allow_trailing_junk) { | 
| 142   ASSERT(current != end); | 142   ASSERT(current != end); | 
| 143 | 143 | 
| 144   // Skip leading 0s. | 144   // Skip leading 0s. | 
| 145   while (*current == '0') { | 145   while (*current == '0') { | 
| 146     ++current; | 146     ++current; | 
| 147     if (current == end) return SignedZero(negative); | 147     if (current == end) return SignedZero(negative); | 
| 148   } | 148   } | 
| 149 | 149 | 
| 150   int64_t number = 0; | 150   int64_t number = 0; | 
| 151   int exponent = 0; | 151   int exponent = 0; | 
| 152   const int radix = (1 << radix_log_2); | 152   const int radix = (1 << radix_log_2); | 
| 153 | 153 | 
| 154   do { | 154   do { | 
| 155     int digit; | 155     int digit; | 
| 156     if (*current >= '0' && *current <= '9' && *current < '0' + radix) { | 156     if (*current >= '0' && *current <= '9' && *current < '0' + radix) { | 
| 157       digit = static_cast<char>(*current) - '0'; | 157       digit = static_cast<char>(*current) - '0'; | 
| 158     } else if (radix > 10 && *current >= 'a' && *current < 'a' + radix - 10) { | 158     } else if (radix > 10 && *current >= 'a' && *current < 'a' + radix - 10) { | 
| 159       digit = static_cast<char>(*current) - 'a' + 10; | 159       digit = static_cast<char>(*current) - 'a' + 10; | 
| 160     } else if (radix > 10 && *current >= 'A' && *current < 'A' + radix - 10) { | 160     } else if (radix > 10 && *current >= 'A' && *current < 'A' + radix - 10) { | 
| 161       digit = static_cast<char>(*current) - 'A' + 10; | 161       digit = static_cast<char>(*current) - 'A' + 10; | 
| 162     } else { | 162     } else { | 
| 163       if (allow_trailing_junk || | 163       if (allow_trailing_junk || | 
| 164           !AdvanceToNonspace(scanner_constants, ¤t, end)) { | 164           !AdvanceToNonspace(unicode_cache, ¤t, end)) { | 
| 165         break; | 165         break; | 
| 166       } else { | 166       } else { | 
| 167         return JUNK_STRING_VALUE; | 167         return JUNK_STRING_VALUE; | 
| 168       } | 168       } | 
| 169     } | 169     } | 
| 170 | 170 | 
| 171     number = number * radix + digit; | 171     number = number * radix + digit; | 
| 172     int overflow = static_cast<int>(number >> 53); | 172     int overflow = static_cast<int>(number >> 53); | 
| 173     if (overflow != 0) { | 173     if (overflow != 0) { | 
| 174       // Overflow occurred. Need to determine which direction to round the | 174       // Overflow occurred. Need to determine which direction to round the | 
| (...skipping 11 matching lines...) Expand all  Loading... | 
| 186 | 186 | 
| 187       bool zero_tail = true; | 187       bool zero_tail = true; | 
| 188       while (true) { | 188       while (true) { | 
| 189         ++current; | 189         ++current; | 
| 190         if (current == end || !isDigit(*current, radix)) break; | 190         if (current == end || !isDigit(*current, radix)) break; | 
| 191         zero_tail = zero_tail && *current == '0'; | 191         zero_tail = zero_tail && *current == '0'; | 
| 192         exponent += radix_log_2; | 192         exponent += radix_log_2; | 
| 193       } | 193       } | 
| 194 | 194 | 
| 195       if (!allow_trailing_junk && | 195       if (!allow_trailing_junk && | 
| 196           AdvanceToNonspace(scanner_constants, ¤t, end)) { | 196           AdvanceToNonspace(unicode_cache, ¤t, end)) { | 
| 197         return JUNK_STRING_VALUE; | 197         return JUNK_STRING_VALUE; | 
| 198       } | 198       } | 
| 199 | 199 | 
| 200       int middle_value = (1 << (overflow_bits_count - 1)); | 200       int middle_value = (1 << (overflow_bits_count - 1)); | 
| 201       if (dropped_bits > middle_value) { | 201       if (dropped_bits > middle_value) { | 
| 202         number++;  // Rounding up. | 202         number++;  // Rounding up. | 
| 203       } else if (dropped_bits == middle_value) { | 203       } else if (dropped_bits == middle_value) { | 
| 204         // Rounding to even to consistency with decimals: half-way case rounds | 204         // Rounding to even to consistency with decimals: half-way case rounds | 
| 205         // up if significant part is odd and down otherwise. | 205         // up if significant part is odd and down otherwise. | 
| 206         if ((number & 1) != 0 || !zero_tail) { | 206         if ((number & 1) != 0 || !zero_tail) { | 
| (...skipping 23 matching lines...) Expand all  Loading... | 
| 230   } | 230   } | 
| 231 | 231 | 
| 232   ASSERT(number != 0); | 232   ASSERT(number != 0); | 
| 233   // The double could be constructed faster from number (mantissa), exponent | 233   // The double could be constructed faster from number (mantissa), exponent | 
| 234   // and sign. Assuming it's a rare case more simple code is used. | 234   // and sign. Assuming it's a rare case more simple code is used. | 
| 235   return static_cast<double>(negative ? -number : number) * pow(2.0, exponent); | 235   return static_cast<double>(negative ? -number : number) * pow(2.0, exponent); | 
| 236 } | 236 } | 
| 237 | 237 | 
| 238 | 238 | 
| 239 template <class Iterator, class EndMark> | 239 template <class Iterator, class EndMark> | 
| 240 static double InternalStringToInt(ScannerConstants* scanner_constants, | 240 static double InternalStringToInt(UnicodeCache* unicode_cache, | 
| 241                                   Iterator current, | 241                                   Iterator current, | 
| 242                                   EndMark end, | 242                                   EndMark end, | 
| 243                                   int radix) { | 243                                   int radix) { | 
| 244   const bool allow_trailing_junk = true; | 244   const bool allow_trailing_junk = true; | 
| 245   const double empty_string_val = JUNK_STRING_VALUE; | 245   const double empty_string_val = JUNK_STRING_VALUE; | 
| 246 | 246 | 
| 247   if (!AdvanceToNonspace(scanner_constants, ¤t, end)) { | 247   if (!AdvanceToNonspace(unicode_cache, ¤t, end)) { | 
| 248     return empty_string_val; | 248     return empty_string_val; | 
| 249   } | 249   } | 
| 250 | 250 | 
| 251   bool negative = false; | 251   bool negative = false; | 
| 252   bool leading_zero = false; | 252   bool leading_zero = false; | 
| 253 | 253 | 
| 254   if (*current == '+') { | 254   if (*current == '+') { | 
| 255     // Ignore leading sign; skip following spaces. | 255     // Ignore leading sign; skip following spaces. | 
| 256     ++current; | 256     ++current; | 
| 257     if (!AdvanceToNonspace(scanner_constants, ¤t, end)) { | 257     if (!AdvanceToNonspace(unicode_cache, ¤t, end)) { | 
| 258       return JUNK_STRING_VALUE; | 258       return JUNK_STRING_VALUE; | 
| 259     } | 259     } | 
| 260   } else if (*current == '-') { | 260   } else if (*current == '-') { | 
| 261     ++current; | 261     ++current; | 
| 262     if (!AdvanceToNonspace(scanner_constants, ¤t, end)) { | 262     if (!AdvanceToNonspace(unicode_cache, ¤t, end)) { | 
| 263       return JUNK_STRING_VALUE; | 263       return JUNK_STRING_VALUE; | 
| 264     } | 264     } | 
| 265     negative = true; | 265     negative = true; | 
| 266   } | 266   } | 
| 267 | 267 | 
| 268   if (radix == 0) { | 268   if (radix == 0) { | 
| 269     // Radix detection. | 269     // Radix detection. | 
| 270     if (*current == '0') { | 270     if (*current == '0') { | 
| 271       ++current; | 271       ++current; | 
| 272       if (current == end) return SignedZero(negative); | 272       if (current == end) return SignedZero(negative); | 
| (...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 305   } | 305   } | 
| 306 | 306 | 
| 307   if (!leading_zero && !isDigit(*current, radix)) { | 307   if (!leading_zero && !isDigit(*current, radix)) { | 
| 308     return JUNK_STRING_VALUE; | 308     return JUNK_STRING_VALUE; | 
| 309   } | 309   } | 
| 310 | 310 | 
| 311   if (IsPowerOf2(radix)) { | 311   if (IsPowerOf2(radix)) { | 
| 312     switch (radix) { | 312     switch (radix) { | 
| 313       case 2: | 313       case 2: | 
| 314         return InternalStringToIntDouble<1>( | 314         return InternalStringToIntDouble<1>( | 
| 315             scanner_constants, current, end, negative, allow_trailing_junk); | 315             unicode_cache, current, end, negative, allow_trailing_junk); | 
| 316       case 4: | 316       case 4: | 
| 317         return InternalStringToIntDouble<2>( | 317         return InternalStringToIntDouble<2>( | 
| 318             scanner_constants, current, end, negative, allow_trailing_junk); | 318             unicode_cache, current, end, negative, allow_trailing_junk); | 
| 319       case 8: | 319       case 8: | 
| 320         return InternalStringToIntDouble<3>( | 320         return InternalStringToIntDouble<3>( | 
| 321             scanner_constants, current, end, negative, allow_trailing_junk); | 321             unicode_cache, current, end, negative, allow_trailing_junk); | 
| 322 | 322 | 
| 323       case 16: | 323       case 16: | 
| 324         return InternalStringToIntDouble<4>( | 324         return InternalStringToIntDouble<4>( | 
| 325             scanner_constants, current, end, negative, allow_trailing_junk); | 325             unicode_cache, current, end, negative, allow_trailing_junk); | 
| 326 | 326 | 
| 327       case 32: | 327       case 32: | 
| 328         return InternalStringToIntDouble<5>( | 328         return InternalStringToIntDouble<5>( | 
| 329             scanner_constants, current, end, negative, allow_trailing_junk); | 329             unicode_cache, current, end, negative, allow_trailing_junk); | 
| 330       default: | 330       default: | 
| 331         UNREACHABLE(); | 331         UNREACHABLE(); | 
| 332     } | 332     } | 
| 333   } | 333   } | 
| 334 | 334 | 
| 335   if (radix == 10) { | 335   if (radix == 10) { | 
| 336     // Parsing with strtod. | 336     // Parsing with strtod. | 
| 337     const int kMaxSignificantDigits = 309;  // Doubles are less than 1.8e308. | 337     const int kMaxSignificantDigits = 309;  // Doubles are less than 1.8e308. | 
| 338     // The buffer may contain up to kMaxSignificantDigits + 1 digits and a zero | 338     // The buffer may contain up to kMaxSignificantDigits + 1 digits and a zero | 
| 339     // end. | 339     // end. | 
| 340     const int kBufferSize = kMaxSignificantDigits + 2; | 340     const int kBufferSize = kMaxSignificantDigits + 2; | 
| 341     char buffer[kBufferSize]; | 341     char buffer[kBufferSize]; | 
| 342     int buffer_pos = 0; | 342     int buffer_pos = 0; | 
| 343     while (*current >= '0' && *current <= '9') { | 343     while (*current >= '0' && *current <= '9') { | 
| 344       if (buffer_pos <= kMaxSignificantDigits) { | 344       if (buffer_pos <= kMaxSignificantDigits) { | 
| 345         // If the number has more than kMaxSignificantDigits it will be parsed | 345         // If the number has more than kMaxSignificantDigits it will be parsed | 
| 346         // as infinity. | 346         // as infinity. | 
| 347         ASSERT(buffer_pos < kBufferSize); | 347         ASSERT(buffer_pos < kBufferSize); | 
| 348         buffer[buffer_pos++] = static_cast<char>(*current); | 348         buffer[buffer_pos++] = static_cast<char>(*current); | 
| 349       } | 349       } | 
| 350       ++current; | 350       ++current; | 
| 351       if (current == end) break; | 351       if (current == end) break; | 
| 352     } | 352     } | 
| 353 | 353 | 
| 354     if (!allow_trailing_junk && | 354     if (!allow_trailing_junk && | 
| 355         AdvanceToNonspace(scanner_constants, ¤t, end)) { | 355         AdvanceToNonspace(unicode_cache, ¤t, end)) { | 
| 356       return JUNK_STRING_VALUE; | 356       return JUNK_STRING_VALUE; | 
| 357     } | 357     } | 
| 358 | 358 | 
| 359     ASSERT(buffer_pos < kBufferSize); | 359     ASSERT(buffer_pos < kBufferSize); | 
| 360     buffer[buffer_pos] = '\0'; | 360     buffer[buffer_pos] = '\0'; | 
| 361     Vector<const char> buffer_vector(buffer, buffer_pos); | 361     Vector<const char> buffer_vector(buffer, buffer_pos); | 
| 362     return negative ? -Strtod(buffer_vector, 0) : Strtod(buffer_vector, 0); | 362     return negative ? -Strtod(buffer_vector, 0) : Strtod(buffer_vector, 0); | 
| 363   } | 363   } | 
| 364 | 364 | 
| 365   // The following code causes accumulating rounding error for numbers greater | 365   // The following code causes accumulating rounding error for numbers greater | 
| (...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 411         done = true; | 411         done = true; | 
| 412         break; | 412         break; | 
| 413       } | 413       } | 
| 414     } | 414     } | 
| 415 | 415 | 
| 416     // Update the value and skip the part in the string. | 416     // Update the value and skip the part in the string. | 
| 417     v = v * multiplier + part; | 417     v = v * multiplier + part; | 
| 418   } while (!done); | 418   } while (!done); | 
| 419 | 419 | 
| 420   if (!allow_trailing_junk && | 420   if (!allow_trailing_junk && | 
| 421       AdvanceToNonspace(scanner_constants, ¤t, end)) { | 421       AdvanceToNonspace(unicode_cache, ¤t, end)) { | 
| 422     return JUNK_STRING_VALUE; | 422     return JUNK_STRING_VALUE; | 
| 423   } | 423   } | 
| 424 | 424 | 
| 425   return negative ? -v : v; | 425   return negative ? -v : v; | 
| 426 } | 426 } | 
| 427 | 427 | 
| 428 | 428 | 
| 429 // Converts a string to a double value. Assumes the Iterator supports | 429 // Converts a string to a double value. Assumes the Iterator supports | 
| 430 // the following operations: | 430 // the following operations: | 
| 431 // 1. current == end (other ops are not allowed), current != end. | 431 // 1. current == end (other ops are not allowed), current != end. | 
| 432 // 2. *current - gets the current character in the sequence. | 432 // 2. *current - gets the current character in the sequence. | 
| 433 // 3. ++current (advances the position). | 433 // 3. ++current (advances the position). | 
| 434 template <class Iterator, class EndMark> | 434 template <class Iterator, class EndMark> | 
| 435 static double InternalStringToDouble(ScannerConstants* scanner_constants, | 435 static double InternalStringToDouble(UnicodeCache* unicode_cache, | 
| 436                                      Iterator current, | 436                                      Iterator current, | 
| 437                                      EndMark end, | 437                                      EndMark end, | 
| 438                                      int flags, | 438                                      int flags, | 
| 439                                      double empty_string_val) { | 439                                      double empty_string_val) { | 
| 440   // To make sure that iterator dereferencing is valid the following | 440   // To make sure that iterator dereferencing is valid the following | 
| 441   // convention is used: | 441   // convention is used: | 
| 442   // 1. Each '++current' statement is followed by check for equality to 'end'. | 442   // 1. Each '++current' statement is followed by check for equality to 'end'. | 
| 443   // 2. If AdvanceToNonspace returned false then current == end. | 443   // 2. If AdvanceToNonspace returned false then current == end. | 
| 444   // 3. If 'current' becomes be equal to 'end' the function returns or goes to | 444   // 3. If 'current' becomes be equal to 'end' the function returns or goes to | 
| 445   // 'parsing_done'. | 445   // 'parsing_done'. | 
| 446   // 4. 'current' is not dereferenced after the 'parsing_done' label. | 446   // 4. 'current' is not dereferenced after the 'parsing_done' label. | 
| 447   // 5. Code before 'parsing_done' may rely on 'current != end'. | 447   // 5. Code before 'parsing_done' may rely on 'current != end'. | 
| 448   if (!AdvanceToNonspace(scanner_constants, ¤t, end)) { | 448   if (!AdvanceToNonspace(unicode_cache, ¤t, end)) { | 
| 449     return empty_string_val; | 449     return empty_string_val; | 
| 450   } | 450   } | 
| 451 | 451 | 
| 452   const bool allow_trailing_junk = (flags & ALLOW_TRAILING_JUNK) != 0; | 452   const bool allow_trailing_junk = (flags & ALLOW_TRAILING_JUNK) != 0; | 
| 453 | 453 | 
| 454   // The longest form of simplified number is: "-<significant digits>'.1eXXX\0". | 454   // The longest form of simplified number is: "-<significant digits>'.1eXXX\0". | 
| 455   const int kBufferSize = kMaxSignificantDigits + 10; | 455   const int kBufferSize = kMaxSignificantDigits + 10; | 
| 456   char buffer[kBufferSize];  // NOLINT: size is known at compile time. | 456   char buffer[kBufferSize];  // NOLINT: size is known at compile time. | 
| 457   int buffer_pos = 0; | 457   int buffer_pos = 0; | 
| 458 | 458 | 
| (...skipping 17 matching lines...) Expand all  Loading... | 
| 476     negative = true; | 476     negative = true; | 
| 477   } | 477   } | 
| 478 | 478 | 
| 479   static const char kInfinitySymbol[] = "Infinity"; | 479   static const char kInfinitySymbol[] = "Infinity"; | 
| 480   if (*current == kInfinitySymbol[0]) { | 480   if (*current == kInfinitySymbol[0]) { | 
| 481     if (!SubStringEquals(¤t, end, kInfinitySymbol)) { | 481     if (!SubStringEquals(¤t, end, kInfinitySymbol)) { | 
| 482       return JUNK_STRING_VALUE; | 482       return JUNK_STRING_VALUE; | 
| 483     } | 483     } | 
| 484 | 484 | 
| 485     if (!allow_trailing_junk && | 485     if (!allow_trailing_junk && | 
| 486         AdvanceToNonspace(scanner_constants, ¤t, end)) { | 486         AdvanceToNonspace(unicode_cache, ¤t, end)) { | 
| 487       return JUNK_STRING_VALUE; | 487       return JUNK_STRING_VALUE; | 
| 488     } | 488     } | 
| 489 | 489 | 
| 490     ASSERT(buffer_pos == 0); | 490     ASSERT(buffer_pos == 0); | 
| 491     return negative ? -V8_INFINITY : V8_INFINITY; | 491     return negative ? -V8_INFINITY : V8_INFINITY; | 
| 492   } | 492   } | 
| 493 | 493 | 
| 494   bool leading_zero = false; | 494   bool leading_zero = false; | 
| 495   if (*current == '0') { | 495   if (*current == '0') { | 
| 496     ++current; | 496     ++current; | 
| 497     if (current == end) return SignedZero(negative); | 497     if (current == end) return SignedZero(negative); | 
| 498 | 498 | 
| 499     leading_zero = true; | 499     leading_zero = true; | 
| 500 | 500 | 
| 501     // It could be hexadecimal value. | 501     // It could be hexadecimal value. | 
| 502     if ((flags & ALLOW_HEX) && (*current == 'x' || *current == 'X')) { | 502     if ((flags & ALLOW_HEX) && (*current == 'x' || *current == 'X')) { | 
| 503       ++current; | 503       ++current; | 
| 504       if (current == end || !isDigit(*current, 16)) { | 504       if (current == end || !isDigit(*current, 16)) { | 
| 505         return JUNK_STRING_VALUE;  // "0x". | 505         return JUNK_STRING_VALUE;  // "0x". | 
| 506       } | 506       } | 
| 507 | 507 | 
| 508       return InternalStringToIntDouble<4>(scanner_constants, | 508       return InternalStringToIntDouble<4>(unicode_cache, | 
| 509                                           current, | 509                                           current, | 
| 510                                           end, | 510                                           end, | 
| 511                                           negative, | 511                                           negative, | 
| 512                                           allow_trailing_junk); | 512                                           allow_trailing_junk); | 
| 513     } | 513     } | 
| 514 | 514 | 
| 515     // Ignore leading zeros in the integer part. | 515     // Ignore leading zeros in the integer part. | 
| 516     while (*current == '0') { | 516     while (*current == '0') { | 
| 517       ++current; | 517       ++current; | 
| 518       if (current == end) return SignedZero(negative); | 518       if (current == end) return SignedZero(negative); | 
| (...skipping 117 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 636       } else { | 636       } else { | 
| 637         num = num * 10 + digit; | 637         num = num * 10 + digit; | 
| 638       } | 638       } | 
| 639       ++current; | 639       ++current; | 
| 640     } while (current != end && *current >= '0' && *current <= '9'); | 640     } while (current != end && *current >= '0' && *current <= '9'); | 
| 641 | 641 | 
| 642     exponent += (sign == '-' ? -num : num); | 642     exponent += (sign == '-' ? -num : num); | 
| 643   } | 643   } | 
| 644 | 644 | 
| 645   if (!allow_trailing_junk && | 645   if (!allow_trailing_junk && | 
| 646       AdvanceToNonspace(scanner_constants, ¤t, end)) { | 646       AdvanceToNonspace(unicode_cache, ¤t, end)) { | 
| 647     return JUNK_STRING_VALUE; | 647     return JUNK_STRING_VALUE; | 
| 648   } | 648   } | 
| 649 | 649 | 
| 650   parsing_done: | 650   parsing_done: | 
| 651   exponent += insignificant_digits; | 651   exponent += insignificant_digits; | 
| 652 | 652 | 
| 653   if (octal) { | 653   if (octal) { | 
| 654     return InternalStringToIntDouble<3>(scanner_constants, | 654     return InternalStringToIntDouble<3>(unicode_cache, | 
| 655                                         buffer, | 655                                         buffer, | 
| 656                                         buffer + buffer_pos, | 656                                         buffer + buffer_pos, | 
| 657                                         negative, | 657                                         negative, | 
| 658                                         allow_trailing_junk); | 658                                         allow_trailing_junk); | 
| 659   } | 659   } | 
| 660 | 660 | 
| 661   if (nonzero_digit_dropped) { | 661   if (nonzero_digit_dropped) { | 
| 662     buffer[buffer_pos++] = '1'; | 662     buffer[buffer_pos++] = '1'; | 
| 663     exponent--; | 663     exponent--; | 
| 664   } | 664   } | 
| 665 | 665 | 
| 666   ASSERT(buffer_pos < kBufferSize); | 666   ASSERT(buffer_pos < kBufferSize); | 
| 667   buffer[buffer_pos] = '\0'; | 667   buffer[buffer_pos] = '\0'; | 
| 668 | 668 | 
| 669   double converted = Strtod(Vector<const char>(buffer, buffer_pos), exponent); | 669   double converted = Strtod(Vector<const char>(buffer, buffer_pos), exponent); | 
| 670   return negative ? -converted : converted; | 670   return negative ? -converted : converted; | 
| 671 } | 671 } | 
| 672 | 672 | 
| 673 | 673 | 
| 674 double StringToDouble(String* str, int flags, double empty_string_val) { | 674 double StringToDouble(UnicodeCache* unicode_cache, | 
| 675   ScannerConstants* scanner_constants = | 675                       String* str, int flags, double empty_string_val) { | 
| 676       Isolate::Current()->scanner_constants(); |  | 
| 677   StringShape shape(str); | 676   StringShape shape(str); | 
| 678   if (shape.IsSequentialAscii()) { | 677   if (shape.IsSequentialAscii()) { | 
| 679     const char* begin = SeqAsciiString::cast(str)->GetChars(); | 678     const char* begin = SeqAsciiString::cast(str)->GetChars(); | 
| 680     const char* end = begin + str->length(); | 679     const char* end = begin + str->length(); | 
| 681     return InternalStringToDouble(scanner_constants, begin, end, flags, | 680     return InternalStringToDouble(unicode_cache, begin, end, flags, | 
| 682                                   empty_string_val); | 681                                   empty_string_val); | 
| 683   } else if (shape.IsSequentialTwoByte()) { | 682   } else if (shape.IsSequentialTwoByte()) { | 
| 684     const uc16* begin = SeqTwoByteString::cast(str)->GetChars(); | 683     const uc16* begin = SeqTwoByteString::cast(str)->GetChars(); | 
| 685     const uc16* end = begin + str->length(); | 684     const uc16* end = begin + str->length(); | 
| 686     return InternalStringToDouble(scanner_constants, begin, end, flags, | 685     return InternalStringToDouble(unicode_cache, begin, end, flags, | 
| 687                                   empty_string_val); | 686                                   empty_string_val); | 
| 688   } else { | 687   } else { | 
| 689     StringInputBuffer buffer(str); | 688     StringInputBuffer buffer(str); | 
| 690     return InternalStringToDouble(scanner_constants, | 689     return InternalStringToDouble(unicode_cache, | 
| 691                                   StringInputBufferIterator(&buffer), | 690                                   StringInputBufferIterator(&buffer), | 
| 692                                   StringInputBufferIterator::EndMarker(), | 691                                   StringInputBufferIterator::EndMarker(), | 
| 693                                   flags, | 692                                   flags, | 
| 694                                   empty_string_val); | 693                                   empty_string_val); | 
| 695   } | 694   } | 
| 696 } | 695 } | 
| 697 | 696 | 
| 698 | 697 | 
| 699 double StringToInt(String* str, int radix) { | 698 double StringToInt(UnicodeCache* unicode_cache, | 
| 700   ScannerConstants* scanner_constants = | 699                    String* str, | 
| 701       Isolate::Current()->scanner_constants(); | 700                    int radix) { | 
| 702   StringShape shape(str); | 701   StringShape shape(str); | 
| 703   if (shape.IsSequentialAscii()) { | 702   if (shape.IsSequentialAscii()) { | 
| 704     const char* begin = SeqAsciiString::cast(str)->GetChars(); | 703     const char* begin = SeqAsciiString::cast(str)->GetChars(); | 
| 705     const char* end = begin + str->length(); | 704     const char* end = begin + str->length(); | 
| 706     return InternalStringToInt(scanner_constants, begin, end, radix); | 705     return InternalStringToInt(unicode_cache, begin, end, radix); | 
| 707   } else if (shape.IsSequentialTwoByte()) { | 706   } else if (shape.IsSequentialTwoByte()) { | 
| 708     const uc16* begin = SeqTwoByteString::cast(str)->GetChars(); | 707     const uc16* begin = SeqTwoByteString::cast(str)->GetChars(); | 
| 709     const uc16* end = begin + str->length(); | 708     const uc16* end = begin + str->length(); | 
| 710     return InternalStringToInt(scanner_constants, begin, end, radix); | 709     return InternalStringToInt(unicode_cache, begin, end, radix); | 
| 711   } else { | 710   } else { | 
| 712     StringInputBuffer buffer(str); | 711     StringInputBuffer buffer(str); | 
| 713     return InternalStringToInt(scanner_constants, | 712     return InternalStringToInt(unicode_cache, | 
| 714                                StringInputBufferIterator(&buffer), | 713                                StringInputBufferIterator(&buffer), | 
| 715                                StringInputBufferIterator::EndMarker(), | 714                                StringInputBufferIterator::EndMarker(), | 
| 716                                radix); | 715                                radix); | 
| 717   } | 716   } | 
| 718 } | 717 } | 
| 719 | 718 | 
| 720 | 719 | 
| 721 double StringToDouble(const char* str, int flags, double empty_string_val) { | 720 double StringToDouble(UnicodeCache* unicode_cache, | 
| 722   ScannerConstants* scanner_constants = | 721                       const char* str, int flags, double empty_string_val) { | 
| 723       Isolate::Current()->scanner_constants(); |  | 
| 724   const char* end = str + StrLength(str); | 722   const char* end = str + StrLength(str); | 
| 725   return InternalStringToDouble(scanner_constants, str, end, flags, | 723   return InternalStringToDouble(unicode_cache, str, end, flags, | 
| 726                                 empty_string_val); | 724                                 empty_string_val); | 
| 727 } | 725 } | 
| 728 | 726 | 
| 729 | 727 | 
| 730 double StringToDouble(Vector<const char> str, | 728 double StringToDouble(UnicodeCache* unicode_cache, | 
|  | 729                       Vector<const char> str, | 
| 731                       int flags, | 730                       int flags, | 
| 732                       double empty_string_val) { | 731                       double empty_string_val) { | 
| 733   ScannerConstants* scanner_constants = |  | 
| 734       Isolate::Current()->scanner_constants(); |  | 
| 735   const char* end = str.start() + str.length(); | 732   const char* end = str.start() + str.length(); | 
| 736   return InternalStringToDouble(scanner_constants, str.start(), end, flags, | 733   return InternalStringToDouble(unicode_cache, str.start(), end, flags, | 
| 737                                 empty_string_val); | 734                                 empty_string_val); | 
| 738 } | 735 } | 
| 739 | 736 | 
| 740 | 737 | 
| 741 const char* DoubleToCString(double v, Vector<char> buffer) { | 738 const char* DoubleToCString(double v, Vector<char> buffer) { | 
| 742   switch (fpclassify(v)) { | 739   switch (fpclassify(v)) { | 
| 743     case FP_NAN: return "NaN"; | 740     case FP_NAN: return "NaN"; | 
| 744     case FP_INFINITE: return (v < 0.0 ? "-Infinity" : "Infinity"); | 741     case FP_INFINITE: return (v < 0.0 ? "-Infinity" : "Infinity"); | 
| 745     case FP_ZERO: return "0"; | 742     case FP_ZERO: return "0"; | 
| 746     default: { | 743     default: { | 
| (...skipping 369 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 1116   (n == 0 ? v8::internal::dtoa_lock_zero : v8::internal::dtoa_lock_one)->Lock(); | 1113   (n == 0 ? v8::internal::dtoa_lock_zero : v8::internal::dtoa_lock_one)->Lock(); | 
| 1117 } | 1114 } | 
| 1118 | 1115 | 
| 1119 | 1116 | 
| 1120 void FREE_DTOA_LOCK(int n) { | 1117 void FREE_DTOA_LOCK(int n) { | 
| 1121   ASSERT(n == 0 || n == 1); | 1118   ASSERT(n == 0 || n == 1); | 
| 1122   (n == 0 ? v8::internal::dtoa_lock_zero : v8::internal::dtoa_lock_one)-> | 1119   (n == 0 ? v8::internal::dtoa_lock_zero : v8::internal::dtoa_lock_one)-> | 
| 1123       Unlock(); | 1120       Unlock(); | 
| 1124 } | 1121 } | 
| 1125 } | 1122 } | 
| OLD | NEW | 
|---|