mirror of
https://github.com/mozilla/gecko-dev.git
synced 2025-02-16 05:45:33 +00:00
Bug 1465808 - Update double-conversion to latest upstream. rs=froydnj
--HG-- extra : rebase_source : 89aeedf516a89aa5d6189bdbde8d1466e59f01f6
This commit is contained in:
parent
e682b9e409
commit
df09db05b8
@ -1,37 +1,9 @@
|
||||
commit 1b5fa314800a0e68e2b5d00d17e87a5b1fa3ac5d
|
||||
Author: Shane <sffc@sffc1.com>
|
||||
Date: Fri Mar 2 01:26:53 2018 -0800
|
||||
commit 9a8e518bedcf171d99eb1c00eef4beb1ecc20a4b
|
||||
Merge: ae9ad90 da420c3
|
||||
Author: Florian Loitsch <floitsch@google.com>
|
||||
Date: Tue May 22 11:24:13 2018 +0200
|
||||
|
||||
Clarify output charset in DoubleToAscii documentation (#61)
|
||||
Merge pull request #68 from floitschG/static_size_assert
|
||||
|
||||
* Clarify output charset in DoubleToAscii documentation
|
||||
|
||||
* Fixing typo in charset docs.
|
||||
Use `static_assert` with newer compilers.
|
||||
|
||||
diff --git a/double-conversion/double-conversion.h b/double-conversion/double-conversion.h
|
||||
index 9978bde..1ccd7fc 100644
|
||||
--- a/double-conversion/double-conversion.h
|
||||
+++ b/double-conversion/double-conversion.h
|
||||
@@ -294,13 +294,18 @@ class DoubleToStringConverter {
|
||||
// should be at least kBase10MaximalLength + 1 characters long.
|
||||
static const int kBase10MaximalLength = 17;
|
||||
|
||||
- // Converts the given double 'v' to ascii. 'v' must not be NaN, +Infinity, or
|
||||
- // -Infinity. In SHORTEST_SINGLE-mode this restriction also applies to 'v'
|
||||
- // after it has been casted to a single-precision float. That is, in this
|
||||
- // mode static_cast<float>(v) must not be NaN, +Infinity or -Infinity.
|
||||
+ // Converts the given double 'v' to digit characters. 'v' must not be NaN,
|
||||
+ // +Infinity, or -Infinity. In SHORTEST_SINGLE-mode this restriction also
|
||||
+ // applies to 'v' after it has been casted to a single-precision float. That
|
||||
+ // is, in this mode static_cast<float>(v) must not be NaN, +Infinity or
|
||||
+ // -Infinity.
|
||||
//
|
||||
// The result should be interpreted as buffer * 10^(point-length).
|
||||
//
|
||||
+ // The digits are written to the buffer in the platform's charset, which is
|
||||
+ // often UTF-8 (with ASCII-range digits) but may be another charset, such
|
||||
+ // as EBCDIC.
|
||||
+ //
|
||||
// The output depends on the given mode:
|
||||
// - SHORTEST: produce the least amount of digits for which the internal
|
||||
// identity requirement is still satisfied. If the digits are printed
|
||||
|
@ -890,9 +890,11 @@ double StringToDoubleConverter::StringToIeee(
|
||||
if (*current == 'e' || *current == 'E') {
|
||||
if (octal && !allow_trailing_junk) return junk_string_value_;
|
||||
if (octal) goto parsing_done;
|
||||
Iterator junk_begin = current;
|
||||
++current;
|
||||
if (current == end) {
|
||||
if (allow_trailing_junk) {
|
||||
current = junk_begin;
|
||||
goto parsing_done;
|
||||
} else {
|
||||
return junk_string_value_;
|
||||
@ -904,6 +906,7 @@ double StringToDoubleConverter::StringToIeee(
|
||||
++current;
|
||||
if (current == end) {
|
||||
if (allow_trailing_junk) {
|
||||
current = junk_begin;
|
||||
goto parsing_done;
|
||||
} else {
|
||||
return junk_string_value_;
|
||||
@ -913,6 +916,7 @@ double StringToDoubleConverter::StringToIeee(
|
||||
|
||||
if (current == end || *current < '0' || *current > '9') {
|
||||
if (allow_trailing_junk) {
|
||||
current = junk_begin;
|
||||
goto parsing_done;
|
||||
} else {
|
||||
return junk_string_value_;
|
||||
|
@ -472,6 +472,30 @@ double Strtod(Vector<const char> buffer, int exponent) {
|
||||
}
|
||||
}
|
||||
|
||||
static float SanitizedDoubletof(double d) {
|
||||
ASSERT(d >= 0.0);
|
||||
// ASAN has a sanitize check that disallows casting doubles to floats if
|
||||
// they are too big.
|
||||
// https://clang.llvm.org/docs/UndefinedBehaviorSanitizer.html#available-checks
|
||||
// The behavior should be covered by IEEE 754, but some projects use this
|
||||
// flag, so work around it.
|
||||
float max_finite = 3.4028234663852885981170418348451692544e+38;
|
||||
// The half-way point between the max-finite and infinity value.
|
||||
// Since infinity has an even significand everything equal or greater than
|
||||
// this value should become infinity.
|
||||
double half_max_finite_infinity =
|
||||
3.40282356779733661637539395458142568448e+38;
|
||||
if (d >= max_finite) {
|
||||
if (d >= half_max_finite_infinity) {
|
||||
return Single::Infinity();
|
||||
} else {
|
||||
return max_finite;
|
||||
}
|
||||
} else {
|
||||
return static_cast<float>(d);
|
||||
}
|
||||
}
|
||||
|
||||
float Strtof(Vector<const char> buffer, int exponent) {
|
||||
char copy_buffer[kMaxSignificantDecimalDigits];
|
||||
Vector<const char> trimmed;
|
||||
@ -483,7 +507,7 @@ float Strtof(Vector<const char> buffer, int exponent) {
|
||||
double double_guess;
|
||||
bool is_correct = ComputeGuess(trimmed, exponent, &double_guess);
|
||||
|
||||
float float_guess = static_cast<float>(double_guess);
|
||||
float float_guess = SanitizedDoubletof(double_guess);
|
||||
if (float_guess == double_guess) {
|
||||
// This shortcut triggers for integer values.
|
||||
return float_guess;
|
||||
@ -506,15 +530,15 @@ float Strtof(Vector<const char> buffer, int exponent) {
|
||||
double double_next = Double(double_guess).NextDouble();
|
||||
double double_previous = Double(double_guess).PreviousDouble();
|
||||
|
||||
float f1 = static_cast<float>(double_previous);
|
||||
float f1 = SanitizedDoubletof(double_previous);
|
||||
float f2 = float_guess;
|
||||
float f3 = static_cast<float>(double_next);
|
||||
float f3 = SanitizedDoubletof(double_next);
|
||||
float f4;
|
||||
if (is_correct) {
|
||||
f4 = f3;
|
||||
} else {
|
||||
double double_next2 = Double(double_next).NextDouble();
|
||||
f4 = static_cast<float>(double_next2);
|
||||
f4 = SanitizedDoubletof(double_next2);
|
||||
}
|
||||
(void) f2; // Mark variable as used.
|
||||
ASSERT(f1 <= f2 && f2 <= f3 && f3 <= f4);
|
||||
@ -529,7 +553,7 @@ float Strtof(Vector<const char> buffer, int exponent) {
|
||||
(f1 == f2 && f2 != f3 && f3 == f4) ||
|
||||
(f1 == f2 && f2 == f3 && f3 != f4));
|
||||
|
||||
// guess and next are the two possible canditates (in the same way that
|
||||
// guess and next are the two possible candidates (in the same way that
|
||||
// double_guess was the lower candidate for a double-precision guess).
|
||||
float guess = f1;
|
||||
float next = f4;
|
||||
|
@ -79,7 +79,8 @@ inline void abort_noreturn() { MOZ_CRASH(); }
|
||||
defined(__AARCH64EL__) || defined(__aarch64__) || \
|
||||
defined(__riscv)
|
||||
#define DOUBLE_CONVERSION_CORRECT_DOUBLE_OPERATIONS 1
|
||||
#elif defined(__mc68000__)
|
||||
#elif defined(__mc68000__) || \
|
||||
defined(__pnacl__) || defined(__native_client__)
|
||||
#undef DOUBLE_CONVERSION_CORRECT_DOUBLE_OPERATIONS
|
||||
#elif defined(_M_IX86) || defined(__i386__) || defined(__i386)
|
||||
#if defined(_WIN32)
|
||||
@ -92,12 +93,6 @@ inline void abort_noreturn() { MOZ_CRASH(); }
|
||||
#error Target architecture was not detected as supported by Double-Conversion.
|
||||
#endif
|
||||
|
||||
#if defined(__GNUC__)
|
||||
#define DOUBLE_CONVERSION_UNUSED __attribute__((unused))
|
||||
#else
|
||||
#define DOUBLE_CONVERSION_UNUSED
|
||||
#endif
|
||||
|
||||
#if defined(_WIN32) && !defined(__MINGW32__)
|
||||
|
||||
typedef signed char int8_t;
|
||||
@ -324,8 +319,12 @@ template <class Dest, class Source>
|
||||
inline Dest BitCast(const Source& source) {
|
||||
// Compile time assertion: sizeof(Dest) == sizeof(Source)
|
||||
// A compile error here means your Dest and Source have different sizes.
|
||||
DOUBLE_CONVERSION_UNUSED
|
||||
typedef char VerifySizesAreEqual[sizeof(Dest) == sizeof(Source) ? 1 : -1];
|
||||
#if __cplusplus >= 201103L
|
||||
static_assert(sizeof(Dest) == sizeof(Source),
|
||||
"source and destination size mismatch");
|
||||
#else
|
||||
typedef char VerifySizesAreEqual[sizeof(Dest) == sizeof(Source) ? 1 : -1];
|
||||
#endif
|
||||
|
||||
Dest dest;
|
||||
memmove(&dest, &source, sizeof(dest));
|
||||
|
Loading…
x
Reference in New Issue
Block a user