Fixed makeString(float) to do shortest-form serialization without first converting...
authordarin@apple.com <darin@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Sat, 2 Mar 2019 20:54:59 +0000 (20:54 +0000)
committerdarin@apple.com <darin@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Sat, 2 Mar 2019 20:54:59 +0000 (20:54 +0000)
https://bugs.webkit.org/show_bug.cgi?id=195142

Reviewed by Daniel Bates.

Source/WebCore:

* platform/graphics/Color.cpp: Removed unneeded include of DecimalNumber.h.

Source/WebKit:

* UIProcess/PerActivityStateCPUUsageSampler.cpp: Removed unneeded include of DecimalNumber.h.

Source/WTF:

* wtf/DecimalNumber.cpp: Removed unneeded includes.

* wtf/DecimalNumber.h: Removed unused constructors; over time we will be
deprecating DecimalNumber, so we should removed the unused parts. Also
marked the constructor explicit, removed types used only for arguments for
the constructors, and removed the sign, exponent, significand, and precision
member functions.

* wtf/JSONValues.cpp:
(WTF::JSONImpl::Value::writeJSON const): Updated for changes to DecimalNumber
switched from NumberToLStringBuffer to NumberToStringBuffer, and for use of
std::array instead of C arrays.

* wtf/dtoa.cpp: Removed unused dtoaRoundSF and dtoaRoundDP functions.
(WTF::dtoa): Updated to use std::array instead of C arrays.
(WTF::dtoaRoundSF): Removed.
(WTF::dtoaRoundDP): Removed.
(WTF::numberToString): Added an overload for float and updated to use std::array.
(WTF::formatStringTruncatingTrailingZerosIfNeeded): Updated to use std::array.
(WTF::numberToFixedPrecisionString): Ditto.
(WTF::numberToFixedWidthString): Ditto.

* wtf/dtoa.h: Changed arrays to be std::array instead of C arrays so the
array types will be checked. Removed dtoaRoundSF and dtoaRoundDP.
Added float overloads for numberToString, numberToFixedPrecisionString,
and numberToFixedWidthString. The only one of these that is called at this
time is numberToString, called by the floating point StringTypeAdapter in
StringConcatenateNummbers.h.

* wtf/text/StringConcatenateNumbers.h: Updated for std::array.

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@242316 268f45cc-cd09-0410-ab3c-d52691b4dbfc

Source/WTF/ChangeLog
Source/WTF/wtf/DecimalNumber.cpp
Source/WTF/wtf/DecimalNumber.h
Source/WTF/wtf/JSONValues.cpp
Source/WTF/wtf/dtoa.cpp
Source/WTF/wtf/dtoa.h
Source/WTF/wtf/text/StringConcatenateNumbers.h
Source/WebCore/ChangeLog
Source/WebCore/platform/graphics/Color.cpp
Source/WebKit/ChangeLog
Source/WebKit/UIProcess/PerActivityStateCPUUsageSampler.cpp

index 1978387..b31a3b7 100644 (file)
@@ -1,3 +1,41 @@
+2019-02-27  Darin Adler  <darin@apple.com>
+
+        Fixed makeString(float) to do shortest-form serialization without first converting to double
+        https://bugs.webkit.org/show_bug.cgi?id=195142
+
+        Reviewed by Daniel Bates.
+
+        * wtf/DecimalNumber.cpp: Removed unneeded includes.
+
+        * wtf/DecimalNumber.h: Removed unused constructors; over time we will be
+        deprecating DecimalNumber, so we should removed the unused parts. Also
+        marked the constructor explicit, removed types used only for arguments for
+        the constructors, and removed the sign, exponent, significand, and precision
+        member functions.
+
+        * wtf/JSONValues.cpp:
+        (WTF::JSONImpl::Value::writeJSON const): Updated for changes to DecimalNumber
+        switched from NumberToLStringBuffer to NumberToStringBuffer, and for use of
+        std::array instead of C arrays.
+
+        * wtf/dtoa.cpp: Removed unused dtoaRoundSF and dtoaRoundDP functions.
+        (WTF::dtoa): Updated to use std::array instead of C arrays.
+        (WTF::dtoaRoundSF): Removed.
+        (WTF::dtoaRoundDP): Removed.
+        (WTF::numberToString): Added an overload for float and updated to use std::array.
+        (WTF::formatStringTruncatingTrailingZerosIfNeeded): Updated to use std::array.
+        (WTF::numberToFixedPrecisionString): Ditto.
+        (WTF::numberToFixedWidthString): Ditto.
+
+        * wtf/dtoa.h: Changed arrays to be std::array instead of C arrays so the
+        array types will be checked. Removed dtoaRoundSF and dtoaRoundDP.
+        Added float overloads for numberToString, numberToFixedPrecisionString,
+        and numberToFixedWidthString. The only one of these that is called at this
+        time is numberToString, called by the floating point StringTypeAdapter in
+        StringConcatenateNummbers.h.
+
+        * wtf/text/StringConcatenateNumbers.h: Updated for std::array.
+
 2019-03-01  Darin Adler  <darin@apple.com>
 
         Finish removing String::format
index d9667b3..c722ce5 100644 (file)
@@ -26,9 +26,7 @@
 #include "config.h"
 #include <wtf/DecimalNumber.h>
 
-#include <math.h>
 #include <wtf/MathExtras.h>
-#include <wtf/text/WTFString.h>
 
 namespace WTF {
 
index d5cf340..ac4eff7 100644 (file)
 
 #pragma once
 
-#include <math.h>
+#include <cmath>
 #include <wtf/dtoa.h>
-#include <wtf/MathExtras.h>
-#include <wtf/text/WTFString.h>
 
 namespace WTF {
 
-enum RoundingSignificantFiguresType { RoundingSignificantFigures };
-enum RoundingDecimalPlacesType { RoundingDecimalPlaces };
-
 class DecimalNumber {
 public:
-    DecimalNumber(double d)
+    explicit DecimalNumber(double d)
     {
         ASSERT(std::isfinite(d));
         dtoa(m_significand, d, m_sign, m_exponent, m_precision);
@@ -51,46 +46,12 @@ public:
         ASSERT(m_significand[0] == '0' || m_significand[m_precision - 1] != '0');
     }
 
-    DecimalNumber(double d, RoundingSignificantFiguresType, unsigned significantFigures)
-    {
-        ASSERT(std::isfinite(d));
-        dtoaRoundSF(m_significand, d, significantFigures, m_sign, m_exponent, m_precision);
-
-        ASSERT_WITH_SECURITY_IMPLICATION(significantFigures && significantFigures <= sizeof(DtoaBuffer));
-        while (m_precision < significantFigures)
-            m_significand[m_precision++] = '0';
-
-        ASSERT(m_precision);
-        // Zero should always have exponent 0.
-        ASSERT(m_significand[0] != '0' || !m_exponent);
-    }
-
-    DecimalNumber(double d, RoundingDecimalPlacesType, unsigned decimalPlaces)
-    {
-        ASSERT(std::isfinite(d));
-        dtoaRoundDP(m_significand, d, decimalPlaces, m_sign, m_exponent, m_precision);
-
-        unsigned significantFigures = 1 + m_exponent + decimalPlaces;
-        ASSERT_WITH_SECURITY_IMPLICATION(significantFigures && significantFigures <= sizeof(DtoaBuffer));
-        while (m_precision < significantFigures)
-            m_significand[m_precision++] = '0';
-
-        ASSERT(m_precision);
-        // Zero should always have exponent 0.
-        ASSERT(m_significand[0] != '0' || !m_exponent);
-    }
-
     WTF_EXPORT_PRIVATE unsigned bufferLengthForStringDecimal() const;
     WTF_EXPORT_PRIVATE unsigned bufferLengthForStringExponential() const;
 
     WTF_EXPORT_PRIVATE unsigned toStringDecimal(LChar* buffer, unsigned bufferLength) const;
     WTF_EXPORT_PRIVATE unsigned toStringExponential(LChar* buffer, unsigned bufferLength) const;
 
-    bool sign() const { return m_sign; }
-    int exponent() const { return m_exponent; }
-    const char* significand() const { return m_significand; } // significand contains precision characters, is not null-terminated.
-    unsigned precision() const { return m_precision; }
-
 private:
     bool m_sign;
     int m_exponent;
@@ -101,5 +62,3 @@ private:
 } // namespace WTF
 
 using WTF::DecimalNumber;
-using WTF::RoundingSignificantFigures;
-using WTF::RoundingDecimalPlaces;
index c02fee5..a0ee101 100644 (file)
@@ -673,24 +673,24 @@ void Value::writeJSON(StringBuilder& output) const
         break;
     case Type::Double:
     case Type::Integer: {
-        NumberToLStringBuffer buffer;
         if (!std::isfinite(m_value.number)) {
             output.appendLiteral("null");
             return;
         }
-        DecimalNumber decimal = m_value.number;
+        DecimalNumber decimal { m_value.number };
+        NumberToStringBuffer buffer;
         unsigned length = 0;
-        if (decimal.bufferLengthForStringDecimal() > WTF::NumberToStringBufferLength) {
+        if (decimal.bufferLengthForStringDecimal() > sizeof(buffer)) {
             // Not enough room for decimal. Use exponential format.
-            if (decimal.bufferLengthForStringExponential() > WTF::NumberToStringBufferLength) {
+            if (decimal.bufferLengthForStringExponential() > sizeof(buffer)) {
                 // Fallback for an abnormal case if it's too little even for exponential.
                 output.appendLiteral("NaN");
                 return;
             }
-            length = decimal.toStringExponential(buffer, WTF::NumberToStringBufferLength);
+            length = decimal.toStringExponential(reinterpret_cast<LChar*>(&buffer[0]), sizeof(buffer));
         } else
-            length = decimal.toStringDecimal(buffer, WTF::NumberToStringBufferLength);
-        output.append(buffer, length);
+            length = decimal.toStringDecimal(reinterpret_cast<LChar*>(&buffer[0]), sizeof(buffer));
+        output.append(&buffer[0], length);
         break;
     }
     default:
index 683314f..f91051e 100644 (file)
@@ -3,7 +3,7 @@
  * The author of this software is David M. Gay.
  *
  * Copyright (c) 1991, 2000, 2001 by Lucent Technologies.
- * Copyright (C) 2002-2017 Apple Inc. All rights reserved.
+ * Copyright (C) 2002-2019 Apple Inc. All rights reserved.
  *
  * Permission to use, copy, modify, and distribute this software for any
  * purpose without fee is hereby granted, provided that this entire notice
@@ -728,17 +728,9 @@ static ALWAYS_INLINE int quorem(BigInt& b, BigInt& S)
  *       "uniformly" distributed input, the probability is
  *       something like 10^(k-15) that we must resort to the int32_t
  *       calculation.
- *
- * Note: 'leftright' translates to 'generate shortest possible string'.
  */
-template<bool roundingNone, bool roundingSignificantFigures, bool roundingDecimalPlaces, bool leftright>
-void dtoa(DtoaBuffer result, double dd, int ndigits, bool& signOut, int& exponentOut, unsigned& precisionOut)
+void dtoa(DtoaBuffer& result, double dd, bool& signOut, int& exponentOut, unsigned& precisionOut)
 {
-    // Exactly one rounding mode must be specified.
-    ASSERT(roundingNone + roundingSignificantFigures + roundingDecimalPlaces == 1);
-    // roundingNone only allowed (only sensible?) with leftright set.
-    ASSERT(!roundingNone || leftright);
-
     ASSERT(std::isfinite(dd));
 
     int bbits, b2, b5, be, dig, i, ieps, ilim = 0, ilim0, ilim1 = 0,
@@ -843,25 +835,10 @@ void dtoa(DtoaBuffer result, double dd, int ndigits, bool& signOut, int& exponen
         s5 = 0;
     }
 
-    if (roundingNone) {
-        ilim = ilim1 = -1;
-        i = 18;
-        ndigits = 0;
-    }
-    if (roundingSignificantFigures) {
-        if (ndigits <= 0)
-            ndigits = 1;
-        ilim = ilim1 = i = ndigits;
-    }
-    if (roundingDecimalPlaces) {
-        i = ndigits + k + 1;
-        ilim = i;
-        ilim1 = i - 1;
-        if (i <= 0)
-            i = 1;
-    }
+    ilim = ilim1 = -1;
+    i = 18;
 
-    s = s0 = result;
+    s = s0 = &result[0];
 
     if (ilim >= 0 && ilim <= Quick_max) {
         /* Try to get by with floating-point arithmetic. */
@@ -916,43 +893,22 @@ void dtoa(DtoaBuffer result, double dd, int ndigits, bool& signOut, int& exponen
                 goto noDigits;
             goto fastFailed;
         }
-        if (leftright) {
-            /* Use Steele & White method of only
-             * generating digits needed.
-             */
-            dval(&eps) = (0.5 / tens[ilim - 1]) - dval(&eps);
-            for (i = 0;;) {
-                L = (long int)dval(&u);
-                dval(&u) -= L;
-                *s++ = '0' + (int)L;
-                if (dval(&u) < dval(&eps))
-                    goto ret;
-                if (1. - dval(&u) < dval(&eps))
-                    goto bumpUp;
-                if (++i >= ilim)
-                    break;
-                dval(&eps) *= 10.;
-                dval(&u) *= 10.;
-            }
-        } else {
-            /* Generate ilim digits, then fix them up. */
-            dval(&eps) *= tens[ilim - 1];
-            for (i = 1;; i++, dval(&u) *= 10.) {
-                L = (int32_t)(dval(&u));
-                if (!(dval(&u) -= L))
-                    ilim = i;
-                *s++ = '0' + (int)L;
-                if (i == ilim) {
-                    if (dval(&u) > 0.5 + dval(&eps))
-                        goto bumpUp;
-                    if (dval(&u) < 0.5 - dval(&eps)) {
-                        while (*--s == '0') { }
-                        s++;
-                        goto ret;
-                    }
-                    break;
-                }
-            }
+        /* Use Steele & White method of only
+         * generating digits needed.
+         */
+        dval(&eps) = (0.5 / tens[ilim - 1]) - dval(&eps);
+        for (i = 0;;) {
+            L = (long int)dval(&u);
+            dval(&u) -= L;
+            *s++ = '0' + (int)L;
+            if (dval(&u) < dval(&eps))
+                goto ret;
+            if (1. - dval(&u) < dval(&eps))
+                goto bumpUp;
+            if (++i >= ilim)
+                break;
+            dval(&eps) *= 10.;
+            dval(&u) *= 10.;
         }
 fastFailed:
         s = s0;
@@ -966,13 +922,6 @@ fastFailed:
     if (be >= 0 && k <= Int_max) {
         /* Yes. */
         ds = tens[k];
-        if (ndigits < 0 && ilim <= 0) {
-            S.clear();
-            mhi.clear();
-            if (ilim < 0 || dval(&u) <= 5 * ds)
-                goto noDigits;
-            goto oneDigit;
-        }
         for (i = 1;; i++, dval(&u) *= 10.) {
             L = (int32_t)(dval(&u) / ds);
             dval(&u) -= L * ds;
@@ -1002,12 +951,10 @@ bumpUp:
     m5 = b5;
     mhi.clear();
     mlo.clear();
-    if (leftright) {
-        i = denorm ? be + (Bias + (P - 1) - 1 + 1) : 1 + P - bbits;
-        b2 += i;
-        s2 += i;
-        i2b(mhi, 1);
-    }
+    i = denorm ? be + (Bias + (P - 1) - 1 + 1) : 1 + P - bbits;
+    b2 += i;
+    s2 += i;
+    i2b(mhi, 1);
     if (m2 > 0 && s2 > 0) {
         i = m2 < s2 ? m2 : s2;
         b2 -= i;
@@ -1015,15 +962,12 @@ bumpUp:
         s2 -= i;
     }
     if (b5 > 0) {
-        if (leftright) {
-            if (m5 > 0) {
-                pow5mult(mhi, m5);
-                mult(b, mhi);
-            }
-            if ((j = b5 - m5))
-                pow5mult(b, j);
-        } else
-            pow5mult(b, b5);
+        if (m5 > 0) {
+            pow5mult(mhi, m5);
+            mult(b, mhi);
+        }
+        if ((j = b5 - m5))
+            pow5mult(b, j);
     }
     i2b(S, 1);
     if (s5 > 0)
@@ -1032,7 +976,7 @@ bumpUp:
     /* Check for special case that d is a normalized power of 2. */
 
     spec_case = 0;
-    if ((roundingNone || leftright) && (!word1(&u) && !(word0(&u) & Bndry_mask) && word0(&u) & (Exp_mask & ~Exp_msk1))) {
+    if ((!word1(&u) && !(word0(&u) & Bndry_mask) && word0(&u) & (Exp_mask & ~Exp_msk1))) {
         /* The special case */
         b2 += Log2P;
         s2 += Log2P;
@@ -1067,105 +1011,84 @@ bumpUp:
         if (cmp(b, S) < 0) {
             k--;
             multadd(b, 10, 0);    /* we botched the k estimate */
-            if (leftright)
-                multadd(mhi, 10, 0);
+            multadd(mhi, 10, 0);
             ilim = ilim1;
         }
     }
-    if (ilim <= 0 && roundingDecimalPlaces) {
-        if (ilim < 0)
-            goto noDigits;
-        multadd(S, 5, 0);
-        // For IEEE-754 unbiased rounding this check should be <=, such that 0.5 would flush to zero.
-        if (cmp(b, S) < 0)
-            goto noDigits;
-        goto oneDigit;
-    }
-    if (leftright) {
-        if (m2 > 0)
-            lshift(mhi, m2);
+    if (m2 > 0)
+        lshift(mhi, m2);
 
-        /* Compute mlo -- check for special case
-         * that d is a normalized power of 2.
-         */
+    /* Compute mlo -- check for special case
+     * that d is a normalized power of 2.
+     */
+
+    mlo = mhi;
+    if (spec_case)
+        lshift(mhi, Log2P);
 
-        mlo = mhi;
-        if (spec_case)
-            lshift(mhi, Log2P);
-
-        for (i = 1;;i++) {
-            dig = quorem(b, S) + '0';
-            /* Do we yet have the shortest decimal string
-             * that will round to d?
-             */
-            j = cmp(b, mlo);
-            diff(delta, S, mhi);
-            j1 = delta.sign ? 1 : cmp(b, delta);
+    for (i = 1;;i++) {
+        dig = quorem(b, S) + '0';
+        /* Do we yet have the shortest decimal string
+         * that will round to d?
+         */
+        j = cmp(b, mlo);
+        diff(delta, S, mhi);
+        j1 = delta.sign ? 1 : cmp(b, delta);
 #ifdef DTOA_ROUND_BIASED
-            if (j < 0 || !j) {
+        if (j < 0 || !j) {
 #else
-            // FIXME: ECMA-262 specifies that equidistant results round away from
-            // zero, which probably means we shouldn't be on the unbiased code path
-            // (the (word1(&u) & 1) clause is looking highly suspicious). I haven't
-            // yet understood this code well enough to make the call, but we should
-            // probably be enabling DTOA_ROUND_BIASED. I think the interesting corner
-            // case to understand is probably "Math.pow(0.5, 24).toString()".
-            // I believe this value is interesting because I think it is precisely
-            // representable in binary floating point, and its decimal representation
-            // has a single digit that Steele & White reduction can remove, with the
-            // value 5 (thus equidistant from the next numbers above and below).
-            // We produce the correct answer using either codepath, and I don't as
-            // yet understand why. :-)
-            if (!j1 && !(word1(&u) & 1)) {
-                if (dig == '9')
-                    goto round9up;
-                if (j > 0)
-                    dig++;
-                *s++ = dig;
-                goto ret;
-            }
-            if (j < 0 || (!j && !(word1(&u) & 1))) {
+        // FIXME: ECMA-262 specifies that equidistant results round away from
+        // zero, which probably means we shouldn't be on the unbiased code path
+        // (the (word1(&u) & 1) clause is looking highly suspicious). I haven't
+        // yet understood this code well enough to make the call, but we should
+        // probably be enabling DTOA_ROUND_BIASED. I think the interesting corner
+        // case to understand is probably "Math.pow(0.5, 24).toString()".
+        // I believe this value is interesting because I think it is precisely
+        // representable in binary floating point, and its decimal representation
+        // has a single digit that Steele & White reduction can remove, with the
+        // value 5 (thus equidistant from the next numbers above and below).
+        // We produce the correct answer using either codepath, and I don't as
+        // yet understand why. :-)
+        if (!j1 && !(word1(&u) & 1)) {
+            if (dig == '9')
+                goto round9up;
+            if (j > 0)
+                dig++;
+            *s++ = dig;
+            goto ret;
+        }
+        if (j < 0 || (!j && !(word1(&u) & 1))) {
 #endif
-                if ((b.words()[0] || b.size() > 1) && (j1 > 0)) {
-                    lshift(b, 1);
-                    j1 = cmp(b, S);
-                    // For IEEE-754 round-to-even, this check should be (j1 > 0 || (!j1 && (dig & 1))),
-                    // but ECMA-262 specifies that equidistant values (e.g. (.5).toFixed()) should
-                    // be rounded away from zero.
-                    if (j1 >= 0) {
-                        if (dig == '9')
-                            goto round9up;
-                        dig++;
-                    }
-                }
-                *s++ = dig;
-                goto ret;
-            }
-            if (j1 > 0) {
-                if (dig == '9') { /* possible if i == 1 */
-round9up:
-                    *s++ = '9';
-                    goto roundoff;
+            if ((b.words()[0] || b.size() > 1) && (j1 > 0)) {
+                lshift(b, 1);
+                j1 = cmp(b, S);
+                // For IEEE-754 round-to-even, this check should be (j1 > 0 || (!j1 && (dig & 1))),
+                // but ECMA-262 specifies that equidistant values (e.g. (.5).toFixed()) should
+                // be rounded away from zero.
+                if (j1 >= 0) {
+                    if (dig == '9')
+                        goto round9up;
+                    dig++;
                 }
-                *s++ = dig + 1;
-                goto ret;
             }
             *s++ = dig;
-            if (i == ilim)
-                break;
-            multadd(b, 10, 0);
-            multadd(mlo, 10, 0);
-            multadd(mhi, 10, 0);
+            goto ret;
         }
-    } else {
-        for (i = 1;; i++) {
-            *s++ = dig = quorem(b, S) + '0';
-            if (!b.words()[0] && b.size() <= 1)
-                goto ret;
-            if (i >= ilim)
-                break;
-            multadd(b, 10, 0);
+        if (j1 > 0) {
+            if (dig == '9') { /* possible if i == 1 */
+round9up:
+                *s++ = '9';
+                goto roundoff;
+            }
+            *s++ = dig + 1;
+            goto ret;
         }
+        *s++ = dig;
+        if (i == ilim)
+            break;
+        multadd(b, 10, 0);
+        multadd(mlo, 10, 0);
+        multadd(mhi, 10, 0);
     }
 
     /* Round off last digit */
@@ -1200,39 +1123,28 @@ oneDigit:
     k++;
     goto ret;
 ret:
-    ASSERT(s > result);
+    ASSERT(s > &result[0]);
     *s = 0;
     exponentOut = k;
-    precisionOut = s - result;
+    precisionOut = s - &result[0];
 }
 
-void dtoa(DtoaBuffer result, double dd, bool& sign, int& exponent, unsigned& precision)
+const char* numberToString(float number, NumberToStringBuffer& buffer)
 {
-    // flags are roundingNone, leftright.
-    dtoa<true, false, false, true>(result, dd, 0, sign, exponent, precision);
-}
-
-void dtoaRoundSF(DtoaBuffer result, double dd, int ndigits, bool& sign, int& exponent, unsigned& precision)
-{
-    // flag is roundingSignificantFigures.
-    dtoa<false, true, false, false>(result, dd, ndigits, sign, exponent, precision);
-}
-
-void dtoaRoundDP(DtoaBuffer result, double dd, int ndigits, bool& sign, int& exponent, unsigned& precision)
-{
-    // flag is roundingDecimalPlaces.
-    dtoa<false, false, true, false>(result, dd, ndigits, sign, exponent, precision);
+    double_conversion::StringBuilder builder(&buffer[0], sizeof(buffer));
+    double_conversion::DoubleToStringConverter::EcmaScriptConverter().ToShortestSingle(number, &builder);
+    return builder.Finalize();
 }
 
-const char* numberToString(double d, NumberToStringBuffer buffer)
+const char* numberToString(double d, NumberToStringBuffer& buffer)
 {
-    double_conversion::StringBuilder builder(buffer, NumberToStringBufferLength);
+    double_conversion::StringBuilder builder(&buffer[0], sizeof(buffer));
     auto& converter = double_conversion::DoubleToStringConverter::EcmaScriptConverter();
     converter.ToShortest(d, &builder);
     return builder.Finalize();
 }
 
-static inline const char* formatStringTruncatingTrailingZerosIfNeeded(NumberToStringBuffer buffer, double_conversion::StringBuilder& builder)
+static inline const char* formatStringTruncatingTrailingZerosIfNeeded(NumberToStringBuffer& buffer, double_conversion::StringBuilder& builder)
 {
     size_t length = builder.position();
     size_t decimalPointPosition = 0;
@@ -1270,14 +1182,14 @@ static inline const char* formatStringTruncatingTrailingZerosIfNeeded(NumberToSt
     return builder.Finalize();
 }
 
-const char* numberToFixedPrecisionString(double d, unsigned significantFigures, NumberToStringBuffer buffer, bool truncateTrailingZeros)
+const char* numberToFixedPrecisionString(double d, unsigned significantFigures, NumberToStringBuffer& buffer, bool truncateTrailingZeros)
 {
     // Mimic sprintf("%.[precision]g", ...), but use dtoas rounding facilities.
     // "g": Signed value printed in f or e format, whichever is more compact for the given value and precision.
     // The e format is used only when the exponent of the value is less than –4 or greater than or equal to the
     // precision argument. Trailing zeros are truncated, and the decimal point appears only if one or more digits follow it.
     // "precision": The precision specifies the maximum number of significant digits printed.
-    double_conversion::StringBuilder builder(buffer, NumberToStringBufferLength);
+    double_conversion::StringBuilder builder(&buffer[0], sizeof(buffer));
     auto& converter = double_conversion::DoubleToStringConverter::EcmaScriptConverter();
     converter.ToPrecision(d, significantFigures, &builder);
     if (!truncateTrailingZeros)
@@ -1285,7 +1197,7 @@ const char* numberToFixedPrecisionString(double d, unsigned significantFigures,
     return formatStringTruncatingTrailingZerosIfNeeded(buffer, builder);
 }
 
-const char* numberToFixedWidthString(double d, unsigned decimalPlaces, NumberToStringBuffer buffer)
+const char* numberToFixedWidthString(double d, unsigned decimalPlaces, NumberToStringBuffer& buffer)
 {
     // Mimic sprintf("%.[precision]f", ...), but use dtoas rounding facilities.
     // "f": Signed value having the form [ – ]dddd.dddd, where dddd is one or more decimal digits.
@@ -1294,7 +1206,7 @@ const char* numberToFixedWidthString(double d, unsigned decimalPlaces, NumberToS
     // "precision": The precision value specifies the number of digits after the decimal point.
     // If a decimal point appears, at least one digit appears before it.
     // The value is rounded to the appropriate number of digits.    
-    double_conversion::StringBuilder builder(buffer, NumberToStringBufferLength);
+    double_conversion::StringBuilder builder(&buffer[0], sizeof(buffer));
     auto& converter = double_conversion::DoubleToStringConverter::EcmaScriptConverter();
     converter.ToFixed(d, decimalPlaces, &builder);
     return builder.Finalize();
index 5f4fadb..d38289d 100644 (file)
@@ -1,5 +1,5 @@
 /*
- *  Copyright (C) 2003, 2008, 2012 Apple Inc. All rights reserved.
+ *  Copyright (C) 2003-2019 Apple Inc. All rights reserved.
  *
  *  This library is free software; you can redistribute it and/or
  *  modify it under the terms of the GNU Library General Public
 
 #pragma once
 
-#include <unicode/utypes.h>
+#include <array>
 #include <wtf/ASCIICType.h>
 #include <wtf/dtoa/double-conversion.h>
 #include <wtf/text/StringView.h>
 
 namespace WTF {
 
-typedef char DtoaBuffer[80];
+using DtoaBuffer = std::array<char, 80>;
 
-WTF_EXPORT_PRIVATE void dtoa(DtoaBuffer result, double dd, bool& sign, int& exponent, unsigned& precision);
-WTF_EXPORT_PRIVATE void dtoaRoundSF(DtoaBuffer result, double dd, int ndigits, bool& sign, int& exponent, unsigned& precision);
-WTF_EXPORT_PRIVATE void dtoaRoundDP(DtoaBuffer result, double dd, int ndigits, bool& sign, int& exponent, unsigned& precision);
+WTF_EXPORT_PRIVATE void dtoa(DtoaBuffer& result, double dd, bool& sign, int& exponent, unsigned& precision);
 
-// Size = 80 for sizeof(DtoaBuffer) + some sign bits, decimal point, 'e', exponent digits.
-const unsigned NumberToStringBufferLength = 96;
-typedef char NumberToStringBuffer[NumberToStringBufferLength];
-typedef LChar NumberToLStringBuffer[NumberToStringBufferLength];
+constexpr unsigned NumberToStringBufferLength = 96;
+using NumberToStringBuffer = std::array<char, NumberToStringBufferLength>;
 
-WTF_EXPORT_PRIVATE const char* numberToString(double, NumberToStringBuffer);
-WTF_EXPORT_PRIVATE const char* numberToFixedPrecisionString(double, unsigned significantFigures, NumberToStringBuffer, bool truncateTrailingZeros = false);
-WTF_EXPORT_PRIVATE const char* numberToFixedWidthString(double, unsigned decimalPlaces, NumberToStringBuffer);
+WTF_EXPORT_PRIVATE const char* numberToString(float, NumberToStringBuffer&);
+WTF_EXPORT_PRIVATE const char* numberToFixedPrecisionString(float, unsigned significantFigures, NumberToStringBuffer&, bool truncateTrailingZeros = false);
+WTF_EXPORT_PRIVATE const char* numberToFixedWidthString(float, unsigned decimalPlaces, NumberToStringBuffer&);
+
+WTF_EXPORT_PRIVATE const char* numberToString(double, NumberToStringBuffer&);
+WTF_EXPORT_PRIVATE const char* numberToFixedPrecisionString(double, unsigned significantFigures, NumberToStringBuffer&, bool truncateTrailingZeros = false);
+WTF_EXPORT_PRIVATE const char* numberToFixedWidthString(double, unsigned decimalPlaces, NumberToStringBuffer&);
 
 double parseDouble(const LChar* string, size_t length, size_t& parsedLength);
 double parseDouble(const UChar* string, size_t length, size_t& parsedLength);
@@ -72,11 +72,10 @@ inline double parseDouble(StringView string, size_t& parsedLength)
         return parseDouble(string.characters8(), string.length(), parsedLength);
     return parseDouble(string.characters16(), string.length(), parsedLength);
 }
-    
+
 } // namespace WTF
 
 using WTF::NumberToStringBuffer;
-using WTF::NumberToLStringBuffer;
 using WTF::numberToString;
 using WTF::numberToFixedPrecisionString;
 using WTF::numberToFixedWidthString;
index 6f4ef89..a80fa3c 100644 (file)
@@ -69,7 +69,7 @@ public:
     StringTypeAdapter(FloatingPoint number)
     {
         numberToString(number, m_buffer);
-        m_length = std::strlen(m_buffer);
+        m_length = std::strlen(&m_buffer[0]);
     }
 
     unsigned length() const { return m_length; }
@@ -77,7 +77,7 @@ public:
     template<typename CharacterType> void writeTo(CharacterType* destination) const { StringImpl::copyCharacters(destination, buffer(), m_length); }
 
 private:
-    const LChar* buffer() const { return reinterpret_cast<const LChar*>(m_buffer); }
+    const LChar* buffer() const { return reinterpret_cast<const LChar*>(&m_buffer[0]); }
 
     NumberToStringBuffer m_buffer;
     unsigned m_length;
@@ -89,7 +89,7 @@ public:
     {
         FormattedNumber numberFormatter;
         numberToFixedPrecisionString(number, significantFigures, numberFormatter.m_buffer, trailingZerosTruncatingPolicy == TruncateTrailingZeros);
-        numberFormatter.m_length = std::strlen(numberFormatter.m_buffer);
+        numberFormatter.m_length = std::strlen(&numberFormatter.m_buffer[0]);
         return numberFormatter;
     }
 
@@ -97,12 +97,12 @@ public:
     {
         FormattedNumber numberFormatter;
         numberToFixedWidthString(number, decimalPlaces, numberFormatter.m_buffer);
-        numberFormatter.m_length = std::strlen(numberFormatter.m_buffer);
+        numberFormatter.m_length = std::strlen(&numberFormatter.m_buffer[0]);
         return numberFormatter;
     }
 
     unsigned length() const { return m_length; }
-    const LChar* buffer() const { return reinterpret_cast<const LChar*>(m_buffer); }
+    const LChar* buffer() const { return reinterpret_cast<const LChar*>(&m_buffer[0]); }
 
 private:
     NumberToStringBuffer m_buffer;
index 9c372e2..4d72923 100644 (file)
@@ -1,3 +1,12 @@
+2019-02-27  Darin Adler  <darin@apple.com>
+
+        Fixed makeString(float) to do shortest-form serialization without first converting to double
+        https://bugs.webkit.org/show_bug.cgi?id=195142
+
+        Reviewed by Daniel Bates.
+
+        * platform/graphics/Color.cpp: Removed unneeded include of DecimalNumber.h.
+
 2019-03-02  Simon Fraser  <simon.fraser@apple.com>
 
         REGRESSION (r242132): Incorrect positioning with multiple position:fixed elements
index ee72938..93a489e 100644 (file)
@@ -29,7 +29,6 @@
 #include "AnimationUtilities.h"
 #include "HashTools.h"
 #include <wtf/Assertions.h>
-#include <wtf/DecimalNumber.h>
 #include <wtf/HexNumber.h>
 #include <wtf/MathExtras.h>
 #include <wtf/text/StringBuilder.h>
index 41c44af..3446c0d 100644 (file)
@@ -1,3 +1,12 @@
+2019-02-27  Darin Adler  <darin@apple.com>
+
+        Fixed makeString(float) to do shortest-form serialization without first converting to double
+        https://bugs.webkit.org/show_bug.cgi?id=195142
+
+        Reviewed by Daniel Bates.
+
+        * UIProcess/PerActivityStateCPUUsageSampler.cpp: Removed unneeded include of DecimalNumber.h.
+
 2019-03-02  Adrian Perez de Castro  <aperez@igalia.com>
 
         [WPE] Public API headers are missing autocleanup definitions
index 51f7786..9e3b8bb 100644 (file)
@@ -31,7 +31,6 @@
 #include "WebProcessPool.h"
 #include "WebProcessProxy.h"
 #include <WebCore/DiagnosticLoggingKeys.h>
-#include <wtf/DecimalNumber.h>
 
 namespace WebKit {
 using namespace WebCore;