| 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 636 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 647 | 647 |
| 648 if (nonzero_digit_dropped) { | 648 if (nonzero_digit_dropped) { |
| 649 buffer[buffer_pos++] = '1'; | 649 buffer[buffer_pos++] = '1'; |
| 650 exponent--; | 650 exponent--; |
| 651 } | 651 } |
| 652 | 652 |
| 653 ASSERT(buffer_pos < kBufferSize); | 653 ASSERT(buffer_pos < kBufferSize); |
| 654 buffer[buffer_pos] = '\0'; | 654 buffer[buffer_pos] = '\0'; |
| 655 | 655 |
| 656 double converted = Strtod(Vector<const char>(buffer, buffer_pos), exponent); | 656 double converted = Strtod(Vector<const char>(buffer, buffer_pos), exponent); |
| 657 return sign? -converted: converted; | 657 return sign ? -converted : converted; |
| 658 } | 658 } |
| 659 | 659 |
| 660 | 660 |
| 661 double StringToDouble(String* str, int flags, double empty_string_val) { | 661 double StringToDouble(String* str, int flags, double empty_string_val) { |
| 662 StringShape shape(str); | 662 StringShape shape(str); |
| 663 if (shape.IsSequentialAscii()) { | 663 if (shape.IsSequentialAscii()) { |
| 664 const char* begin = SeqAsciiString::cast(str)->GetChars(); | 664 const char* begin = SeqAsciiString::cast(str)->GetChars(); |
| 665 const char* end = begin + str->length(); | 665 const char* end = begin + str->length(); |
| 666 return InternalStringToDouble(begin, end, flags, empty_string_val); | 666 return InternalStringToDouble(begin, end, flags, empty_string_val); |
| 667 } else if (shape.IsSequentialTwoByte()) { | 667 } else if (shape.IsSequentialTwoByte()) { |
| (...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 704 | 704 |
| 705 | 705 |
| 706 double StringToDouble(Vector<const char> str, | 706 double StringToDouble(Vector<const char> str, |
| 707 int flags, | 707 int flags, |
| 708 double empty_string_val) { | 708 double empty_string_val) { |
| 709 const char* end = str.start() + str.length(); | 709 const char* end = str.start() + str.length(); |
| 710 return InternalStringToDouble(str.start(), end, flags, empty_string_val); | 710 return InternalStringToDouble(str.start(), end, flags, empty_string_val); |
| 711 } | 711 } |
| 712 | 712 |
| 713 | 713 |
| 714 extern "C" char* dtoa(double d, int mode, int ndigits, | |
| 715 int* decpt, int* sign, char** rve); | |
| 716 | |
| 717 extern "C" void freedtoa(char* s); | |
| 718 | |
| 719 const char* DoubleToCString(double v, Vector<char> buffer) { | 714 const char* DoubleToCString(double v, Vector<char> buffer) { |
| 720 StringBuilder builder(buffer.start(), buffer.length()); | 715 StringBuilder builder(buffer.start(), buffer.length()); |
| 721 | 716 |
| 722 switch (fpclassify(v)) { | 717 switch (fpclassify(v)) { |
| 723 case FP_NAN: | 718 case FP_NAN: |
| 724 builder.AddString("NaN"); | 719 builder.AddString("NaN"); |
| 725 break; | 720 break; |
| 726 | 721 |
| 727 case FP_INFINITE: | 722 case FP_INFINITE: |
| 728 if (v < 0.0) { | 723 if (v < 0.0) { |
| 729 builder.AddString("-Infinity"); | 724 builder.AddString("-Infinity"); |
| 730 } else { | 725 } else { |
| 731 builder.AddString("Infinity"); | 726 builder.AddString("Infinity"); |
| 732 } | 727 } |
| 733 break; | 728 break; |
| 734 | 729 |
| 735 case FP_ZERO: | 730 case FP_ZERO: |
| 736 builder.AddCharacter('0'); | 731 builder.AddCharacter('0'); |
| 737 break; | 732 break; |
| 738 | 733 |
| 739 default: { | 734 default: { |
| 740 int decimal_point; | 735 int decimal_point; |
| 741 int sign; | 736 int sign; |
| 742 char* decimal_rep; | |
| 743 bool used_gay_dtoa = false; | |
| 744 const int kV8DtoaBufferCapacity = kBase10MaximalLength + 1; | 737 const int kV8DtoaBufferCapacity = kBase10MaximalLength + 1; |
| 745 char v8_dtoa_buffer[kV8DtoaBufferCapacity]; | 738 char decimal_rep[kV8DtoaBufferCapacity]; |
| 746 int length; | 739 int length; |
| 747 | 740 |
| 748 if (DoubleToAscii(v, DTOA_SHORTEST, 0, | 741 DoubleToAscii(v, DTOA_SHORTEST, 0, |
| 749 Vector<char>(v8_dtoa_buffer, kV8DtoaBufferCapacity), | 742 Vector<char>(decimal_rep, kV8DtoaBufferCapacity), |
| 750 &sign, &length, &decimal_point)) { | 743 &sign, &length, &decimal_point); |
| 751 decimal_rep = v8_dtoa_buffer; | |
| 752 } else { | |
| 753 decimal_rep = dtoa(v, 0, 0, &decimal_point, &sign, NULL); | |
| 754 used_gay_dtoa = true; | |
| 755 length = StrLength(decimal_rep); | |
| 756 } | |
| 757 | 744 |
| 758 if (sign) builder.AddCharacter('-'); | 745 if (sign) builder.AddCharacter('-'); |
| 759 | 746 |
| 760 if (length <= decimal_point && decimal_point <= 21) { | 747 if (length <= decimal_point && decimal_point <= 21) { |
| 761 // ECMA-262 section 9.8.1 step 6. | 748 // ECMA-262 section 9.8.1 step 6. |
| 762 builder.AddString(decimal_rep); | 749 builder.AddString(decimal_rep); |
| 763 builder.AddPadding('0', decimal_point - length); | 750 builder.AddPadding('0', decimal_point - length); |
| 764 | 751 |
| 765 } else if (0 < decimal_point && decimal_point <= 21) { | 752 } else if (0 < decimal_point && decimal_point <= 21) { |
| 766 // ECMA-262 section 9.8.1 step 7. | 753 // ECMA-262 section 9.8.1 step 7. |
| (...skipping 13 matching lines...) Expand all Loading... |
| 780 if (length != 1) { | 767 if (length != 1) { |
| 781 builder.AddCharacter('.'); | 768 builder.AddCharacter('.'); |
| 782 builder.AddString(decimal_rep + 1); | 769 builder.AddString(decimal_rep + 1); |
| 783 } | 770 } |
| 784 builder.AddCharacter('e'); | 771 builder.AddCharacter('e'); |
| 785 builder.AddCharacter((decimal_point >= 0) ? '+' : '-'); | 772 builder.AddCharacter((decimal_point >= 0) ? '+' : '-'); |
| 786 int exponent = decimal_point - 1; | 773 int exponent = decimal_point - 1; |
| 787 if (exponent < 0) exponent = -exponent; | 774 if (exponent < 0) exponent = -exponent; |
| 788 builder.AddFormatted("%d", exponent); | 775 builder.AddFormatted("%d", exponent); |
| 789 } | 776 } |
| 790 | |
| 791 if (used_gay_dtoa) freedtoa(decimal_rep); | |
| 792 } | 777 } |
| 793 } | 778 } |
| 794 return builder.Finalize(); | 779 return builder.Finalize(); |
| 795 } | 780 } |
| 796 | 781 |
| 797 | 782 |
| 798 const char* IntToCString(int n, Vector<char> buffer) { | 783 const char* IntToCString(int n, Vector<char> buffer) { |
| 799 bool negative = false; | 784 bool negative = false; |
| 800 if (n < 0) { | 785 if (n < 0) { |
| 801 // We must not negate the most negative int. | 786 // We must not negate the most negative int. |
| (...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 838 } | 823 } |
| 839 | 824 |
| 840 // Find a sufficiently precise decimal representation of n. | 825 // Find a sufficiently precise decimal representation of n. |
| 841 int decimal_point; | 826 int decimal_point; |
| 842 int sign; | 827 int sign; |
| 843 // Add space for the '\0' byte. | 828 // Add space for the '\0' byte. |
| 844 const int kDecimalRepCapacity = | 829 const int kDecimalRepCapacity = |
| 845 kMaxDigitsBeforePoint + kMaxDigitsAfterPoint + 1; | 830 kMaxDigitsBeforePoint + kMaxDigitsAfterPoint + 1; |
| 846 char decimal_rep[kDecimalRepCapacity]; | 831 char decimal_rep[kDecimalRepCapacity]; |
| 847 int decimal_rep_length; | 832 int decimal_rep_length; |
| 848 bool status = DoubleToAscii(value, DTOA_FIXED, f, | 833 DoubleToAscii(value, DTOA_FIXED, f, |
| 849 Vector<char>(decimal_rep, kDecimalRepCapacity), | 834 Vector<char>(decimal_rep, kDecimalRepCapacity), |
| 850 &sign, &decimal_rep_length, &decimal_point); | 835 &sign, &decimal_rep_length, &decimal_point); |
| 851 USE(status); | |
| 852 ASSERT(status); | |
| 853 | 836 |
| 854 // Create a representation that is padded with zeros if needed. | 837 // Create a representation that is padded with zeros if needed. |
| 855 int zero_prefix_length = 0; | 838 int zero_prefix_length = 0; |
| 856 int zero_postfix_length = 0; | 839 int zero_postfix_length = 0; |
| 857 | 840 |
| 858 if (decimal_point <= 0) { | 841 if (decimal_point <= 0) { |
| 859 zero_prefix_length = -decimal_point + 1; | 842 zero_prefix_length = -decimal_point + 1; |
| 860 decimal_point = 1; | 843 decimal_point = 1; |
| 861 } | 844 } |
| 862 | 845 |
| (...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 928 | 911 |
| 929 bool negative = false; | 912 bool negative = false; |
| 930 if (value < 0) { | 913 if (value < 0) { |
| 931 value = -value; | 914 value = -value; |
| 932 negative = true; | 915 negative = true; |
| 933 } | 916 } |
| 934 | 917 |
| 935 // Find a sufficiently precise decimal representation of n. | 918 // Find a sufficiently precise decimal representation of n. |
| 936 int decimal_point; | 919 int decimal_point; |
| 937 int sign; | 920 int sign; |
| 938 char* decimal_rep = NULL; | |
| 939 bool used_gay_dtoa = false; | |
| 940 // f corresponds to the digits after the point. There is always one digit | 921 // f corresponds to the digits after the point. There is always one digit |
| 941 // before the point. The number of requested_digits equals hence f + 1. | 922 // before the point. The number of requested_digits equals hence f + 1. |
| 942 // And we have to add one character for the null-terminator. | 923 // And we have to add one character for the null-terminator. |
| 943 const int kV8DtoaBufferCapacity = kMaxDigitsAfterPoint + 1 + 1; | 924 const int kV8DtoaBufferCapacity = kMaxDigitsAfterPoint + 1 + 1; |
| 944 // Make sure that the buffer is big enough, even if we fall back to the | 925 // Make sure that the buffer is big enough, even if we fall back to the |
| 945 // shortest representation (which happens when f equals -1). | 926 // shortest representation (which happens when f equals -1). |
| 946 ASSERT(kBase10MaximalLength <= kMaxDigitsAfterPoint + 1); | 927 ASSERT(kBase10MaximalLength <= kMaxDigitsAfterPoint + 1); |
| 947 char v8_dtoa_buffer[kV8DtoaBufferCapacity]; | 928 char decimal_rep[kV8DtoaBufferCapacity]; |
| 948 int decimal_rep_length; | 929 int decimal_rep_length; |
| 949 | 930 |
| 950 if (f == -1) { | 931 if (f == -1) { |
| 951 if (DoubleToAscii(value, DTOA_SHORTEST, 0, | 932 DoubleToAscii(value, DTOA_SHORTEST, 0, |
| 952 Vector<char>(v8_dtoa_buffer, kV8DtoaBufferCapacity), | 933 Vector<char>(decimal_rep, kV8DtoaBufferCapacity), |
| 953 &sign, &decimal_rep_length, &decimal_point)) { | 934 &sign, &decimal_rep_length, &decimal_point); |
| 954 f = decimal_rep_length - 1; | 935 f = decimal_rep_length - 1; |
| 955 decimal_rep = v8_dtoa_buffer; | |
| 956 } else { | |
| 957 decimal_rep = dtoa(value, 0, 0, &decimal_point, &sign, NULL); | |
| 958 decimal_rep_length = StrLength(decimal_rep); | |
| 959 f = decimal_rep_length - 1; | |
| 960 used_gay_dtoa = true; | |
| 961 } | |
| 962 } else { | 936 } else { |
| 963 if (DoubleToAscii(value, DTOA_PRECISION, f + 1, | 937 DoubleToAscii(value, DTOA_PRECISION, f + 1, |
| 964 Vector<char>(v8_dtoa_buffer, kV8DtoaBufferCapacity), | 938 Vector<char>(decimal_rep, kV8DtoaBufferCapacity), |
| 965 &sign, &decimal_rep_length, &decimal_point)) { | 939 &sign, &decimal_rep_length, &decimal_point); |
| 966 decimal_rep = v8_dtoa_buffer; | |
| 967 } else { | |
| 968 decimal_rep = dtoa(value, 2, f + 1, &decimal_point, &sign, NULL); | |
| 969 decimal_rep_length = StrLength(decimal_rep); | |
| 970 used_gay_dtoa = true; | |
| 971 } | |
| 972 } | 940 } |
| 973 ASSERT(decimal_rep_length > 0); | 941 ASSERT(decimal_rep_length > 0); |
| 974 ASSERT(decimal_rep_length <= f + 1); | 942 ASSERT(decimal_rep_length <= f + 1); |
| 975 | 943 |
| 976 int exponent = decimal_point - 1; | 944 int exponent = decimal_point - 1; |
| 977 char* result = | 945 char* result = |
| 978 CreateExponentialRepresentation(decimal_rep, exponent, negative, f+1); | 946 CreateExponentialRepresentation(decimal_rep, exponent, negative, f+1); |
| 979 | 947 |
| 980 if (used_gay_dtoa) { | |
| 981 freedtoa(decimal_rep); | |
| 982 } | |
| 983 | |
| 984 return result; | 948 return result; |
| 985 } | 949 } |
| 986 | 950 |
| 987 | 951 |
| 988 char* DoubleToPrecisionCString(double value, int p) { | 952 char* DoubleToPrecisionCString(double value, int p) { |
| 989 const int kMinimalDigits = 1; | 953 const int kMinimalDigits = 1; |
| 990 const int kMaximalDigits = 21; | 954 const int kMaximalDigits = 21; |
| 991 ASSERT(p >= kMinimalDigits && p <= kMaximalDigits); | 955 ASSERT(p >= kMinimalDigits && p <= kMaximalDigits); |
| 992 USE(kMinimalDigits); | 956 USE(kMinimalDigits); |
| 993 | 957 |
| 994 bool negative = false; | 958 bool negative = false; |
| 995 if (value < 0) { | 959 if (value < 0) { |
| 996 value = -value; | 960 value = -value; |
| 997 negative = true; | 961 negative = true; |
| 998 } | 962 } |
| 999 | 963 |
| 1000 // Find a sufficiently precise decimal representation of n. | 964 // Find a sufficiently precise decimal representation of n. |
| 1001 int decimal_point; | 965 int decimal_point; |
| 1002 int sign; | 966 int sign; |
| 1003 char* decimal_rep = NULL; | |
| 1004 bool used_gay_dtoa = false; | |
| 1005 // Add one for the terminating null character. | 967 // Add one for the terminating null character. |
| 1006 const int kV8DtoaBufferCapacity = kMaximalDigits + 1; | 968 const int kV8DtoaBufferCapacity = kMaximalDigits + 1; |
| 1007 char v8_dtoa_buffer[kV8DtoaBufferCapacity]; | 969 char decimal_rep[kV8DtoaBufferCapacity]; |
| 1008 int decimal_rep_length; | 970 int decimal_rep_length; |
| 1009 | 971 |
| 1010 if (DoubleToAscii(value, DTOA_PRECISION, p, | 972 DoubleToAscii(value, DTOA_PRECISION, p, |
| 1011 Vector<char>(v8_dtoa_buffer, kV8DtoaBufferCapacity), | 973 Vector<char>(decimal_rep, kV8DtoaBufferCapacity), |
| 1012 &sign, &decimal_rep_length, &decimal_point)) { | 974 &sign, &decimal_rep_length, &decimal_point); |
| 1013 decimal_rep = v8_dtoa_buffer; | |
| 1014 } else { | |
| 1015 decimal_rep = dtoa(value, 2, p, &decimal_point, &sign, NULL); | |
| 1016 decimal_rep_length = StrLength(decimal_rep); | |
| 1017 used_gay_dtoa = true; | |
| 1018 } | |
| 1019 ASSERT(decimal_rep_length <= p); | 975 ASSERT(decimal_rep_length <= p); |
| 1020 | 976 |
| 1021 int exponent = decimal_point - 1; | 977 int exponent = decimal_point - 1; |
| 1022 | 978 |
| 1023 char* result = NULL; | 979 char* result = NULL; |
| 1024 | 980 |
| 1025 if (exponent < -6 || exponent >= p) { | 981 if (exponent < -6 || exponent >= p) { |
| 1026 result = | 982 result = |
| 1027 CreateExponentialRepresentation(decimal_rep, exponent, negative, p); | 983 CreateExponentialRepresentation(decimal_rep, exponent, negative, p); |
| 1028 } else { | 984 } else { |
| (...skipping 23 matching lines...) Expand all Loading... |
| 1052 const int len = StrLength(decimal_rep + decimal_point); | 1008 const int len = StrLength(decimal_rep + decimal_point); |
| 1053 const int n = Min(len, p - (builder.position() - extra)); | 1009 const int n = Min(len, p - (builder.position() - extra)); |
| 1054 builder.AddSubstring(decimal_rep + decimal_point, n); | 1010 builder.AddSubstring(decimal_rep + decimal_point, n); |
| 1055 } | 1011 } |
| 1056 builder.AddPadding('0', extra + (p - builder.position())); | 1012 builder.AddPadding('0', extra + (p - builder.position())); |
| 1057 } | 1013 } |
| 1058 } | 1014 } |
| 1059 result = builder.Finalize(); | 1015 result = builder.Finalize(); |
| 1060 } | 1016 } |
| 1061 | 1017 |
| 1062 if (used_gay_dtoa) { | |
| 1063 freedtoa(decimal_rep); | |
| 1064 } | |
| 1065 return result; | 1018 return result; |
| 1066 } | 1019 } |
| 1067 | 1020 |
| 1068 | 1021 |
| 1069 char* DoubleToRadixCString(double value, int radix) { | 1022 char* DoubleToRadixCString(double value, int radix) { |
| 1070 ASSERT(radix >= 2 && radix <= 36); | 1023 ASSERT(radix >= 2 && radix <= 36); |
| 1071 | 1024 |
| 1072 // Character array used for conversion. | 1025 // Character array used for conversion. |
| 1073 static const char chars[] = "0123456789abcdefghijklmnopqrstuvwxyz"; | 1026 static const char chars[] = "0123456789abcdefghijklmnopqrstuvwxyz"; |
| 1074 | 1027 |
| (...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1131 // Allocate result and fill in the parts. | 1084 // Allocate result and fill in the parts. |
| 1132 StringBuilder builder(result_size + 1); | 1085 StringBuilder builder(result_size + 1); |
| 1133 builder.AddSubstring(integer_buffer + integer_pos + 1, integer_part_size); | 1086 builder.AddSubstring(integer_buffer + integer_pos + 1, integer_part_size); |
| 1134 if (decimal_pos > 0) builder.AddCharacter('.'); | 1087 if (decimal_pos > 0) builder.AddCharacter('.'); |
| 1135 builder.AddSubstring(decimal_buffer, decimal_pos); | 1088 builder.AddSubstring(decimal_buffer, decimal_pos); |
| 1136 return builder.Finalize(); | 1089 return builder.Finalize(); |
| 1137 } | 1090 } |
| 1138 | 1091 |
| 1139 | 1092 |
| 1140 } } // namespace v8::internal | 1093 } } // namespace v8::internal |
| OLD | NEW |