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 |