On Wed, Jun 20, 2018 at 1:25 PM, Khem Raj <raj.k...@gmail.com> wrote: > On Wed, Jun 20, 2018 at 1:22 PM Alistair Francis > <alistair.fran...@wdc.com> wrote: >> >> Update the Double-Conversion source inside mozjs to add support for more >> architectures. >> > > could you describe the patch a bit more and testing it needs.
Do you want it updated in the commit message or is the list fine? Either way, the Double-Conversion (https://github.com/google/double-conversion) library is used inside a lot of projects for IEEE doubles. The version in mozjs 17 is very old and it missing a lot of newer achitecutre support. It's even missing AArch64 which is why there is a seperate patch to add that. This just updates the script already included in mozjs for updating Double Conversion and then updates Double Conversion to the latest. This gives us RISC-V support as well as other architectures. Alistair > >> Signed-off-by: Alistair Francis <alistair.fran...@wdc.com> >> --- >> .../mozjs/0003-Add-AArch64-support.patch | 76 - >> .../mozjs/Update-Double-Conversion.patch | 1732 +++++++++++++++++ >> ...-the-double-conversion-update-script.patch | 175 ++ >> .../recipes-extended/mozjs/mozjs_17.0.0.bb | 3 +- >> 4 files changed, 1909 insertions(+), 77 deletions(-) >> delete mode 100644 >> meta-oe/recipes-extended/mozjs/mozjs/0003-Add-AArch64-support.patch >> create mode 100644 >> meta-oe/recipes-extended/mozjs/mozjs/Update-Double-Conversion.patch >> create mode 100644 >> meta-oe/recipes-extended/mozjs/mozjs/Update-the-double-conversion-update-script.patch >> >> diff --git >> a/meta-oe/recipes-extended/mozjs/mozjs/0003-Add-AArch64-support.patch >> b/meta-oe/recipes-extended/mozjs/mozjs/0003-Add-AArch64-support.patch >> deleted file mode 100644 >> index 6e724292a..000000000 >> --- a/meta-oe/recipes-extended/mozjs/mozjs/0003-Add-AArch64-support.patch >> +++ /dev/null >> @@ -1,76 +0,0 @@ >> -From 15e710e331d36eb279852b5cd1ba37a9a6005217 Mon Sep 17 00:00:00 2001 >> -From: Koen Kooi <koen.k...@linaro.org> >> -Date: Mon, 2 Mar 2015 19:08:22 +0800 >> -Subject: [PATCH 3/5] Add AArch64 support >> - >> ---- >> -Upstream-status: Pending >> - >> - js/src/assembler/jit/ExecutableAllocator.h | 6 ++++++ >> - js/src/assembler/wtf/Platform.h | 4 ++++ >> - js/src/configure.in | 4 ++++ >> - mfbt/double-conversion/utils.h | 1 + >> - 4 files changed, 15 insertions(+) >> - >> -diff --git a/js/src/assembler/jit/ExecutableAllocator.h >> b/js/src/assembler/jit/ExecutableAllocator.h >> -index c071c33..90764c3 100644 >> ---- a/js/src/assembler/jit/ExecutableAllocator.h >> -+++ b/js/src/assembler/jit/ExecutableAllocator.h >> -@@ -382,6 +382,12 @@ public: >> - { >> - reprotectRegion(start, size, Executable); >> - } >> -+#elif WTF_CPU_AARCH64 && WTF_PLATFORM_LINUX >> -+ static void cacheFlush(void* code, size_t size) >> -+ { >> -+ intptr_t end = reinterpret_cast<intptr_t>(code) + size; >> -+ __builtin___clear_cache(reinterpret_cast<char*>(code), >> reinterpret_cast<char*>(end)); >> -+ } >> - #else >> - static void makeWritable(void*, size_t) {} >> - static void makeExecutable(void*, size_t) {} >> -diff --git a/js/src/assembler/wtf/Platform.h >> b/js/src/assembler/wtf/Platform.h >> -index 0c84896..e8763a7 100644 >> ---- a/js/src/assembler/wtf/Platform.h >> -+++ b/js/src/assembler/wtf/Platform.h >> -@@ -325,6 +325,10 @@ >> - #define WTF_THUMB_ARCH_VERSION 0 >> - #endif >> - >> -+/* CPU(AArch64) - 64-bit ARM */ >> -+#if defined(__aarch64__) >> -+#define WTF_CPU_AARCH64 1 >> -+#endif >> - >> - /* WTF_CPU_ARMV5_OR_LOWER - ARM instruction set v5 or earlier */ >> - /* On ARMv5 and below the natural alignment is required. >> -diff --git a/js/src/configure.in b/js/src/configure.in >> -index 64c7606..0673aca 100644 >> ---- a/js/src/configure.in >> -+++ b/js/src/configure.in >> -@@ -1121,6 +1121,10 @@ arm*) >> - CPU_ARCH=arm >> - ;; >> - >> -+aarch64) >> -+ CPU_ARCH=aarch64 >> -+ ;; >> -+ >> - mips|mipsel) >> - CPU_ARCH="mips" >> - ;; >> -diff --git a/mfbt/double-conversion/utils.h b/mfbt/double-conversion/utils.h >> -index 0eec2d9..fe26dab 100644 >> ---- a/mfbt/double-conversion/utils.h >> -+++ b/mfbt/double-conversion/utils.h >> -@@ -58,6 +58,7 @@ >> - defined(__mips__) || defined(__powerpc__) || \ >> - defined(__sparc__) || defined(__sparc) || defined(__s390__) || \ >> - defined(__SH4__) || defined(__alpha__) || \ >> -+ defined(__aarch64__) || \ >> - defined(_MIPS_ARCH_MIPS32R2) >> - #define DOUBLE_CONVERSION_CORRECT_DOUBLE_OPERATIONS 1 >> - #elif defined(_M_IX86) || defined(__i386__) || defined(__i386) >> --- >> -1.9.3 >> - >> diff --git >> a/meta-oe/recipes-extended/mozjs/mozjs/Update-Double-Conversion.patch >> b/meta-oe/recipes-extended/mozjs/mozjs/Update-Double-Conversion.patch >> new file mode 100644 >> index 000000000..c5979c97b >> --- /dev/null >> +++ b/meta-oe/recipes-extended/mozjs/mozjs/Update-Double-Conversion.patch >> @@ -0,0 +1,1732 @@ >> +From b4961d6e1d273dd9643fc3c055163d5cd3362fb7 Mon Sep 17 00:00:00 2001 >> +From: Alistair Francis <alistair.fran...@wdc.com> >> +Date: Fri, 1 Jun 2018 14:47:31 -0700 >> +Subject: [PATCH] Update double conversion >> + >> +Signed-off-by: Alistair Francis <alistair.fran...@wdc.com> >> +--- >> + mfbt/double-conversion/COPYING | 26 ++ >> + mfbt/double-conversion/bignum-dtoa.cc | 19 +- >> + mfbt/double-conversion/bignum-dtoa.h | 2 +- >> + mfbt/double-conversion/bignum.cc | 39 +-- >> + mfbt/double-conversion/bignum.h | 5 +- >> + mfbt/double-conversion/cached-powers.cc | 14 +- >> + mfbt/double-conversion/cached-powers.h | 2 +- >> + mfbt/double-conversion/diy-fp.cc | 4 +- >> + mfbt/double-conversion/diy-fp.h | 24 +- >> + mfbt/double-conversion/double-conversion.cc | 293 ++++++++++++++------ >> + mfbt/double-conversion/double-conversion.h | 78 +++--- >> + mfbt/double-conversion/fast-dtoa.cc | 29 +- >> + mfbt/double-conversion/fast-dtoa.h | 2 +- >> + mfbt/double-conversion/fixed-dtoa.cc | 23 +- >> + mfbt/double-conversion/fixed-dtoa.h | 2 +- >> + mfbt/double-conversion/ieee.h | 8 +- >> + mfbt/double-conversion/strtod.cc | 59 ++-- >> + mfbt/double-conversion/strtod.h | 2 +- >> + mfbt/double-conversion/utils.h | 62 +++-- >> + 19 files changed, 465 insertions(+), 228 deletions(-) >> + create mode 100644 mfbt/double-conversion/COPYING >> + >> +diff --git a/mfbt/double-conversion/COPYING b/mfbt/double-conversion/COPYING >> +new file mode 100644 >> +index 0000000..933718a >> +--- /dev/null >> ++++ b/mfbt/double-conversion/COPYING >> +@@ -0,0 +1,26 @@ >> ++Copyright 2006-2011, the V8 project authors. All rights reserved. >> ++Redistribution and use in source and binary forms, with or without >> ++modification, are permitted provided that the following conditions are >> ++met: >> ++ >> ++ * Redistributions of source code must retain the above copyright >> ++ notice, this list of conditions and the following disclaimer. >> ++ * Redistributions in binary form must reproduce the above >> ++ copyright notice, this list of conditions and the following >> ++ disclaimer in the documentation and/or other materials provided >> ++ with the distribution. >> ++ * Neither the name of Google Inc. nor the names of its >> ++ contributors may be used to endorse or promote products derived >> ++ from this software without specific prior written permission. >> ++ >> ++THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS >> ++"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT >> ++LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR >> ++A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT >> ++OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, >> ++SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT >> ++LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, >> ++DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY >> ++THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT >> ++(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE >> ++OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. >> +diff --git a/mfbt/double-conversion/bignum-dtoa.cc >> b/mfbt/double-conversion/bignum-dtoa.cc >> +index b6c2e85..06bdf55 100644 >> +--- a/mfbt/double-conversion/bignum-dtoa.cc >> ++++ b/mfbt/double-conversion/bignum-dtoa.cc >> +@@ -25,12 +25,12 @@ >> + // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE >> + // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. >> + >> +-#include <math.h> >> ++#include <cmath> >> + >> +-#include "bignum-dtoa.h" >> ++#include <bignum-dtoa.h> >> + >> +-#include "bignum.h" >> +-#include "ieee.h" >> ++#include <bignum.h> >> ++#include <ieee.h> >> + >> + namespace double_conversion { >> + >> +@@ -192,13 +192,13 @@ static void GenerateShortestDigits(Bignum* numerator, >> Bignum* denominator, >> + delta_plus = delta_minus; >> + } >> + *length = 0; >> +- while (true) { >> ++ for (;;) { >> + uint16_t digit; >> + digit = numerator->DivideModuloIntBignum(*denominator); >> + ASSERT(digit <= 9); // digit is a uint16_t and therefore always >> positive. >> + // digit = numerator / denominator (integer division). >> + // numerator = numerator % denominator. >> +- buffer[(*length)++] = digit + '0'; >> ++ buffer[(*length)++] = static_cast<char>(digit + '0'); >> + >> + // Can we stop already? >> + // If the remainder of the division is less than the distance to the >> lower >> +@@ -282,7 +282,7 @@ static void GenerateShortestDigits(Bignum* numerator, >> Bignum* denominator, >> + // exponent (decimal_point), when rounding upwards. >> + static void GenerateCountedDigits(int count, int* decimal_point, >> + Bignum* numerator, Bignum* denominator, >> +- Vector<char>(buffer), int* length) { >> ++ Vector<char> buffer, int* length) { >> + ASSERT(count >= 0); >> + for (int i = 0; i < count - 1; ++i) { >> + uint16_t digit; >> +@@ -290,7 +290,7 @@ static void GenerateCountedDigits(int count, int* >> decimal_point, >> + ASSERT(digit <= 9); // digit is a uint16_t and therefore always >> positive. >> + // digit = numerator / denominator (integer division). >> + // numerator = numerator % denominator. >> +- buffer[i] = digit + '0'; >> ++ buffer[i] = static_cast<char>(digit + '0'); >> + // Prepare for next iteration. >> + numerator->Times10(); >> + } >> +@@ -300,7 +300,8 @@ static void GenerateCountedDigits(int count, int* >> decimal_point, >> + if (Bignum::PlusCompare(*numerator, *numerator, *denominator) >= 0) { >> + digit++; >> + } >> +- buffer[count - 1] = digit + '0'; >> ++ ASSERT(digit <= 10); >> ++ buffer[count - 1] = static_cast<char>(digit + '0'); >> + // Correct bad digits (in case we had a sequence of '9's). Propagate the >> + // carry until we hat a non-'9' or til we reach the first digit. >> + for (int i = count - 1; i > 0; --i) { >> +diff --git a/mfbt/double-conversion/bignum-dtoa.h >> b/mfbt/double-conversion/bignum-dtoa.h >> +index 34b9619..88d936a 100644 >> +--- a/mfbt/double-conversion/bignum-dtoa.h >> ++++ b/mfbt/double-conversion/bignum-dtoa.h >> +@@ -28,7 +28,7 @@ >> + #ifndef DOUBLE_CONVERSION_BIGNUM_DTOA_H_ >> + #define DOUBLE_CONVERSION_BIGNUM_DTOA_H_ >> + >> +-#include "utils.h" >> ++#include <utils.h> >> + >> + namespace double_conversion { >> + >> +diff --git a/mfbt/double-conversion/bignum.cc >> b/mfbt/double-conversion/bignum.cc >> +index 747491a..4786c2e 100644 >> +--- a/mfbt/double-conversion/bignum.cc >> ++++ b/mfbt/double-conversion/bignum.cc >> +@@ -25,13 +25,13 @@ >> + // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE >> + // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. >> + >> +-#include "bignum.h" >> +-#include "utils.h" >> ++#include <bignum.h> >> ++#include <utils.h> >> + >> + namespace double_conversion { >> + >> + Bignum::Bignum() >> +- : bigits_(bigits_buffer_, kBigitCapacity), used_digits_(0), >> exponent_(0) { >> ++ : bigits_buffer_(), bigits_(bigits_buffer_, kBigitCapacity), >> used_digits_(0), exponent_(0) { >> + for (int i = 0; i < kBigitCapacity; ++i) { >> + bigits_[i] = 0; >> + } >> +@@ -40,6 +40,7 @@ Bignum::Bignum() >> + >> + template<typename S> >> + static int BitSize(S value) { >> ++ (void) value; // Mark variable as used. >> + return 8 * sizeof(value); >> + } >> + >> +@@ -103,7 +104,7 @@ void Bignum::AssignDecimalString(Vector<const char> >> value) { >> + const int kMaxUint64DecimalDigits = 19; >> + Zero(); >> + int length = value.length(); >> +- int pos = 0; >> ++ unsigned int pos = 0; >> + // Let's just say that each digit needs 4 bits. >> + while (length >= kMaxUint64DecimalDigits) { >> + uint64_t digits = ReadUInt64(value, pos, kMaxUint64DecimalDigits); >> +@@ -122,9 +123,8 @@ void Bignum::AssignDecimalString(Vector<const char> >> value) { >> + static int HexCharValue(char c) { >> + if ('0' <= c && c <= '9') return c - '0'; >> + if ('a' <= c && c <= 'f') return 10 + c - 'a'; >> +- if ('A' <= c && c <= 'F') return 10 + c - 'A'; >> +- UNREACHABLE(); >> +- return 0; // To make compiler happy. >> ++ ASSERT('A' <= c && c <= 'F'); >> ++ return 10 + c - 'A'; >> + } >> + >> + >> +@@ -445,26 +445,27 @@ void Bignum::AssignPowerUInt16(uint16_t base, int >> power_exponent) { >> + mask >>= 2; >> + uint64_t this_value = base; >> + >> +- bool delayed_multipliciation = false; >> ++ bool delayed_multiplication = false; >> + const uint64_t max_32bits = 0xFFFFFFFF; >> + while (mask != 0 && this_value <= max_32bits) { >> + this_value = this_value * this_value; >> + // Verify that there is enough space in this_value to perform the >> + // multiplication. The first bit_size bits must be 0. >> + if ((power_exponent & mask) != 0) { >> ++ ASSERT(bit_size > 0); >> + uint64_t base_bits_mask = >> + ~((static_cast<uint64_t>(1) << (64 - bit_size)) - 1); >> + bool high_bits_zero = (this_value & base_bits_mask) == 0; >> + if (high_bits_zero) { >> + this_value *= base; >> + } else { >> +- delayed_multipliciation = true; >> ++ delayed_multiplication = true; >> + } >> + } >> + mask >>= 1; >> + } >> + AssignUInt64(this_value); >> +- if (delayed_multipliciation) { >> ++ if (delayed_multiplication) { >> + MultiplyByUInt32(base); >> + } >> + >> +@@ -501,13 +502,14 @@ uint16_t Bignum::DivideModuloIntBignum(const Bignum& >> other) { >> + // Start by removing multiples of 'other' until both numbers have the >> same >> + // number of digits. >> + while (BigitLength() > other.BigitLength()) { >> +- // This naive approach is extremely inefficient if the this divided >> other >> +- // might be big. This function is implemented for doubleToString where >> ++ // This naive approach is extremely inefficient if `this` divided by >> other >> ++ // is big. This function is implemented for doubleToString where >> + // the result should be small (less than 10). >> + ASSERT(other.bigits_[other.used_digits_ - 1] >= ((1 << kBigitSize) / >> 16)); >> ++ ASSERT(bigits_[used_digits_ - 1] < 0x10000); >> + // Remove the multiples of the first digit. >> + // Example this = 23 and other equals 9. -> Remove 2 multiples. >> +- result += bigits_[used_digits_ - 1]; >> ++ result += static_cast<uint16_t>(bigits_[used_digits_ - 1]); >> + SubtractTimes(other, bigits_[used_digits_ - 1]); >> + } >> + >> +@@ -523,13 +525,15 @@ uint16_t Bignum::DivideModuloIntBignum(const Bignum& >> other) { >> + // Shortcut for easy (and common) case. >> + int quotient = this_bigit / other_bigit; >> + bigits_[used_digits_ - 1] = this_bigit - other_bigit * quotient; >> +- result += quotient; >> ++ ASSERT(quotient < 0x10000); >> ++ result += static_cast<uint16_t>(quotient); >> + Clamp(); >> + return result; >> + } >> + >> + int division_estimate = this_bigit / (other_bigit + 1); >> +- result += division_estimate; >> ++ ASSERT(division_estimate < 0x10000); >> ++ result += static_cast<uint16_t>(division_estimate); >> + SubtractTimes(other, division_estimate); >> + >> + if (other_bigit * (division_estimate + 1) > this_bigit) { >> +@@ -560,8 +564,8 @@ static int SizeInHexChars(S number) { >> + >> + static char HexCharOfValue(int value) { >> + ASSERT(0 <= value && value <= 16); >> +- if (value < 10) return value + '0'; >> +- return value - 10 + 'A'; >> ++ if (value < 10) return static_cast<char>(value + '0'); >> ++ return static_cast<char>(value - 10 + 'A'); >> + } >> + >> + >> +@@ -755,7 +759,6 @@ void Bignum::SubtractTimes(const Bignum& other, int >> factor) { >> + Chunk difference = bigits_[i] - borrow; >> + bigits_[i] = difference & kBigitMask; >> + borrow = difference >> (kChunkSize - 1); >> +- ++i; >> + } >> + Clamp(); >> + } >> +diff --git a/mfbt/double-conversion/bignum.h >> b/mfbt/double-conversion/bignum.h >> +index 5ec3544..4fdad0c 100644 >> +--- a/mfbt/double-conversion/bignum.h >> ++++ b/mfbt/double-conversion/bignum.h >> +@@ -28,7 +28,7 @@ >> + #ifndef DOUBLE_CONVERSION_BIGNUM_H_ >> + #define DOUBLE_CONVERSION_BIGNUM_H_ >> + >> +-#include "utils.h" >> ++#include <utils.h> >> + >> + namespace double_conversion { >> + >> +@@ -49,7 +49,6 @@ class Bignum { >> + >> + void AssignPowerUInt16(uint16_t base, int exponent); >> + >> +- void AddUInt16(uint16_t operand); >> + void AddUInt64(uint64_t operand); >> + void AddBignum(const Bignum& other); >> + // Precondition: this >= other. >> +@@ -137,7 +136,7 @@ class Bignum { >> + // The Bignum's value equals value(bigits_) * 2^(exponent_ * kBigitSize). >> + int exponent_; >> + >> +- DISALLOW_COPY_AND_ASSIGN(Bignum); >> ++ DC_DISALLOW_COPY_AND_ASSIGN(Bignum); >> + }; >> + >> + } // namespace double_conversion >> +diff --git a/mfbt/double-conversion/cached-powers.cc >> b/mfbt/double-conversion/cached-powers.cc >> +index c676429..06e819d 100644 >> +--- a/mfbt/double-conversion/cached-powers.cc >> ++++ b/mfbt/double-conversion/cached-powers.cc >> +@@ -25,13 +25,13 @@ >> + // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE >> + // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. >> + >> +-#include <stdarg.h> >> +-#include <limits.h> >> +-#include <math.h> >> ++#include <climits> >> ++#include <cmath> >> ++#include <cstdarg> >> + >> +-#include "utils.h" >> ++#include <utils.h> >> + >> +-#include "cached-powers.h" >> ++#include <cached-powers.h> >> + >> + namespace double_conversion { >> + >> +@@ -131,7 +131,6 @@ static const CachedPower kCachedPowers[] = { >> + {UINT64_2PART_C(0xaf87023b, 9bf0ee6b), 1066, 340}, >> + }; >> + >> +-static const int kCachedPowersLength = ARRAY_SIZE(kCachedPowers); >> + static const int kCachedPowersOffset = 348; // -1 * the first >> decimal_exponent. >> + static const double kD_1_LOG2_10 = 0.30102999566398114; // 1 / lg(10) >> + // Difference between the decimal exponents in the table above. >> +@@ -149,9 +148,10 @@ void >> PowersOfTenCache::GetCachedPowerForBinaryExponentRange( >> + int foo = kCachedPowersOffset; >> + int index = >> + (foo + static_cast<int>(k) - 1) / kDecimalExponentDistance + 1; >> +- ASSERT(0 <= index && index < kCachedPowersLength); >> ++ ASSERT(0 <= index && index < >> static_cast<int>(ARRAY_SIZE(kCachedPowers))); >> + CachedPower cached_power = kCachedPowers[index]; >> + ASSERT(min_exponent <= cached_power.binary_exponent); >> ++ (void) max_exponent; // Mark variable as used. >> + ASSERT(cached_power.binary_exponent <= max_exponent); >> + *decimal_exponent = cached_power.decimal_exponent; >> + *power = DiyFp(cached_power.significand, cached_power.binary_exponent); >> +diff --git a/mfbt/double-conversion/cached-powers.h >> b/mfbt/double-conversion/cached-powers.h >> +index 61a5061..a425d7c 100644 >> +--- a/mfbt/double-conversion/cached-powers.h >> ++++ b/mfbt/double-conversion/cached-powers.h >> +@@ -28,7 +28,7 @@ >> + #ifndef DOUBLE_CONVERSION_CACHED_POWERS_H_ >> + #define DOUBLE_CONVERSION_CACHED_POWERS_H_ >> + >> +-#include "diy-fp.h" >> ++#include <diy-fp.h> >> + >> + namespace double_conversion { >> + >> +diff --git a/mfbt/double-conversion/diy-fp.cc >> b/mfbt/double-conversion/diy-fp.cc >> +index ddd1891..f31cf60 100644 >> +--- a/mfbt/double-conversion/diy-fp.cc >> ++++ b/mfbt/double-conversion/diy-fp.cc >> +@@ -26,8 +26,8 @@ >> + // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. >> + >> + >> +-#include "diy-fp.h" >> +-#include "utils.h" >> ++#include <diy-fp.h> >> ++#include <utils.h> >> + >> + namespace double_conversion { >> + >> +diff --git a/mfbt/double-conversion/diy-fp.h >> b/mfbt/double-conversion/diy-fp.h >> +index 9dcf8fb..80a8c4c 100644 >> +--- a/mfbt/double-conversion/diy-fp.h >> ++++ b/mfbt/double-conversion/diy-fp.h >> +@@ -28,7 +28,7 @@ >> + #ifndef DOUBLE_CONVERSION_DIY_FP_H_ >> + #define DOUBLE_CONVERSION_DIY_FP_H_ >> + >> +-#include "utils.h" >> ++#include <utils.h> >> + >> + namespace double_conversion { >> + >> +@@ -42,7 +42,7 @@ class DiyFp { >> + static const int kSignificandSize = 64; >> + >> + DiyFp() : f_(0), e_(0) {} >> +- DiyFp(uint64_t f, int e) : f_(f), e_(e) {} >> ++ DiyFp(uint64_t significand, int exponent) : f_(significand), >> e_(exponent) {} >> + >> + // this = this - other. >> + // The exponents of both numbers must be the same and the significand of >> this >> +@@ -76,22 +76,22 @@ class DiyFp { >> + >> + void Normalize() { >> + ASSERT(f_ != 0); >> +- uint64_t f = f_; >> +- int e = e_; >> ++ uint64_t significand = f_; >> ++ int exponent = e_; >> + >> + // This method is mainly called for normalizing boundaries. In general >> + // boundaries need to be shifted by 10 bits. We thus optimize for this >> case. >> + const uint64_t k10MSBits = UINT64_2PART_C(0xFFC00000, 00000000); >> +- while ((f & k10MSBits) == 0) { >> +- f <<= 10; >> +- e -= 10; >> ++ while ((significand & k10MSBits) == 0) { >> ++ significand <<= 10; >> ++ exponent -= 10; >> + } >> +- while ((f & kUint64MSB) == 0) { >> +- f <<= 1; >> +- e--; >> ++ while ((significand & kUint64MSB) == 0) { >> ++ significand <<= 1; >> ++ exponent--; >> + } >> +- f_ = f; >> +- e_ = e; >> ++ f_ = significand; >> ++ e_ = exponent; >> + } >> + >> + static DiyFp Normalize(const DiyFp& a) { >> +diff --git a/mfbt/double-conversion/double-conversion.cc >> b/mfbt/double-conversion/double-conversion.cc >> +index 650137b..7819267 100644 >> +--- a/mfbt/double-conversion/double-conversion.cc >> ++++ b/mfbt/double-conversion/double-conversion.cc >> +@@ -25,17 +25,18 @@ >> + // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE >> + // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. >> + >> +-#include <limits.h> >> +-#include <math.h> >> ++#include <climits> >> ++#include <locale> >> ++#include <cmath> >> + >> +-#include "double-conversion.h" >> ++#include <double-conversion.h> >> + >> +-#include "bignum-dtoa.h" >> +-#include "fast-dtoa.h" >> +-#include "fixed-dtoa.h" >> +-#include "ieee.h" >> +-#include "strtod.h" >> +-#include "utils.h" >> ++#include <bignum-dtoa.h> >> ++#include <fast-dtoa.h> >> ++#include <fixed-dtoa.h> >> ++#include <ieee.h> >> ++#include <strtod.h> >> ++#include <utils.h> >> + >> + namespace double_conversion { >> + >> +@@ -118,7 +119,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 +130,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 +138,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('.'); >> +@@ -162,7 +163,7 @@ bool DoubleToStringConverter::ToShortestIeeeNumber( >> + double value, >> + StringBuilder* result_builder, >> + DoubleToStringConverter::DtoaMode mode) const { >> +- assert(mode == SHORTEST || mode == SHORTEST_SINGLE); >> ++ ASSERT(mode == SHORTEST || mode == SHORTEST_SINGLE); >> + if (Double(value).IsSpecial()) { >> + return HandleSpecialValues(value, result_builder); >> + } >> +@@ -348,7 +349,6 @@ static BignumDtoaMode DtoaToBignumDtoaMode( >> + case DoubleToStringConverter::PRECISION: return BIGNUM_DTOA_PRECISION; >> + default: >> + UNREACHABLE(); >> +- return BIGNUM_DTOA_SHORTEST; // To silence compiler. >> + } >> + } >> + >> +@@ -403,8 +403,8 @@ void DoubleToStringConverter::DoubleToAscii(double v, >> + vector, length, point); >> + break; >> + default: >> +- UNREACHABLE(); >> + fast_worked = false; >> ++ UNREACHABLE(); >> + } >> + if (fast_worked) return; >> + >> +@@ -415,20 +415,55 @@ 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, >> +- const char* substring) { >> +- ASSERT(**current == *substring); >> ++namespace { >> ++ >> ++inline char ToLower(char ch) { >> ++ static const std::ctype<char>& cType = >> ++ std::use_facet<std::ctype<char> >(std::locale::classic()); >> ++ return cType.tolower(ch); >> ++} >> ++ >> ++inline char Pass(char ch) { >> ++ return ch; >> ++} >> ++ >> ++template <class Iterator, class Converter> >> ++static inline bool ConsumeSubStringImpl(Iterator* current, >> ++ Iterator end, >> ++ const char* substring, >> ++ Converter converter) { >> ++ ASSERT(converter(**current) == *substring); >> + for (substring++; *substring != '\0'; substring++) { >> + ++*current; >> +- if (*current == end || **current != *substring) return false; >> ++ if (*current == end || converter(**current) != *substring) { >> ++ return false; >> ++ } >> + } >> + ++*current; >> + return true; >> + } >> + >> ++// Consumes the given substring from the iterator. >> ++// Returns false, if the substring does not match. >> ++template <class Iterator> >> ++static bool ConsumeSubString(Iterator* current, >> ++ Iterator end, >> ++ const char* substring, >> ++ bool allow_case_insensibility) { >> ++ if (allow_case_insensibility) { >> ++ return ConsumeSubStringImpl(current, end, substring, ToLower); >> ++ } else { >> ++ return ConsumeSubStringImpl(current, end, substring, Pass); >> ++ } >> ++} >> ++ >> ++// Consumes first character of the str is equal to ch >> ++inline bool ConsumeFirstCharacter(char ch, >> ++ const char* str, >> ++ bool case_insensibility) { >> ++ return case_insensibility ? ToLower(ch) == str[0] : ch == str[0]; >> ++} >> ++} // namespace >> + >> + // Maximum number of significant digits in decimal representation. >> + // The longest possible double in decimal representation is >> +@@ -440,10 +475,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; >> +@@ -462,26 +523,57 @@ static double SignedZero(bool sign) { >> + } >> + >> + >> ++// Returns true if 'c' is a decimal digit that is valid for the given >> radix. >> ++// >> ++// The function is small and could be inlined, but VS2012 emitted a warning >> ++// 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'. >> ++// >> ++// The function is small and could be inlined, but VS2012 emitted a warning >> ++// because it constant-propagated the radix and concluded that the first >> ++// condition was always false. By moving it into a separate function the >> ++// compiler wouldn't warn anymore. >> ++static bool IsCharacterDigitForRadix(int c, int radix, char a_character) { >> ++ return radix > 10 && c >= a_character && c < a_character + radix - 10; >> ++} >> ++ >> ++ >> + // 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); >> + } >> + } >> +@@ -492,14 +584,14 @@ static double RadixStringToIeee(const char* current, >> + >> + do { >> + int digit; >> +- if (*current >= '0' && *current <= '9' && *current < '0' + radix) { >> +- digit = static_cast<char>(*current) - '0'; >> +- } else if (radix > 10 && *current >= 'a' && *current < 'a' + radix - >> 10) { >> +- digit = static_cast<char>(*current) - 'a' + 10; >> +- } else if (radix > 10 && *current >= 'A' && *current < 'A' + radix - >> 10) { >> +- 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; >> +@@ -523,14 +615,14 @@ static double RadixStringToIeee(const char* current, >> + exponent = overflow_bits_count; >> + >> + bool zero_tail = true; >> +- while (true) { >> +- ++current; >> +- if (current == end || !isDigit(*current, radix)) break; >> +- zero_tail = zero_tail && *current == '0'; >> ++ for (;;) { >> ++ ++(*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; >> + } >> + >> +@@ -552,13 +644,13 @@ static double RadixStringToIeee(const char* current, >> + } >> + break; >> + } >> +- ++current; >> +- } while (current != end); >> ++ ++(*current); >> ++ } while (*current != end); >> + >> + ASSERT(number < ((int64_t)1 << kSignificandSize)); >> + ASSERT(static_cast<int64_t>(static_cast<double>(number)) == number); >> + >> +- *trailing_pointer = current; >> ++ *result_is_junk = false; >> + >> + if (exponent == 0) { >> + if (sign) { >> +@@ -572,14 +664,14 @@ static double RadixStringToIeee(const char* current, >> + return Double(DiyFp(number, exponent)).value(); >> + } >> + >> +- >> ++template <class Iterator> >> + double StringToDoubleConverter::StringToIeee( >> +- const char* input, >> ++ Iterator input, >> + int length, >> +- int* processed_characters_count, >> +- bool read_as_double) { >> +- 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; >> + >> +@@ -587,6 +679,8 @@ double StringToDoubleConverter::StringToIeee( >> + const bool allow_leading_spaces = (flags_ & ALLOW_LEADING_SPACES) != 0; >> + const bool allow_trailing_spaces = (flags_ & ALLOW_TRAILING_SPACES) != 0; >> + const bool allow_spaces_after_sign = (flags_ & ALLOW_SPACES_AFTER_SIGN) >> != 0; >> ++ const bool allow_case_insensibility = (flags_ & >> ALLOW_CASE_INSENSIBILITY) != 0; >> ++ >> + >> + // To make sure that iterator dereferencing is valid the following >> + // convention is used: >> +@@ -600,7 +694,7 @@ double StringToDoubleConverter::StringToIeee( >> + >> + if (allow_leading_spaces || allow_trailing_spaces) { >> + if (!AdvanceToNonspace(¤t, end)) { >> +- *processed_characters_count = current - input; >> ++ *processed_characters_count = static_cast<int>(current - input); >> + return empty_string_value_; >> + } >> + if (!allow_leading_spaces && (input != current)) { >> +@@ -626,7 +720,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)) { >> +@@ -636,8 +730,8 @@ double StringToDoubleConverter::StringToIeee( >> + } >> + >> + if (infinity_symbol_ != NULL) { >> +- if (*current == infinity_symbol_[0]) { >> +- if (!ConsumeSubString(¤t, end, infinity_symbol_)) { >> ++ if (ConsumeFirstCharacter(*current, infinity_symbol_, >> allow_case_insensibility)) { >> ++ if (!ConsumeSubString(¤t, end, infinity_symbol_, >> allow_case_insensibility)) { >> + return junk_string_value_; >> + } >> + >> +@@ -649,14 +743,14 @@ double StringToDoubleConverter::StringToIeee( >> + } >> + >> + ASSERT(buffer_pos == 0); >> +- *processed_characters_count = current - input; >> ++ *processed_characters_count = static_cast<int>(current - input); >> + return sign ? -Double::Infinity() : Double::Infinity(); >> + } >> + } >> + >> + if (nan_symbol_ != NULL) { >> +- if (*current == nan_symbol_[0]) { >> +- if (!ConsumeSubString(¤t, end, nan_symbol_)) { >> ++ if (ConsumeFirstCharacter(*current, nan_symbol_, >> allow_case_insensibility)) { >> ++ if (!ConsumeSubString(¤t, end, nan_symbol_, >> allow_case_insensibility)) { >> + return junk_string_value_; >> + } >> + >> +@@ -668,7 +762,7 @@ double StringToDoubleConverter::StringToIeee( >> + } >> + >> + ASSERT(buffer_pos == 0); >> +- *processed_characters_count = current - input; >> ++ *processed_characters_count = static_cast<int>(current - input); >> + return sign ? -Double::NaN() : Double::NaN(); >> + } >> + } >> +@@ -677,7 +771,7 @@ double StringToDoubleConverter::StringToIeee( >> + if (*current == '0') { >> + ++current; >> + if (current == end) { >> +- *processed_characters_count = current - input; >> ++ *processed_characters_count = static_cast<int>(current - input); >> + return SignedZero(sign); >> + } >> + >> +@@ -690,17 +784,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 = 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; >> + } >> +@@ -709,7 +803,7 @@ double StringToDoubleConverter::StringToIeee( >> + while (*current == '0') { >> + ++current; >> + if (current == end) { >> +- *processed_characters_count = current - input; >> ++ *processed_characters_count = static_cast<int>(current - input); >> + return SignedZero(sign); >> + } >> + } >> +@@ -757,7 +851,7 @@ double StringToDoubleConverter::StringToIeee( >> + while (*current == '0') { >> + ++current; >> + if (current == end) { >> +- *processed_characters_count = current - input; >> ++ *processed_characters_count = static_cast<int>(current - input); >> + return SignedZero(sign); >> + } >> + exponent--; // Move this 0 into the exponent. >> +@@ -793,20 +887,23 @@ 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_; >> + } >> + } >> +- 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) { >> ++ current = junk_begin; >> + goto parsing_done; >> + } else { >> + return junk_string_value_; >> +@@ -816,6 +913,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_; >> +@@ -837,7 +935,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)) >> { >> +@@ -855,16 +953,17 @@ 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); >> +- *processed_characters_count = current - input; >> ++ &result_is_junk); >> ++ ASSERT(!result_is_junk); >> ++ *processed_characters_count = static_cast<int>(current - input); >> + return result; >> + } >> + >> +@@ -882,8 +981,42 @@ double StringToDoubleConverter::StringToIeee( >> + } else { >> + converted = Strtof(Vector<const char>(buffer, buffer_pos), exponent); >> + } >> +- *processed_characters_count = current - input; >> ++ *processed_characters_count = static_cast<int>(current - input); >> + 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 >> +diff --git a/mfbt/double-conversion/double-conversion.h >> b/mfbt/double-conversion/double-conversion.h >> +index 0e7226d..e66a566 100644 >> +--- a/mfbt/double-conversion/double-conversion.h >> ++++ b/mfbt/double-conversion/double-conversion.h >> +@@ -28,8 +28,7 @@ >> + #ifndef DOUBLE_CONVERSION_DOUBLE_CONVERSION_H_ >> + #define DOUBLE_CONVERSION_DOUBLE_CONVERSION_H_ >> + >> +-#include "mozilla/Types.h" >> +-#include "utils.h" >> ++#include <utils.h> >> + >> + namespace double_conversion { >> + >> +@@ -130,7 +129,7 @@ class DoubleToStringConverter { >> + } >> + >> + // Returns a converter following the EcmaScript specification. >> +- static MFBT_API(const DoubleToStringConverter&) EcmaScriptConverter(); >> ++ static const DoubleToStringConverter& EcmaScriptConverter(); >> + >> + // Computes the shortest string of digits that correctly represent the >> input >> + // number. Depending on decimal_in_shortest_low and >> decimal_in_shortest_high >> +@@ -198,7 +197,7 @@ class DoubleToStringConverter { >> + // The last two conditions imply that the result will never contain more >> than >> + // 1 + kMaxFixedDigitsBeforePoint + 1 + kMaxFixedDigitsAfterPoint >> characters >> + // (one additional character for the sign, and one for the decimal >> point). >> +- MFBT_API(bool) ToFixed(double value, >> ++ bool ToFixed(double value, >> + int requested_digits, >> + StringBuilder* result_builder) const; >> + >> +@@ -230,7 +229,7 @@ class DoubleToStringConverter { >> + // kMaxExponentialDigits + 8 characters (the sign, the digit before the >> + // decimal point, the decimal point, the exponent character, the >> + // exponent's sign, and at most 3 exponent digits). >> +- MFBT_API(bool) ToExponential(double value, >> ++ bool ToExponential(double value, >> + int requested_digits, >> + StringBuilder* result_builder) const; >> + >> +@@ -268,7 +267,7 @@ class DoubleToStringConverter { >> + // The last condition implies that the result will never contain more >> than >> + // kMaxPrecisionDigits + 7 characters (the sign, the decimal point, the >> + // exponent character, the exponent's sign, and at most 3 exponent >> digits). >> +- MFBT_API(bool) ToPrecision(double value, >> ++ bool ToPrecision(double value, >> + int precision, >> + StringBuilder* result_builder) const; >> + >> +@@ -293,15 +292,20 @@ class DoubleToStringConverter { >> + // kBase10MaximalLength. >> + // Note that DoubleToAscii null-terminates its input. So the given buffer >> + // should be at least kBase10MaximalLength + 1 characters long. >> +- static const MFBT_DATA(int) kBase10MaximalLength = 17; >> ++ 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 >> +@@ -333,7 +337,7 @@ class DoubleToStringConverter { >> + // terminating null-character when computing the maximal output size. >> + // The given length is only used in debug mode to ensure the buffer is >> big >> + // enough. >> +- static MFBT_API(void) DoubleToAscii(double v, >> ++ static void DoubleToAscii(double v, >> + DtoaMode mode, >> + int requested_digits, >> + char* buffer, >> +@@ -344,7 +348,7 @@ class DoubleToStringConverter { >> + >> + private: >> + // Implementation for ToShortest and ToShortestSingle. >> +- MFBT_API(bool) ToShortestIeeeNumber(double value, >> ++ bool ToShortestIeeeNumber(double value, >> + StringBuilder* result_builder, >> + DtoaMode mode) const; >> + >> +@@ -352,15 +356,15 @@ class DoubleToStringConverter { >> + // corresponding string using the configured infinity/nan-symbol. >> + // If either of them is NULL or the value is not special then the >> + // function returns false. >> +- MFBT_API(bool) HandleSpecialValues(double value, StringBuilder* >> result_builder) const; >> ++ bool HandleSpecialValues(double value, StringBuilder* result_builder) >> const; >> + // Constructs an exponential representation (i.e. 1.234e56). >> + // The given exponent assumes a decimal point after the first decimal >> digit. >> +- MFBT_API(void) CreateExponentialRepresentation(const char* >> decimal_digits, >> ++ void CreateExponentialRepresentation(const char* decimal_digits, >> + int length, >> + int exponent, >> + StringBuilder* result_builder) >> const; >> + // Creates a decimal representation (i.e 1234.5678). >> +- MFBT_API(void) CreateDecimalRepresentation(const char* decimal_digits, >> ++ void CreateDecimalRepresentation(const char* decimal_digits, >> + int length, >> + int decimal_point, >> + int digits_after_point, >> +@@ -375,7 +379,7 @@ class DoubleToStringConverter { >> + const int max_leading_padding_zeroes_in_precision_mode_; >> + const int max_trailing_padding_zeroes_in_precision_mode_; >> + >> +- DISALLOW_IMPLICIT_CONSTRUCTORS(DoubleToStringConverter); >> ++ DC_DISALLOW_IMPLICIT_CONSTRUCTORS(DoubleToStringConverter); >> + }; >> + >> + >> +@@ -390,7 +394,8 @@ class StringToDoubleConverter { >> + ALLOW_TRAILING_JUNK = 4, >> + ALLOW_LEADING_SPACES = 8, >> + ALLOW_TRAILING_SPACES = 16, >> +- ALLOW_SPACES_AFTER_SIGN = 32 >> ++ ALLOW_SPACES_AFTER_SIGN = 32, >> ++ ALLOW_CASE_INSENSIBILITY = 64, >> + }; >> + >> + // Flags should be a bit-or combination of the possible Flags-enum. >> +@@ -416,11 +421,14 @@ class StringToDoubleConverter { >> + // junk, too. >> + // - ALLOW_TRAILING_JUNK: ignore trailing characters that are not part >> of >> + // a double literal. >> +- // - ALLOW_LEADING_SPACES: skip over leading spaces. >> +- // - ALLOW_TRAILING_SPACES: ignore trailing spaces. >> +- // - ALLOW_SPACES_AFTER_SIGN: ignore spaces after the sign. >> ++ // - ALLOW_LEADING_SPACES: skip over leading whitespace, including >> spaces, >> ++ // new-lines, and tabs. >> ++ // - ALLOW_TRAILING_SPACES: ignore trailing whitespace. >> ++ // - ALLOW_SPACES_AFTER_SIGN: ignore whitespace after the sign. >> + // Ex: StringToDouble("- 123.2") -> -123.2. >> + // StringToDouble("+ 123.2") -> 123.2 >> ++ // - ALLOW_CASE_INSENSIBILITY: ignore case of characters for special >> values: >> ++ // infinity and nan. >> + // >> + // empty_string_value is returned when an empty string is given as input. >> + // If ALLOW_LEADING_SPACES or ALLOW_TRAILING_SPACES are set, then a >> string >> +@@ -503,19 +511,24 @@ class StringToDoubleConverter { >> + // in the 'processed_characters_count'. Trailing junk is never included. >> + double StringToDouble(const char* buffer, >> + int length, >> +- int* processed_characters_count) { >> +- return StringToIeee(buffer, length, processed_characters_count, true); >> +- } >> ++ int* processed_characters_count) const; >> ++ >> ++ // Same as StringToDouble above but for 16 bit characters. >> ++ double StringToDouble(const uc16* buffer, >> ++ int length, >> ++ int* processed_characters_count) const; >> + >> + // Same as StringToDouble but reads a float. >> + // Note that this is not equivalent to >> static_cast<float>(StringToDouble(...)) >> + // due to potential double-rounding. >> + float StringToFloat(const char* buffer, >> + int length, >> +- int* processed_characters_count) { >> +- return static_cast<float>(StringToIeee(buffer, length, >> +- processed_characters_count, >> false)); >> +- } >> ++ int* processed_characters_count) const; >> ++ >> ++ // Same as StringToFloat above but for 16 bit characters. >> ++ float StringToFloat(const uc16* buffer, >> ++ int length, >> ++ int* processed_characters_count) const; >> + >> + private: >> + const int flags_; >> +@@ -524,12 +537,13 @@ class StringToDoubleConverter { >> + const char* const infinity_symbol_; >> + const char* const nan_symbol_; >> + >> +- double StringToIeee(const char* buffer, >> ++ template <class Iterator> >> ++ double StringToIeee(Iterator start_pointer, >> + int length, >> +- int* processed_characters_count, >> +- bool read_as_double); >> ++ bool read_as_double, >> ++ int* processed_characters_count) const; >> + >> +- DISALLOW_IMPLICIT_CONSTRUCTORS(StringToDoubleConverter); >> ++ DC_DISALLOW_IMPLICIT_CONSTRUCTORS(StringToDoubleConverter); >> + }; >> + >> + } // namespace double_conversion >> +diff --git a/mfbt/double-conversion/fast-dtoa.cc >> b/mfbt/double-conversion/fast-dtoa.cc >> +index 0609422..d338216 100644 >> +--- a/mfbt/double-conversion/fast-dtoa.cc >> ++++ b/mfbt/double-conversion/fast-dtoa.cc >> +@@ -25,11 +25,11 @@ >> + // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE >> + // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. >> + >> +-#include "fast-dtoa.h" >> ++#include <fast-dtoa.h> >> + >> +-#include "cached-powers.h" >> +-#include "diy-fp.h" >> +-#include "ieee.h" >> ++#include <cached-powers.h> >> ++#include <diy-fp.h> >> ++#include <ieee.h> >> + >> + namespace double_conversion { >> + >> +@@ -248,10 +248,7 @@ static void BiggestPowerTen(uint32_t number, >> + // Note: kPowersOf10[i] == 10^(i-1). >> + exponent_plus_one_guess++; >> + // We don't have any guarantees that 2^number_bits <= number. >> +- // TODO(floitsch): can we change the 'while' into an 'if'? We definitely >> see >> +- // number < (2^number_bits - 1), but I haven't encountered >> +- // number < (2^number_bits - 2) yet. >> +- while (number < kSmallPowersOfTen[exponent_plus_one_guess]) { >> ++ if (number < kSmallPowersOfTen[exponent_plus_one_guess]) { >> + exponent_plus_one_guess--; >> + } >> + *power = kSmallPowersOfTen[exponent_plus_one_guess]; >> +@@ -350,7 +347,8 @@ static bool DigitGen(DiyFp low, >> + // that is smaller than integrals. >> + while (*kappa > 0) { >> + int digit = integrals / divisor; >> +- buffer[*length] = '0' + digit; >> ++ ASSERT(digit <= 9); >> ++ buffer[*length] = static_cast<char>('0' + digit); >> + (*length)++; >> + integrals %= divisor; >> + (*kappa)--; >> +@@ -379,13 +377,14 @@ static bool DigitGen(DiyFp low, >> + ASSERT(one.e() >= -60); >> + ASSERT(fractionals < one.f()); >> + ASSERT(UINT64_2PART_C(0xFFFFFFFF, FFFFFFFF) / 10 >= one.f()); >> +- while (true) { >> ++ for (;;) { >> + fractionals *= 10; >> + unit *= 10; >> + unsafe_interval.set_f(unsafe_interval.f() * 10); >> + // Integer division by one. >> + int digit = static_cast<int>(fractionals >> -one.e()); >> +- buffer[*length] = '0' + digit; >> ++ ASSERT(digit <= 9); >> ++ buffer[*length] = static_cast<char>('0' + digit); >> + (*length)++; >> + fractionals &= one.f() - 1; // Modulo by one. >> + (*kappa)--; >> +@@ -459,7 +458,8 @@ static bool DigitGenCounted(DiyFp w, >> + // that is smaller than 'integrals'. >> + while (*kappa > 0) { >> + int digit = integrals / divisor; >> +- buffer[*length] = '0' + digit; >> ++ ASSERT(digit <= 9); >> ++ buffer[*length] = static_cast<char>('0' + digit); >> + (*length)++; >> + requested_digits--; >> + integrals %= divisor; >> +@@ -492,7 +492,8 @@ static bool DigitGenCounted(DiyFp w, >> + w_error *= 10; >> + // Integer division by one. >> + int digit = static_cast<int>(fractionals >> -one.e()); >> +- buffer[*length] = '0' + digit; >> ++ ASSERT(digit <= 9); >> ++ buffer[*length] = static_cast<char>('0' + digit); >> + (*length)++; >> + requested_digits--; >> + fractionals &= one.f() - 1; // Modulo by one. >> +@@ -529,7 +530,7 @@ static bool Grisu3(double v, >> + if (mode == FAST_DTOA_SHORTEST) { >> + Double(v).NormalizedBoundaries(&boundary_minus, &boundary_plus); >> + } else { >> +- assert(mode == FAST_DTOA_SHORTEST_SINGLE); >> ++ ASSERT(mode == FAST_DTOA_SHORTEST_SINGLE); >> + float single_v = static_cast<float>(v); >> + Single(single_v).NormalizedBoundaries(&boundary_minus, &boundary_plus); >> + } >> +diff --git a/mfbt/double-conversion/fast-dtoa.h >> b/mfbt/double-conversion/fast-dtoa.h >> +index 5f1e8ee..9c4da92 100644 >> +--- a/mfbt/double-conversion/fast-dtoa.h >> ++++ b/mfbt/double-conversion/fast-dtoa.h >> +@@ -28,7 +28,7 @@ >> + #ifndef DOUBLE_CONVERSION_FAST_DTOA_H_ >> + #define DOUBLE_CONVERSION_FAST_DTOA_H_ >> + >> +-#include "utils.h" >> ++#include <utils.h> >> + >> + namespace double_conversion { >> + >> +diff --git a/mfbt/double-conversion/fixed-dtoa.cc >> b/mfbt/double-conversion/fixed-dtoa.cc >> +index d56b144..fa23529 100644 >> +--- a/mfbt/double-conversion/fixed-dtoa.cc >> ++++ b/mfbt/double-conversion/fixed-dtoa.cc >> +@@ -25,10 +25,10 @@ >> + // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE >> + // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. >> + >> +-#include <math.h> >> ++#include <cmath> >> + >> +-#include "fixed-dtoa.h" >> +-#include "ieee.h" >> ++#include <fixed-dtoa.h> >> ++#include <ieee.h> >> + >> + namespace double_conversion { >> + >> +@@ -98,7 +98,7 @@ class UInt128 { >> + return high_bits_ == 0 && low_bits_ == 0; >> + } >> + >> +- int BitAt(int position) { >> ++ int BitAt(int position) const { >> + if (position >= 64) { >> + return static_cast<int>(high_bits_ >> (position - 64)) & 1; >> + } else { >> +@@ -133,7 +133,7 @@ static void FillDigits32(uint32_t number, Vector<char> >> buffer, int* length) { >> + while (number != 0) { >> + int digit = number % 10; >> + number /= 10; >> +- buffer[(*length) + number_length] = '0' + digit; >> ++ buffer[(*length) + number_length] = static_cast<char>('0' + digit); >> + number_length++; >> + } >> + // Exchange the digits. >> +@@ -150,7 +150,7 @@ static void FillDigits32(uint32_t number, Vector<char> >> buffer, int* length) { >> + } >> + >> + >> +-static void FillDigits64FixedLength(uint64_t number, int requested_length, >> ++static void FillDigits64FixedLength(uint64_t number, >> + Vector<char> buffer, int* length) { >> + const uint32_t kTen7 = 10000000; >> + // For efficiency cut the number into 3 uint32_t parts, and print those. >> +@@ -253,12 +253,14 @@ static void FillFractionals(uint64_t fractionals, int >> exponent, >> + fractionals *= 5; >> + point--; >> + int digit = static_cast<int>(fractionals >> point); >> +- buffer[*length] = '0' + digit; >> ++ ASSERT(digit <= 9); >> ++ buffer[*length] = static_cast<char>('0' + digit); >> + (*length)++; >> + fractionals -= static_cast<uint64_t>(digit) << point; >> + } >> + // If the first bit after the point is set we have to round up. >> +- if (((fractionals >> (point - 1)) & 1) == 1) { >> ++ ASSERT(fractionals == 0 || point - 1 >= 0); >> ++ if ((fractionals != 0) && ((fractionals >> (point - 1)) & 1) == 1) { >> + RoundUp(buffer, length, decimal_point); >> + } >> + } else { // We need 128 bits. >> +@@ -274,7 +276,8 @@ static void FillFractionals(uint64_t fractionals, int >> exponent, >> + fractionals128.Multiply(5); >> + point--; >> + int digit = fractionals128.DivModPowerOf2(point); >> +- buffer[*length] = '0' + digit; >> ++ ASSERT(digit <= 9); >> ++ buffer[*length] = static_cast<char>('0' + digit); >> + (*length)++; >> + } >> + if (fractionals128.BitAt(point - 1) == 1) { >> +@@ -358,7 +361,7 @@ bool FastFixedDtoa(double v, >> + remainder = (dividend % divisor) << exponent; >> + } >> + FillDigits32(quotient, buffer, length); >> +- FillDigits64FixedLength(remainder, divisor_power, buffer, length); >> ++ FillDigits64FixedLength(remainder, buffer, length); >> + *decimal_point = *length; >> + } else if (exponent >= 0) { >> + // 0 <= exponent <= 11 >> +diff --git a/mfbt/double-conversion/fixed-dtoa.h >> b/mfbt/double-conversion/fixed-dtoa.h >> +index 3bdd08e..19fd2e7 100644 >> +--- a/mfbt/double-conversion/fixed-dtoa.h >> ++++ b/mfbt/double-conversion/fixed-dtoa.h >> +@@ -28,7 +28,7 @@ >> + #ifndef DOUBLE_CONVERSION_FIXED_DTOA_H_ >> + #define DOUBLE_CONVERSION_FIXED_DTOA_H_ >> + >> +-#include "utils.h" >> ++#include <utils.h> >> + >> + namespace double_conversion { >> + >> +diff --git a/mfbt/double-conversion/ieee.h b/mfbt/double-conversion/ieee.h >> +index 839dc47..8949b02 100644 >> +--- a/mfbt/double-conversion/ieee.h >> ++++ b/mfbt/double-conversion/ieee.h >> +@@ -28,7 +28,7 @@ >> + #ifndef DOUBLE_CONVERSION_DOUBLE_H_ >> + #define DOUBLE_CONVERSION_DOUBLE_H_ >> + >> +-#include "diy-fp.h" >> ++#include <diy-fp.h> >> + >> + namespace double_conversion { >> + >> +@@ -99,7 +99,7 @@ class Double { >> + } >> + >> + double PreviousDouble() const { >> +- if (d64_ == (kInfinity | kSignMask)) return -Double::Infinity(); >> ++ if (d64_ == (kInfinity | kSignMask)) return -Infinity(); >> + if (Sign() < 0) { >> + return Double(d64_ + 1).value(); >> + } else { >> +@@ -256,6 +256,8 @@ class Double { >> + return (significand & kSignificandMask) | >> + (biased_exponent << kPhysicalSignificandSize); >> + } >> ++ >> ++ DC_DISALLOW_COPY_AND_ASSIGN(Double); >> + }; >> + >> + class Single { >> +@@ -391,6 +393,8 @@ class Single { >> + static const uint32_t kNaN = 0x7FC00000; >> + >> + const uint32_t d32_; >> ++ >> ++ DC_DISALLOW_COPY_AND_ASSIGN(Single); >> + }; >> + >> + } // namespace double_conversion >> +diff --git a/mfbt/double-conversion/strtod.cc >> b/mfbt/double-conversion/strtod.cc >> +index d773f44..a9e85c1 100644 >> +--- a/mfbt/double-conversion/strtod.cc >> ++++ b/mfbt/double-conversion/strtod.cc >> +@@ -25,13 +25,13 @@ >> + // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE >> + // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. >> + >> +-#include <stdarg.h> >> +-#include <limits.h> >> ++#include <climits> >> ++#include <cstdarg> >> + >> +-#include "strtod.h" >> +-#include "bignum.h" >> +-#include "cached-powers.h" >> +-#include "ieee.h" >> ++#include <bignum.h> >> ++#include <cached-powers.h> >> ++#include <ieee.h> >> ++#include <strtod.h> >> + >> + namespace double_conversion { >> + >> +@@ -137,6 +137,7 @@ static void TrimAndCut(Vector<const char> buffer, int >> exponent, >> + Vector<const char> right_trimmed = TrimTrailingZeros(left_trimmed); >> + exponent += left_trimmed.length() - right_trimmed.length(); >> + if (right_trimmed.length() > kMaxSignificantDecimalDigits) { >> ++ (void) space_size; // Mark variable as used. >> + ASSERT(space_size >= kMaxSignificantDecimalDigits); >> + CutToMaxSignificantDigits(right_trimmed, exponent, >> + buffer_copy_space, updated_exponent); >> +@@ -204,7 +205,7 @@ static bool DoubleStrtod(Vector<const char> trimmed, >> + // Note that the ARM simulator is compiled for 32bits. It therefore >> exhibits >> + // the same problem. >> + return false; >> +-#endif >> ++#else >> + if (trimmed.length() <= kMaxExactDoubleIntegerDecimalDigits) { >> + int read_digits; >> + // The trimmed input fits into a double. >> +@@ -242,6 +243,7 @@ static bool DoubleStrtod(Vector<const char> trimmed, >> + } >> + } >> + return false; >> ++#endif >> + } >> + >> + >> +@@ -263,7 +265,6 @@ static DiyFp AdjustmentPowerOfTen(int exponent) { >> + case 7: return DiyFp(UINT64_2PART_C(0x98968000, 00000000), -40); >> + default: >> + UNREACHABLE(); >> +- return DiyFp(0, 0); >> + } >> + } >> + >> +@@ -286,7 +287,7 @@ static bool DiyFpStrtod(Vector<const char> buffer, >> + const int kDenominator = 1 << kDenominatorLog; >> + // Move the remaining decimals into the exponent. >> + exponent += remaining_decimals; >> +- int error = (remaining_decimals == 0 ? 0 : kDenominator / 2); >> ++ uint64_t error = (remaining_decimals == 0 ? 0 : kDenominator / 2); >> + >> + int old_e = input.e(); >> + input.Normalize(); >> +@@ -471,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; >> +@@ -482,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; >> +@@ -505,18 +530,18 @@ 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; >> +- assert(f1 <= f2 && f2 <= f3 && f3 <= f4); >> ++ (void) f2; // Mark variable as used. >> ++ ASSERT(f1 <= f2 && f2 <= f3 && f3 <= f4); >> + >> + // If the guess doesn't lie near a single-precision boundary we can >> simply >> + // return its float-value. >> +@@ -524,11 +549,11 @@ float Strtof(Vector<const char> buffer, int exponent) >> { >> + return float_guess; >> + } >> + >> +- assert((f1 != f2 && f2 == f3 && f3 == f4) || >> ++ ASSERT((f1 != f2 && f2 == f3 && f3 == f4) || >> + (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; >> +diff --git a/mfbt/double-conversion/strtod.h >> b/mfbt/double-conversion/strtod.h >> +index ed0293b..58c4926 100644 >> +--- a/mfbt/double-conversion/strtod.h >> ++++ b/mfbt/double-conversion/strtod.h >> +@@ -28,7 +28,7 @@ >> + #ifndef DOUBLE_CONVERSION_STRTOD_H_ >> + #define DOUBLE_CONVERSION_STRTOD_H_ >> + >> +-#include "utils.h" >> ++#include <utils.h> >> + >> + namespace double_conversion { >> + >> +diff --git a/mfbt/double-conversion/utils.h b/mfbt/double-conversion/utils.h >> +index 0eec2d9..a748654 100644 >> +--- a/mfbt/double-conversion/utils.h >> ++++ b/mfbt/double-conversion/utils.h >> +@@ -28,19 +28,34 @@ >> + #ifndef DOUBLE_CONVERSION_UTILS_H_ >> + #define DOUBLE_CONVERSION_UTILS_H_ >> + >> +-#include <stdlib.h> >> +-#include <string.h> >> ++#include <cstdlib> >> ++#include <cstring> >> + >> +-#include <assert.h> >> ++#include <cassert> >> + #ifndef ASSERT >> +-#define ASSERT(condition) (assert(condition)) >> ++#define ASSERT(condition) \ >> ++ assert(condition); >> + #endif >> + #ifndef UNIMPLEMENTED >> + #define UNIMPLEMENTED() (abort()) >> + #endif >> ++#ifndef DOUBLE_CONVERSION_NO_RETURN >> ++#ifdef _MSC_VER >> ++#define DOUBLE_CONVERSION_NO_RETURN __declspec(noreturn) >> ++#else >> ++#define DOUBLE_CONVERSION_NO_RETURN __attribute__((noreturn)) >> ++#endif >> ++#endif >> + #ifndef UNREACHABLE >> ++#ifdef _MSC_VER >> ++void DOUBLE_CONVERSION_NO_RETURN abort_noreturn(); >> ++inline void abort_noreturn() { abort(); } >> ++#define UNREACHABLE() (abort_noreturn()) >> ++#else >> + #define UNREACHABLE() (abort()) >> + #endif >> ++#endif >> ++ >> + >> + // Double operations detection based on target architecture. >> + // Linux uses a 80bit wide floating point stack on x86. This induces double >> +@@ -55,11 +70,18 @@ >> + #if defined(_M_X64) || defined(__x86_64__) || \ >> + defined(__ARMEL__) || defined(__avr32__) || \ >> + defined(__hppa__) || defined(__ia64__) || \ >> +- defined(__mips__) || defined(__powerpc__) || \ >> ++ defined(__mips__) || \ >> ++ defined(__powerpc__) || defined(__ppc__) || defined(__ppc64__) || \ >> ++ defined(_POWER) || defined(_ARCH_PPC) || defined(_ARCH_PPC64) || \ >> + defined(__sparc__) || defined(__sparc) || defined(__s390__) || \ >> + defined(__SH4__) || defined(__alpha__) || \ >> +- defined(_MIPS_ARCH_MIPS32R2) >> ++ defined(_MIPS_ARCH_MIPS32R2) || \ >> ++ defined(__AARCH64EL__) || defined(__aarch64__) || \ >> ++ defined(__riscv) >> + #define DOUBLE_CONVERSION_CORRECT_DOUBLE_OPERATIONS 1 >> ++#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) >> + // Windows uses a 64bit wide floating point stack. >> +@@ -71,9 +93,10 @@ >> + #error Target architecture was not detected as supported by >> Double-Conversion. >> + #endif >> + >> +- >> + #include "mozilla/StandardInteger.h" >> + >> ++typedef uint16_t uc16; >> ++ >> + // The following macro works on both 32 and 64-bit platforms. >> + // Usage: instead of writing 0x1234567890123456 >> + // write UINT64_2PART_C(0x12345678,90123456); >> +@@ -92,8 +115,8 @@ >> + >> + // A macro to disallow the evil copy constructor and operator= functions >> + // This should be used in the private: declarations for a class >> +-#ifndef DISALLOW_COPY_AND_ASSIGN >> +-#define DISALLOW_COPY_AND_ASSIGN(TypeName) \ >> ++#ifndef DC_DISALLOW_COPY_AND_ASSIGN >> ++#define DC_DISALLOW_COPY_AND_ASSIGN(TypeName) \ >> + TypeName(const TypeName&); \ >> + void operator=(const TypeName&) >> + #endif >> +@@ -104,10 +127,10 @@ >> + // This should be used in the private: declarations for a class >> + // that wants to prevent anyone from instantiating it. This is >> + // especially useful for classes containing only static methods. >> +-#ifndef DISALLOW_IMPLICIT_CONSTRUCTORS >> +-#define DISALLOW_IMPLICIT_ -- _______________________________________________ Openembedded-devel mailing list Openembedded-devel@lists.openembedded.org http://lists.openembedded.org/mailman/listinfo/openembedded-devel