OLD | NEW |
---|---|
1 // Copyright 2011 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 |
(...skipping 441 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
452 char buffer[kBufferSize]; // NOLINT: size is known at compile time. | 452 char buffer[kBufferSize]; // NOLINT: size is known at compile time. |
453 int buffer_pos = 0; | 453 int buffer_pos = 0; |
454 | 454 |
455 // Exponent will be adjusted if insignificant digits of the integer part | 455 // Exponent will be adjusted if insignificant digits of the integer part |
456 // or insignificant leading zeros of the fractional part are dropped. | 456 // or insignificant leading zeros of the fractional part are dropped. |
457 int exponent = 0; | 457 int exponent = 0; |
458 int significant_digits = 0; | 458 int significant_digits = 0; |
459 int insignificant_digits = 0; | 459 int insignificant_digits = 0; |
460 bool nonzero_digit_dropped = false; | 460 bool nonzero_digit_dropped = false; |
461 | 461 |
462 bool negative = false; | 462 enum Sign { |
463 POSITIVE, | |
464 NEGATIVE, | |
465 EXPLICIT_POSITIVE | |
rossberg
2012/07/23 09:59:20
For symmetry, I'd call this POSITIVE, and the othe
| |
466 }; | |
467 | |
468 Sign sign = POSITIVE; | |
463 | 469 |
464 if (*current == '+') { | 470 if (*current == '+') { |
465 // Ignore leading sign. | 471 // Ignore leading sign. |
466 ++current; | 472 ++current; |
467 if (current == end) return JunkStringValue(); | 473 if (current == end) return JunkStringValue(); |
474 sign = EXPLICIT_POSITIVE; | |
468 } else if (*current == '-') { | 475 } else if (*current == '-') { |
469 ++current; | 476 ++current; |
470 if (current == end) return JunkStringValue(); | 477 if (current == end) return JunkStringValue(); |
471 negative = true; | 478 sign = NEGATIVE; |
472 } | 479 } |
473 | 480 |
474 static const char kInfinitySymbol[] = "Infinity"; | 481 static const char kInfinitySymbol[] = "Infinity"; |
475 if (*current == kInfinitySymbol[0]) { | 482 if (*current == kInfinitySymbol[0]) { |
476 if (!SubStringEquals(¤t, end, kInfinitySymbol)) { | 483 if (!SubStringEquals(¤t, end, kInfinitySymbol)) { |
477 return JunkStringValue(); | 484 return JunkStringValue(); |
478 } | 485 } |
479 | 486 |
480 if (!allow_trailing_junk && | 487 if (!allow_trailing_junk && |
481 AdvanceToNonspace(unicode_cache, ¤t, end)) { | 488 AdvanceToNonspace(unicode_cache, ¤t, end)) { |
482 return JunkStringValue(); | 489 return JunkStringValue(); |
483 } | 490 } |
484 | 491 |
485 ASSERT(buffer_pos == 0); | 492 ASSERT(buffer_pos == 0); |
486 return negative ? -V8_INFINITY : V8_INFINITY; | 493 return (sign == NEGATIVE) ? -V8_INFINITY : V8_INFINITY; |
487 } | 494 } |
488 | 495 |
489 bool leading_zero = false; | 496 bool leading_zero = false; |
490 if (*current == '0') { | 497 if (*current == '0') { |
491 ++current; | 498 ++current; |
492 if (current == end) return SignedZero(negative); | 499 if (current == end) return SignedZero(sign == NEGATIVE); |
493 | 500 |
494 leading_zero = true; | 501 leading_zero = true; |
495 | 502 |
496 // It could be hexadecimal value. | 503 // It could be hexadecimal value. |
497 if ((flags & ALLOW_HEX) && (*current == 'x' || *current == 'X')) { | 504 if ((flags & ALLOW_HEX) && (*current == 'x' || *current == 'X')) { |
498 ++current; | 505 ++current; |
499 if (current == end || !isDigit(*current, 16)) { | 506 if (current == end || !isDigit(*current, 16) || sign != POSITIVE) { |
500 return JunkStringValue(); // "0x". | 507 return JunkStringValue(); // "0x". |
501 } | 508 } |
502 | 509 |
503 return InternalStringToIntDouble<4>(unicode_cache, | 510 return InternalStringToIntDouble<4>(unicode_cache, |
504 current, | 511 current, |
505 end, | 512 end, |
506 negative, | 513 false, |
507 allow_trailing_junk); | 514 allow_trailing_junk); |
508 } | 515 } |
509 | 516 |
510 // Ignore leading zeros in the integer part. | 517 // Ignore leading zeros in the integer part. |
511 while (*current == '0') { | 518 while (*current == '0') { |
512 ++current; | 519 ++current; |
513 if (current == end) return SignedZero(negative); | 520 if (current == end) return SignedZero(sign == NEGATIVE); |
514 } | 521 } |
515 } | 522 } |
516 | 523 |
517 bool octal = leading_zero && (flags & ALLOW_OCTALS) != 0; | 524 bool octal = leading_zero && (flags & ALLOW_OCTALS) != 0; |
518 | 525 |
519 // Copy significant digits of the integer part (if any) to the buffer. | 526 // Copy significant digits of the integer part (if any) to the buffer. |
520 while (*current >= '0' && *current <= '9') { | 527 while (*current >= '0' && *current <= '9') { |
521 if (significant_digits < kMaxSignificantDigits) { | 528 if (significant_digits < kMaxSignificantDigits) { |
522 ASSERT(buffer_pos < kBufferSize); | 529 ASSERT(buffer_pos < kBufferSize); |
523 buffer[buffer_pos++] = static_cast<char>(*current); | 530 buffer[buffer_pos++] = static_cast<char>(*current); |
(...skipping 24 matching lines...) Expand all Loading... | |
548 goto parsing_done; | 555 goto parsing_done; |
549 } | 556 } |
550 } | 557 } |
551 | 558 |
552 if (significant_digits == 0) { | 559 if (significant_digits == 0) { |
553 // octal = false; | 560 // octal = false; |
554 // Integer part consists of 0 or is absent. Significant digits start after | 561 // Integer part consists of 0 or is absent. Significant digits start after |
555 // leading zeros (if any). | 562 // leading zeros (if any). |
556 while (*current == '0') { | 563 while (*current == '0') { |
557 ++current; | 564 ++current; |
558 if (current == end) return SignedZero(negative); | 565 if (current == end) return SignedZero(sign == NEGATIVE); |
559 exponent--; // Move this 0 into the exponent. | 566 exponent--; // Move this 0 into the exponent. |
560 } | 567 } |
561 } | 568 } |
562 | 569 |
563 // There is a fractional part. We don't emit a '.', but adjust the exponent | 570 // There is a fractional part. We don't emit a '.', but adjust the exponent |
564 // instead. | 571 // instead. |
565 while (*current >= '0' && *current <= '9') { | 572 while (*current >= '0' && *current <= '9') { |
566 if (significant_digits < kMaxSignificantDigits) { | 573 if (significant_digits < kMaxSignificantDigits) { |
567 ASSERT(buffer_pos < kBufferSize); | 574 ASSERT(buffer_pos < kBufferSize); |
568 buffer[buffer_pos++] = static_cast<char>(*current); | 575 buffer[buffer_pos++] = static_cast<char>(*current); |
(...skipping 71 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
640 return JunkStringValue(); | 647 return JunkStringValue(); |
641 } | 648 } |
642 | 649 |
643 parsing_done: | 650 parsing_done: |
644 exponent += insignificant_digits; | 651 exponent += insignificant_digits; |
645 | 652 |
646 if (octal) { | 653 if (octal) { |
647 return InternalStringToIntDouble<3>(unicode_cache, | 654 return InternalStringToIntDouble<3>(unicode_cache, |
648 buffer, | 655 buffer, |
649 buffer + buffer_pos, | 656 buffer + buffer_pos, |
650 negative, | 657 sign == NEGATIVE, |
651 allow_trailing_junk); | 658 allow_trailing_junk); |
652 } | 659 } |
653 | 660 |
654 if (nonzero_digit_dropped) { | 661 if (nonzero_digit_dropped) { |
655 buffer[buffer_pos++] = '1'; | 662 buffer[buffer_pos++] = '1'; |
656 exponent--; | 663 exponent--; |
657 } | 664 } |
658 | 665 |
659 ASSERT(buffer_pos < kBufferSize); | 666 ASSERT(buffer_pos < kBufferSize); |
660 buffer[buffer_pos] = '\0'; | 667 buffer[buffer_pos] = '\0'; |
661 | 668 |
662 double converted = Strtod(Vector<const char>(buffer, buffer_pos), exponent); | 669 double converted = Strtod(Vector<const char>(buffer, buffer_pos), exponent); |
663 return negative ? -converted : converted; | 670 return (sign == NEGATIVE) ? -converted : converted; |
664 } | 671 } |
665 | 672 |
666 } } // namespace v8::internal | 673 } } // namespace v8::internal |
667 | 674 |
668 #endif // V8_CONVERSIONS_INL_H_ | 675 #endif // V8_CONVERSIONS_INL_H_ |
OLD | NEW |