OLD | NEW |
1 // Copyright 2006-2008 the V8 project authors. All rights reserved. | 1 // Copyright 2006-2008 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 |
(...skipping 359 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
370 const int kBufferSize = kMaxSignificantDigits + 10; | 370 const int kBufferSize = kMaxSignificantDigits + 10; |
371 char buffer[kBufferSize]; // NOLINT: size is known at compile time. | 371 char buffer[kBufferSize]; // NOLINT: size is known at compile time. |
372 int buffer_pos = 0; | 372 int buffer_pos = 0; |
373 | 373 |
374 // Exponent will be adjusted if insignificant digits of the integer part | 374 // Exponent will be adjusted if insignificant digits of the integer part |
375 // or insignificant leading zeros of the fractional part are dropped. | 375 // or insignificant leading zeros of the fractional part are dropped. |
376 int exponent = 0; | 376 int exponent = 0; |
377 int significant_digits = 0; | 377 int significant_digits = 0; |
378 int insignificant_digits = 0; | 378 int insignificant_digits = 0; |
379 bool nonzero_digit_dropped = false; | 379 bool nonzero_digit_dropped = false; |
| 380 bool fractional_part = false; |
380 | 381 |
381 double signed_zero = 0.0; | 382 double signed_zero = 0.0; |
382 | 383 |
383 if (*current == '+') { | 384 if (*current == '+') { |
384 // Ignore leading sign; skip following spaces. | 385 // Ignore leading sign; skip following spaces. |
385 ++current; | 386 ++current; |
386 if (!AdvanceToNonspace(¤t, end)) return JUNK_STRING_VALUE; | 387 if (!AdvanceToNonspace(¤t, end)) return JUNK_STRING_VALUE; |
387 } else if (*current == '-') { | 388 } else if (*current == '-') { |
388 buffer[buffer_pos++] = '-'; | 389 buffer[buffer_pos++] = '-'; |
389 ++current; | 390 ++current; |
(...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
447 octal = octal && *current < '8'; | 448 octal = octal && *current < '8'; |
448 ++current; | 449 ++current; |
449 if (current == end) goto parsing_done; | 450 if (current == end) goto parsing_done; |
450 } | 451 } |
451 | 452 |
452 if (significant_digits == 0) { | 453 if (significant_digits == 0) { |
453 octal = false; | 454 octal = false; |
454 } | 455 } |
455 | 456 |
456 if (*current == '.') { | 457 if (*current == '.') { |
457 ASSERT(buffer_pos < kBufferSize); | |
458 buffer[buffer_pos++] = '.'; | |
459 ++current; | 458 ++current; |
460 if (current == end) { | 459 if (current == end) { |
461 if (significant_digits == 0 && !leading_zero) { | 460 if (significant_digits == 0 && !leading_zero) { |
462 return JUNK_STRING_VALUE; | 461 return JUNK_STRING_VALUE; |
463 } else { | 462 } else { |
464 goto parsing_done; | 463 goto parsing_done; |
465 } | 464 } |
466 } | 465 } |
467 | 466 |
468 if (significant_digits == 0) { | 467 if (significant_digits == 0) { |
469 // octal = false; | 468 // octal = false; |
470 // Integer part consists of 0 or is absent. Significant digits start after | 469 // Integer part consists of 0 or is absent. Significant digits start after |
471 // leading zeros (if any). | 470 // leading zeros (if any). |
472 while (*current == '0') { | 471 while (*current == '0') { |
473 ++current; | 472 ++current; |
474 if (current == end) return signed_zero; | 473 if (current == end) return signed_zero; |
475 exponent--; // Move this 0 into the exponent. | 474 exponent--; // Move this 0 into the exponent. |
476 } | 475 } |
477 } | 476 } |
478 | 477 |
| 478 ASSERT(buffer_pos < kBufferSize); |
| 479 buffer[buffer_pos++] = '.'; |
| 480 fractional_part = true; |
| 481 |
479 // There is the fractional part. | 482 // There is the fractional part. |
480 while (*current >= '0' && *current <= '9') { | 483 while (*current >= '0' && *current <= '9') { |
481 if (significant_digits < kMaxSignificantDigits) { | 484 if (significant_digits < kMaxSignificantDigits) { |
482 ASSERT(buffer_pos < kBufferSize); | 485 ASSERT(buffer_pos < kBufferSize); |
483 buffer[buffer_pos++] = static_cast<char>(*current); | 486 buffer[buffer_pos++] = static_cast<char>(*current); |
484 significant_digits++; | 487 significant_digits++; |
485 } else { | 488 } else { |
486 // Ignore insignificant digits in the fractional part. | 489 // Ignore insignificant digits in the fractional part. |
487 nonzero_digit_dropped = nonzero_digit_dropped || *current != '0'; | 490 nonzero_digit_dropped = nonzero_digit_dropped || *current != '0'; |
488 } | 491 } |
(...skipping 84 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
573 result *= pow(8.0, insignificant_digits); | 576 result *= pow(8.0, insignificant_digits); |
574 } | 577 } |
575 return result; | 578 return result; |
576 } | 579 } |
577 | 580 |
578 if (nonzero_digit_dropped) { | 581 if (nonzero_digit_dropped) { |
579 if (insignificant_digits) buffer[buffer_pos++] = '.'; | 582 if (insignificant_digits) buffer[buffer_pos++] = '.'; |
580 buffer[buffer_pos++] = '1'; | 583 buffer[buffer_pos++] = '1'; |
581 } | 584 } |
582 | 585 |
| 586 // If the number has no more than kMaxDigitsInInt digits and doesn't have |
| 587 // fractional part it could be parsed faster (without checks for |
| 588 // spaces, overflow, etc.). |
| 589 const int kMaxDigitsInInt = 9 * sizeof(int) / 4; // NOLINT |
| 590 |
583 if (exponent != 0) { | 591 if (exponent != 0) { |
584 ASSERT(buffer_pos < kBufferSize); | 592 ASSERT(buffer_pos < kBufferSize); |
585 buffer[buffer_pos++] = 'e'; | 593 buffer[buffer_pos++] = 'e'; |
586 if (exponent < 0) { | 594 if (exponent < 0) { |
587 ASSERT(buffer_pos < kBufferSize); | 595 ASSERT(buffer_pos < kBufferSize); |
588 buffer[buffer_pos++] = '-'; | 596 buffer[buffer_pos++] = '-'; |
589 exponent = -exponent; | 597 exponent = -exponent; |
590 } | 598 } |
591 if (exponent > 999) exponent = 999; // Result will be Infinity or 0 or -0. | 599 if (exponent > 999) exponent = 999; // Result will be Infinity or 0 or -0. |
592 | 600 |
593 const int exp_digits = 3; | 601 const int exp_digits = 3; |
594 for (int i = 0; i < exp_digits; i++) { | 602 for (int i = 0; i < exp_digits; i++) { |
595 buffer[buffer_pos + exp_digits - 1 - i] = '0' + exponent % 10; | 603 buffer[buffer_pos + exp_digits - 1 - i] = '0' + exponent % 10; |
596 exponent /= 10; | 604 exponent /= 10; |
597 } | 605 } |
598 ASSERT(exponent == 0); | 606 ASSERT(exponent == 0); |
599 buffer_pos += exp_digits; | 607 buffer_pos += exp_digits; |
| 608 } else if (!fractional_part && significant_digits <= kMaxDigitsInInt) { |
| 609 if (significant_digits == 0) return signed_zero; |
| 610 ASSERT(buffer_pos > 0); |
| 611 int num = 0; |
| 612 int start_pos = (buffer[0] == '-' ? 1 : 0); |
| 613 for (int i = start_pos; i < buffer_pos; i++) { |
| 614 ASSERT(buffer[i] >= '0' && buffer[i] <= '9'); |
| 615 num = 10 * num + (buffer[i] - '0'); |
| 616 } |
| 617 return static_cast<double>(start_pos == 0 ? num : -num); |
600 } | 618 } |
601 | 619 |
602 ASSERT(buffer_pos < kBufferSize); | 620 ASSERT(buffer_pos < kBufferSize); |
603 buffer[buffer_pos] = '\0'; | 621 buffer[buffer_pos] = '\0'; |
604 | 622 |
605 return gay_strtod(buffer, NULL); | 623 return gay_strtod(buffer, NULL); |
606 } | 624 } |
607 | 625 |
608 double StringToDouble(String* str, int flags, double empty_string_val) { | 626 double StringToDouble(String* str, int flags, double empty_string_val) { |
609 StringShape shape(str); | 627 StringShape shape(str); |
(...skipping 378 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
988 // Allocate result and fill in the parts. | 1006 // Allocate result and fill in the parts. |
989 StringBuilder builder(result_size + 1); | 1007 StringBuilder builder(result_size + 1); |
990 builder.AddSubstring(integer_buffer + integer_pos + 1, integer_part_size); | 1008 builder.AddSubstring(integer_buffer + integer_pos + 1, integer_part_size); |
991 if (decimal_pos > 0) builder.AddCharacter('.'); | 1009 if (decimal_pos > 0) builder.AddCharacter('.'); |
992 builder.AddSubstring(decimal_buffer, decimal_pos); | 1010 builder.AddSubstring(decimal_buffer, decimal_pos); |
993 return builder.Finalize(); | 1011 return builder.Finalize(); |
994 } | 1012 } |
995 | 1013 |
996 | 1014 |
997 } } // namespace v8::internal | 1015 } } // namespace v8::internal |
OLD | NEW |