| Index: runtime/third_party/double-conversion/src/double-conversion.cc
|
| diff --git a/runtime/third_party/double-conversion/src/double-conversion.cc b/runtime/third_party/double-conversion/src/double-conversion.cc
|
| index e379299f106fb66aa3c5daaff33b0715a5c5cfe0..477f94e1b7c5a12e1660507361d0397f3ac00ad3 100644
|
| --- a/runtime/third_party/double-conversion/src/double-conversion.cc
|
| +++ b/runtime/third_party/double-conversion/src/double-conversion.cc
|
| @@ -118,7 +118,7 @@ void DoubleToStringConverter::CreateDecimalRepresentation(
|
| StringBuilder* result_builder) const {
|
| // Create a representation that is padded with zeros if needed.
|
| if (decimal_point <= 0) {
|
| - // "0.00000decimal_rep".
|
| + // "0.00000decimal_rep" or "0.000decimal_rep00".
|
| result_builder->AddCharacter('0');
|
| if (digits_after_point > 0) {
|
| result_builder->AddCharacter('.');
|
| @@ -129,7 +129,7 @@ void DoubleToStringConverter::CreateDecimalRepresentation(
|
| result_builder->AddPadding('0', remaining_digits);
|
| }
|
| } else if (decimal_point >= length) {
|
| - // "decimal_rep0000.00000" or "decimal_rep.0000"
|
| + // "decimal_rep0000.00000" or "decimal_rep.0000".
|
| result_builder->AddSubstring(decimal_digits, length);
|
| result_builder->AddPadding('0', decimal_point - length);
|
| if (digits_after_point > 0) {
|
| @@ -137,7 +137,7 @@ void DoubleToStringConverter::CreateDecimalRepresentation(
|
| result_builder->AddPadding('0', digits_after_point);
|
| }
|
| } else {
|
| - // "decima.l_rep000"
|
| + // "decima.l_rep000".
|
| ASSERT(digits_after_point > 0);
|
| result_builder->AddSubstring(decimal_digits, decimal_point);
|
| result_builder->AddCharacter('.');
|
| @@ -416,8 +416,9 @@ void DoubleToStringConverter::DoubleToAscii(double v,
|
|
|
| // Consumes the given substring from the iterator.
|
| // Returns false, if the substring does not match.
|
| -static bool ConsumeSubString(const char** current,
|
| - const char* end,
|
| +template <class Iterator>
|
| +static bool ConsumeSubString(Iterator* current,
|
| + Iterator end,
|
| const char* substring) {
|
| ASSERT(**current == *substring);
|
| for (substring++; *substring != '\0'; substring++) {
|
| @@ -439,10 +440,36 @@ static bool ConsumeSubString(const char** current,
|
| const int kMaxSignificantDigits = 772;
|
|
|
|
|
| +static const char kWhitespaceTable7[] = { 32, 13, 10, 9, 11, 12 };
|
| +static const int kWhitespaceTable7Length = ARRAY_SIZE(kWhitespaceTable7);
|
| +
|
| +
|
| +static const uc16 kWhitespaceTable16[] = {
|
| + 160, 8232, 8233, 5760, 6158, 8192, 8193, 8194, 8195,
|
| + 8196, 8197, 8198, 8199, 8200, 8201, 8202, 8239, 8287, 12288, 65279
|
| +};
|
| +static const int kWhitespaceTable16Length = ARRAY_SIZE(kWhitespaceTable16);
|
| +
|
| +
|
| +static bool isWhitespace(int x) {
|
| + if (x < 128) {
|
| + for (int i = 0; i < kWhitespaceTable7Length; i++) {
|
| + if (kWhitespaceTable7[i] == x) return true;
|
| + }
|
| + } else {
|
| + for (int i = 0; i < kWhitespaceTable16Length; i++) {
|
| + if (kWhitespaceTable16[i] == x) return true;
|
| + }
|
| + }
|
| + return false;
|
| +}
|
| +
|
| +
|
| // Returns true if a nonspace found and false if the end has reached.
|
| -static inline bool AdvanceToNonspace(const char** current, const char* end) {
|
| +template <class Iterator>
|
| +static inline bool AdvanceToNonspace(Iterator* current, Iterator end) {
|
| while (*current != end) {
|
| - if (**current != ' ') return true;
|
| + if (!isWhitespace(**current)) return true;
|
| ++*current;
|
| }
|
| return false;
|
| @@ -467,10 +494,17 @@ static double SignedZero(bool sign) {
|
| // because it constant-propagated the radix and concluded that the last
|
| // condition was always true. By moving it into a separate function the
|
| // compiler wouldn't warn anymore.
|
| +#if _MSC_VER
|
| +#pragma optimize("",off)
|
| static bool IsDecimalDigitForRadix(int c, int radix) {
|
| return '0' <= c && c <= '9' && (c - '0') < radix;
|
| }
|
| -
|
| +#pragma optimize("",on)
|
| +#else
|
| +static bool inline IsDecimalDigitForRadix(int c, int radix) {
|
| + return '0' <= c && c <= '9' && (c - '0') < radix;
|
| +}
|
| +#endif
|
| // Returns true if 'c' is a character digit that is valid for the given radix.
|
| // The 'a_character' should be 'a' or 'A'.
|
| //
|
| @@ -484,25 +518,27 @@ static bool IsCharacterDigitForRadix(int c, int radix, char a_character) {
|
|
|
|
|
| // Parsing integers with radix 2, 4, 8, 16, 32. Assumes current != end.
|
| -template <int radix_log_2>
|
| -static double RadixStringToIeee(const char* current,
|
| - const char* end,
|
| +template <int radix_log_2, class Iterator>
|
| +static double RadixStringToIeee(Iterator* current,
|
| + Iterator end,
|
| bool sign,
|
| bool allow_trailing_junk,
|
| double junk_string_value,
|
| bool read_as_double,
|
| - const char** trailing_pointer) {
|
| - ASSERT(current != end);
|
| + bool* result_is_junk) {
|
| + ASSERT(*current != end);
|
|
|
| const int kDoubleSize = Double::kSignificandSize;
|
| const int kSingleSize = Single::kSignificandSize;
|
| const int kSignificandSize = read_as_double? kDoubleSize: kSingleSize;
|
|
|
| + *result_is_junk = true;
|
| +
|
| // Skip leading 0s.
|
| - while (*current == '0') {
|
| - ++current;
|
| - if (current == end) {
|
| - *trailing_pointer = end;
|
| + while (**current == '0') {
|
| + ++(*current);
|
| + if (*current == end) {
|
| + *result_is_junk = false;
|
| return SignedZero(sign);
|
| }
|
| }
|
| @@ -513,14 +549,14 @@ static double RadixStringToIeee(const char* current,
|
|
|
| do {
|
| int digit;
|
| - if (IsDecimalDigitForRadix(*current, radix)) {
|
| - digit = static_cast<char>(*current) - '0';
|
| - } else if (IsCharacterDigitForRadix(*current, radix, 'a')) {
|
| - digit = static_cast<char>(*current) - 'a' + 10;
|
| - } else if (IsCharacterDigitForRadix(*current, radix, 'A')) {
|
| - digit = static_cast<char>(*current) - 'A' + 10;
|
| + if (IsDecimalDigitForRadix(**current, radix)) {
|
| + digit = static_cast<char>(**current) - '0';
|
| + } else if (IsCharacterDigitForRadix(**current, radix, 'a')) {
|
| + digit = static_cast<char>(**current) - 'a' + 10;
|
| + } else if (IsCharacterDigitForRadix(**current, radix, 'A')) {
|
| + digit = static_cast<char>(**current) - 'A' + 10;
|
| } else {
|
| - if (allow_trailing_junk || !AdvanceToNonspace(¤t, end)) {
|
| + if (allow_trailing_junk || !AdvanceToNonspace(current, end)) {
|
| break;
|
| } else {
|
| return junk_string_value;
|
| @@ -545,13 +581,13 @@ static double RadixStringToIeee(const char* current,
|
|
|
| bool zero_tail = true;
|
| for (;;) {
|
| - ++current;
|
| - if (current == end || !isDigit(*current, radix)) break;
|
| - zero_tail = zero_tail && *current == '0';
|
| + ++(*current);
|
| + if (*current == end || !isDigit(**current, radix)) break;
|
| + zero_tail = zero_tail && **current == '0';
|
| exponent += radix_log_2;
|
| }
|
|
|
| - if (!allow_trailing_junk && AdvanceToNonspace(¤t, end)) {
|
| + if (!allow_trailing_junk && AdvanceToNonspace(current, end)) {
|
| return junk_string_value;
|
| }
|
|
|
| @@ -573,14 +609,13 @@ static double RadixStringToIeee(const char* current,
|
| }
|
| break;
|
| }
|
| - ++current;
|
| - } while (current != end);
|
| + ++(*current);
|
| + } while (*current != end);
|
|
|
| ASSERT(number < ((int64_t)1 << kSignificandSize));
|
| - const double double_number = static_cast<double>(number);
|
| - ASSERT(static_cast<int64_t>(double_number) == number);
|
| + ASSERT(static_cast<int64_t>(static_cast<double>(number)) == number);
|
|
|
| - *trailing_pointer = current;
|
| + *result_is_junk = false;
|
|
|
| if (exponent == 0) {
|
| if (sign) {
|
| @@ -595,13 +630,14 @@ static double RadixStringToIeee(const char* current,
|
| }
|
|
|
|
|
| +template <class Iterator>
|
| double StringToDoubleConverter::StringToIeee(
|
| - const char* input,
|
| + Iterator input,
|
| int length,
|
| - int* processed_characters_count,
|
| - bool read_as_double) const {
|
| - const char* current = input;
|
| - const char* end = input + length;
|
| + bool read_as_double,
|
| + int* processed_characters_count) const {
|
| + Iterator current = input;
|
| + Iterator end = input + length;
|
|
|
| *processed_characters_count = 0;
|
|
|
| @@ -648,7 +684,7 @@ double StringToDoubleConverter::StringToIeee(
|
| if (*current == '+' || *current == '-') {
|
| sign = (*current == '-');
|
| ++current;
|
| - const char* next_non_space = current;
|
| + Iterator next_non_space = current;
|
| // Skip following spaces (if allowed).
|
| if (!AdvanceToNonspace(&next_non_space, end)) return junk_string_value_;
|
| if (!allow_spaces_after_sign && (current != next_non_space)) {
|
| @@ -712,17 +748,17 @@ double StringToDoubleConverter::StringToIeee(
|
| return junk_string_value_; // "0x".
|
| }
|
|
|
| - const char* tail_pointer = NULL;
|
| - double result = RadixStringToIeee<4>(current,
|
| + bool result_is_junk;
|
| + double result = RadixStringToIeee<4>(¤t,
|
| end,
|
| sign,
|
| allow_trailing_junk,
|
| junk_string_value_,
|
| read_as_double,
|
| - &tail_pointer);
|
| - if (tail_pointer != NULL) {
|
| - if (allow_trailing_spaces) AdvanceToNonspace(&tail_pointer, end);
|
| - *processed_characters_count = static_cast<int>(tail_pointer - input);
|
| + &result_is_junk);
|
| + if (!result_is_junk) {
|
| + if (allow_trailing_spaces) AdvanceToNonspace(¤t, end);
|
| + *processed_characters_count = static_cast<int>(current - input);
|
| }
|
| return result;
|
| }
|
| @@ -823,9 +859,9 @@ double StringToDoubleConverter::StringToIeee(
|
| return junk_string_value_;
|
| }
|
| }
|
| - char sign = '+';
|
| + char exponen_sign = '+';
|
| if (*current == '+' || *current == '-') {
|
| - sign = static_cast<char>(*current);
|
| + exponen_sign = static_cast<char>(*current);
|
| ++current;
|
| if (current == end) {
|
| if (allow_trailing_junk) {
|
| @@ -859,7 +895,7 @@ double StringToDoubleConverter::StringToIeee(
|
| ++current;
|
| } while (current != end && *current >= '0' && *current <= '9');
|
|
|
| - exponent += (sign == '-' ? -num : num);
|
| + exponent += (exponen_sign == '-' ? -num : num);
|
| }
|
|
|
| if (!(allow_trailing_spaces || allow_trailing_junk) && (current != end)) {
|
| @@ -877,15 +913,16 @@ double StringToDoubleConverter::StringToIeee(
|
|
|
| if (octal) {
|
| double result;
|
| - const char* tail_pointer = NULL;
|
| - result = RadixStringToIeee<3>(buffer,
|
| + bool result_is_junk;
|
| + char* start = buffer;
|
| + result = RadixStringToIeee<3>(&start,
|
| buffer + buffer_pos,
|
| sign,
|
| allow_trailing_junk,
|
| junk_string_value_,
|
| read_as_double,
|
| - &tail_pointer);
|
| - ASSERT(tail_pointer != NULL);
|
| + &result_is_junk);
|
| + ASSERT(!result_is_junk);
|
| *processed_characters_count = static_cast<int>(current - input);
|
| return result;
|
| }
|
| @@ -908,4 +945,38 @@ double StringToDoubleConverter::StringToIeee(
|
| return sign? -converted: converted;
|
| }
|
|
|
| +
|
| +double StringToDoubleConverter::StringToDouble(
|
| + const char* buffer,
|
| + int length,
|
| + int* processed_characters_count) const {
|
| + return StringToIeee(buffer, length, true, processed_characters_count);
|
| +}
|
| +
|
| +
|
| +double StringToDoubleConverter::StringToDouble(
|
| + const uc16* buffer,
|
| + int length,
|
| + int* processed_characters_count) const {
|
| + return StringToIeee(buffer, length, true, processed_characters_count);
|
| +}
|
| +
|
| +
|
| +float StringToDoubleConverter::StringToFloat(
|
| + const char* buffer,
|
| + int length,
|
| + int* processed_characters_count) const {
|
| + return static_cast<float>(StringToIeee(buffer, length, false,
|
| + processed_characters_count));
|
| +}
|
| +
|
| +
|
| +float StringToDoubleConverter::StringToFloat(
|
| + const uc16* buffer,
|
| + int length,
|
| + int* processed_characters_count) const {
|
| + return static_cast<float>(StringToIeee(buffer, length, false,
|
| + processed_characters_count));
|
| +}
|
| +
|
| } // namespace double_conversion
|
|
|