23
23
#include " src/strings/char-predicates-inl.h"
24
24
#include " src/utils/allocation.h"
25
25
26
+ #define FASTFLOAT_ALLOWS_LEADING_PLUS
27
+
28
+ #include " third_party/fast_float/src/include/fast_float/fast_float.h"
29
+ #include " third_party/fast_float/src/include/fast_float/float_common.h"
30
+
26
31
#if defined(_STLP_VENDOR_CSTD)
27
32
// STLPort doesn't import fpclassify into the std namespace.
28
33
#define FPCLASSIFY_NAMESPACE
@@ -689,197 +694,63 @@ double InternalStringToDouble(const Char* current, const Char* end,
689
694
690
695
// From here we are parsing a StrDecimalLiteral, as per
691
696
// https://tc39.es/ecma262/#sec-tonumber-applied-to-the-string-type
692
-
693
697
const bool allow_trailing_junk = flag == ALLOW_TRAILING_JUNK;
694
698
695
- // Maximum number of significant digits in decimal representation.
696
- // The longest possible double in decimal representation is
697
- // (2^53 - 1) * 2 ^ -1074 that is (2 ^ 53 - 1) * 5 ^ 1074 / 10 ^ 1074
698
- // (768 digits). If we parse a number whose first digits are equal to a
699
- // mean of 2 adjacent doubles (that could have up to 769 digits) the result
700
- // must be rounded to the bigger one unless the tail consists of zeros, so
701
- // we don't need to preserve all the digits.
702
- const int kMaxSignificantDigits = 772 ;
703
-
704
- // The longest form of simplified number is: "-<significant digits>'.1eXXX\0".
705
- const int kBufferSize = kMaxSignificantDigits + 10 ;
706
- char buffer[kBufferSize ];
707
- int buffer_pos = 0 ;
708
-
709
- // Exponent will be adjusted if insignificant digits of the integer part
710
- // or insignificant leading zeros of the fractional part are dropped.
711
- int exponent = 0 ;
712
- int significant_digits = 0 ;
713
- int insignificant_digits = 0 ;
714
- bool nonzero_digit_dropped = false ;
715
-
716
- enum class Sign { kNone , kNegative , kPositive };
717
-
718
- Sign sign = Sign::kNone ;
719
-
720
- if (*current == ' +' ) {
721
- // Ignore leading sign.
722
- ++current;
723
- if (current == end) return JunkStringValue ();
724
- sign = Sign::kPositive ;
725
- } else if (*current == ' -' ) {
726
- ++current;
727
- if (current == end) return JunkStringValue ();
728
- sign = Sign::kNegative ;
729
- }
730
-
731
- static const char kInfinityString [] = " Infinity" ;
732
- if (*current == kInfinityString [0 ]) {
733
- if (!SubStringEquals (¤t, end, kInfinityString )) {
734
- return JunkStringValue ();
735
- }
736
-
699
+ double value;
700
+ // fast_float takes a char/char16_t instead of a uint8_t/uint16_t. Cast the
701
+ // pointers to match.
702
+ using UC = std::conditional_t <std::is_same_v<Char, uint8_t >, char , char16_t >;
703
+ static_assert (sizeof (UC) == sizeof (Char));
704
+ const UC* current_uc = reinterpret_cast <const UC*>(current);
705
+ const UC* end_uc = reinterpret_cast <const UC*>(end);
706
+ auto ret = fast_float::from_chars (current_uc, end_uc, value,
707
+ static_cast <fast_float::chars_format>(
708
+ fast_float::chars_format::general |
709
+ fast_float::chars_format::no_infnan));
710
+ if (ret.ptr == end_uc) return value;
711
+ if (ret.ptr > current_uc) {
712
+ current = reinterpret_cast <const Char*>(ret.ptr );
737
713
if (!allow_trailing_junk && AdvanceToNonspace (¤t, end)) {
738
714
return JunkStringValue ();
739
715
}
740
-
741
- DCHECK_EQ (buffer_pos, 0 );
742
- return (sign == Sign::kNegative ) ? -V8_INFINITY : V8_INFINITY;
743
- }
744
-
745
- // Ignore leading zeros in the integer part.
746
- bool leading_zero = false ;
747
- if (*current == ' 0' ) {
748
- do {
749
- current++;
750
- if (current == end) return SignedZero (sign == Sign::kNegative );
751
- } while (*current == ' 0' );
752
- leading_zero = true ;
753
- }
754
-
755
- // Copy significant digits of the integer part (if any) to the buffer.
756
- while (*current >= ' 0' && *current <= ' 9' ) {
757
- if (significant_digits < kMaxSignificantDigits ) {
758
- DCHECK_LT (buffer_pos, kBufferSize );
759
- buffer[buffer_pos++] = static_cast <char >(*current);
760
- significant_digits++;
761
- // Will later check if it's an octal in the buffer.
762
- } else {
763
- insignificant_digits++; // Move the digit into the exponential part.
764
- nonzero_digit_dropped = nonzero_digit_dropped || *current != ' 0' ;
765
- }
766
- ++current;
767
- if (current == end) goto parsing_done;
716
+ return value;
768
717
}
769
718
770
- if (*current == ' .' ) {
771
- ++current;
772
- if (current == end) {
773
- if (significant_digits == 0 && !leading_zero) {
719
+ // Failed to parse any number -- handle ±Infinity before giving up.
720
+ DCHECK_EQ (ret.ptr , current_uc);
721
+ DCHECK_NE (current, end);
722
+ static constexpr char kInfinityString [] = " Infinity" ;
723
+ switch (*current) {
724
+ case ' +' :
725
+ // Ignore leading plus sign.
726
+ ++current;
727
+ if (current == end) return JunkStringValue ();
728
+ if (*current != kInfinityString [0 ]) return JunkStringValue ();
729
+ [[fallthrough]];
730
+ case kInfinityString [0 ]:
731
+ if (!SubStringEquals (¤t, end, kInfinityString )) {
774
732
return JunkStringValue ();
775
- } else {
776
- goto parsing_done;
777
733
}
778
- }
779
-
780
- if (significant_digits == 0 ) {
781
- // octal = false;
782
- // Integer part consists of 0 or is absent. Significant digits start after
783
- // leading zeros (if any).
784
- while (*current == ' 0' ) {
785
- ++current;
786
- if (current == end) return SignedZero (sign == Sign::kNegative );
787
- exponent--; // Move this 0 into the exponent.
734
+ if (!allow_trailing_junk && AdvanceToNonspace (¤t, end)) {
735
+ return JunkStringValue ();
788
736
}
789
- }
737
+ return V8_INFINITY;
790
738
791
- // There is a fractional part. We don't emit a '.', but adjust the exponent
792
- // instead.
793
- while (*current >= ' 0' && *current <= ' 9' ) {
794
- if (significant_digits < kMaxSignificantDigits ) {
795
- DCHECK_LT (buffer_pos, kBufferSize );
796
- buffer[buffer_pos++] = static_cast <char >(*current);
797
- significant_digits++;
798
- exponent--;
799
- } else {
800
- // Ignore insignificant digits in the fractional part.
801
- nonzero_digit_dropped = nonzero_digit_dropped || *current != ' 0' ;
802
- }
739
+ case ' -' :
803
740
++current;
804
- if (current == end) goto parsing_done;
805
- }
806
- }
807
-
808
- if (!leading_zero && exponent == 0 && significant_digits == 0 ) {
809
- // If leading_zeros is true then the string contains zeros.
810
- // If exponent < 0 then string was [+-]\.0*...
811
- // If significant_digits != 0 the string is not equal to 0.
812
- // Otherwise there are no digits in the string.
813
- return JunkStringValue ();
814
- }
815
-
816
- // Parse exponential part.
817
- if (*current == ' e' || *current == ' E' ) {
818
- ++current;
819
- if (current == end) {
820
- if (allow_trailing_junk) {
821
- goto parsing_done;
822
- } else {
741
+ if (current == end) return JunkStringValue ();
742
+ if (*current != kInfinityString [0 ]) return JunkStringValue ();
743
+ if (!SubStringEquals (¤t, end, kInfinityString )) {
823
744
return JunkStringValue ();
824
745
}
825
- }
826
- char exponent_sign = ' +' ;
827
- if (*current == ' +' || *current == ' -' ) {
828
- exponent_sign = static_cast <char >(*current);
829
- ++current;
830
- if (current == end) {
831
- if (allow_trailing_junk) {
832
- goto parsing_done;
833
- } else {
834
- return JunkStringValue ();
835
- }
836
- }
837
- }
838
-
839
- if (current == end || *current < ' 0' || *current > ' 9' ) {
840
- if (allow_trailing_junk) {
841
- goto parsing_done;
842
- } else {
746
+ if (!allow_trailing_junk && AdvanceToNonspace (¤t, end)) {
843
747
return JunkStringValue ();
844
748
}
845
- }
846
-
847
- const int max_exponent = INT_MAX / 2 ;
848
- DCHECK (-max_exponent / 2 <= exponent && exponent <= max_exponent / 2 );
849
- int num = 0 ;
850
- do {
851
- // Check overflow.
852
- int digit = *current - ' 0' ;
853
- if (num >= max_exponent / 10 &&
854
- !(num == max_exponent / 10 && digit <= max_exponent % 10 )) {
855
- num = max_exponent;
856
- } else {
857
- num = num * 10 + digit;
858
- }
859
- ++current;
860
- } while (current != end && *current >= ' 0' && *current <= ' 9' );
861
-
862
- exponent += (exponent_sign == ' -' ? -num : num);
863
- }
864
-
865
- if (!allow_trailing_junk && AdvanceToNonspace (¤t, end)) {
866
- return JunkStringValue ();
867
- }
749
+ return -V8_INFINITY;
868
750
869
- parsing_done:
870
- exponent += insignificant_digits;
871
-
872
- if (nonzero_digit_dropped) {
873
- buffer[buffer_pos++] = ' 1' ;
874
- exponent--;
751
+ default :
752
+ return JunkStringValue ();
875
753
}
876
-
877
- SLOW_DCHECK (buffer_pos < kBufferSize );
878
- buffer[buffer_pos] = ' \0 ' ;
879
-
880
- double converted =
881
- Strtod (base::Vector<const char >(buffer, buffer_pos), exponent);
882
- return (sign == Sign::kNegative ) ? -converted : converted;
883
754
}
884
755
885
756
double StringToDouble (const char * str, ConversionFlag flags,
@@ -898,8 +769,8 @@ double StringToDouble(base::Vector<const uint8_t> str, ConversionFlag flags,
898
769
899
770
double StringToDouble (base::Vector<const base::uc16> str, ConversionFlag flags,
900
771
double empty_string_val) {
901
- const base::uc16* end = str.begin () + str.length ();
902
- return InternalStringToDouble (str. begin (), end, flags, empty_string_val);
772
+ return InternalStringToDouble ( str.begin (), str.end (), flags,
773
+ empty_string_val);
903
774
}
904
775
905
776
double BinaryStringToDouble (base::Vector<const uint8_t > str) {
0 commit comments