Title: [246034] trunk
Revision
246034
Author
[email protected]
Date
2019-06-03 04:34:20 -0700 (Mon, 03 Jun 2019)

Log Message

Finish cleanup of String::number for floating point
https://bugs.webkit.org/show_bug.cgi?id=198471

Reviewed by Yusuke Suzuki.

Source/_javascript_Core:

* dfg/DFGStrengthReductionPhase.cpp:
(JSC::DFG::StrengthReductionPhase::handleNode): Use String::number instead of
String::numberToStringECMAScript, since that's now the default.
* parser/ParserArena.h:
(JSC::IdentifierArena::makeNumericIdentifier): Ditto.
* runtime/JSONObject.cpp:
(JSC::Stringifier::appendStringifiedValue): Use appendNumber instead of
builder.appendECMAScriptNumber, since that's now the default.
* runtime/NumberPrototype.cpp:
(JSC::toStringWithRadix): Use String::number instead of
String::numberToStringECMAScript, since that's now the default.
(JSC::numberProtoFuncToExponential): Ditto.
(JSC::numberProtoFuncToFixed): Ditto.
(JSC::numberProtoFuncToPrecision): Ditto.
(JSC::numberToStringInternal): Ditto.
* runtime/NumericStrings.h:
(JSC::NumericStrings::add): Ditto.
* wasm/WasmBBQPlan.cpp:
(JSC::Wasm::BBQPlan::prepare): Ditto.

Source/WebCore:

* css/CSSCursorImageValue.cpp:
(WebCore::CSSCursorImageValue::customCSSText const): Use makeString instead
of StringBuilder since it is more terse and possibly more efficient as well.
* css/DOMMatrixReadOnly.cpp:
(WebCore::DOMMatrixReadOnly::toString const): Ditto.
* css/WebKitCSSMatrix.cpp:
(WebCore::WebKitCSSMatrix::toString const): Ditto.

* html/parser/HTMLParserIdioms.cpp:
(WebCore::serializeForNumberType): Use String::number instead of
String::numberToStringECMAScript since that is now the default.
* html/shadow/MediaControlElementTypes.cpp:
(WebCore::MediaControlVolumeSliderElement::setVolume): Ditto.
* html/shadow/MediaControlElements.cpp:
(WebCore::MediaControlTimelineElement::setPosition): Ditto.
* platform/Decimal.cpp:
(WebCore::Decimal::fromDouble): Ditto.

* rendering/RenderListMarker.cpp:
(WebCore::toRoman): Return a String instead of taking a StringBuilder argument.
Use LetterCase enum instead of bool for the uppercase vs. lowercase argument, to
be less mysterious at call sites. Use unsigned for string lengths since that's
what WTF::String uses.
(WebCore::toAlphabeticOrNumeric): Ditto. Also updated since SequenceType is now
an enum class.
(WebCore::toSymbolic): Use String::createUninitialized instead of StringBuilder.
Return a String instead of taking a StringBuilder argument. Straighten out the
algorithm so it's easier to understand.
(WebCore::toAlphabetic): Updated since SequenceType is now an enum class.
(WebCore::toNumeric): Ditto.
(WebCore::toHebrew): Return a String instead of taking a StringBuilder argument.
Use unsigned for string lengths since that's what WTF::String uses.
(WebCore::toArmenianUnder10000): Use unsigned and the LetterCase enum class.
(WebCore::toArmenian): Return a String instead of taking a StringBuilder argument.
Also use unsigned for string lengths since that's what WTF::String uses.
(WebCore::toGeorgian): Ditto.
(WebCore::toCJKIdeographic): Ditto.
(WebCore::listMarkerSuffix): Tweaked a comment.
(WebCore::listMarkerText): Use String return values instead of StringBuilder.
(WebCore::RenderListMarker::paint): Use String::createUninitialized instead of
StringBuilder since it's a bit more efficient. Use makeString instead of turning
single characters into strings since that's more efficient.

* svg/SVGPathUtilities.cpp:
(WebCore::buildStringFromPath): Use appendNumber instead of appendShortestFormNumber
since that is now the default.

Source/WebKit:

* NetworkProcess/Classifier/WebResourceLoadStatisticsTelemetry.cpp:
(WebKit::submitTopList): Use makeString instead of StringBuilder since it
is more terse and possibly more efficient as well.
* UIProcess/API/APIUserScript.cpp:
(API::UserScript::generateUniqueURL): Ditto.
* UIProcess/API/APIUserStyleSheet.cpp:
(API::UserStyleSheet::generateUniqueURL): Ditto.

Source/WTF:

* wtf/JSONValues.cpp:
(WTF::JSONImpl::Value::writeJSON const): Use appendNumber instead of
appendECMAScriptNumber, since that's now the default.

* wtf/text/StringBuilder.cpp:
(WTF::StringBuilder::appendNumber): Renamed from appendShortestFormNumber.
* wtf/text/StringBuilder.h: Removed appendShortestFormNumber and
appendECMAScriptNumber, replacing both with overload of appendNumber.

* wtf/text/WTFString.cpp:
(WTF::String::number): Renamed from numberToStringShortest.
* wtf/text/WTFString.h: Removed numberToStringShortest and
numberToStringECMAScript, replacing both with overload of number.

Tools:

* TestWebKitAPI/Tests/WTF/WTFString.cpp:
(TestWebKitAPI::testStringNumber): Go back to calling String::number instead of
String::numberToStringECMAScript.

* WebKitTestRunner/InjectedBundle/InjectedBundlePage.cpp:
(WTR::dumpFrameScrollPosition): Use appendNumber instead of appendECMAScriptNumber
since that is now the default.

Modified Paths

Diff

Modified: trunk/Source/_javascript_Core/ChangeLog (246033 => 246034)


--- trunk/Source/_javascript_Core/ChangeLog	2019-06-03 09:45:51 UTC (rev 246033)
+++ trunk/Source/_javascript_Core/ChangeLog	2019-06-03 11:34:20 UTC (rev 246034)
@@ -1,3 +1,30 @@
+2019-06-03  Darin Adler  <[email protected]>
+
+        Finish cleanup of String::number for floating point
+        https://bugs.webkit.org/show_bug.cgi?id=198471
+
+        Reviewed by Yusuke Suzuki.
+
+        * dfg/DFGStrengthReductionPhase.cpp:
+        (JSC::DFG::StrengthReductionPhase::handleNode): Use String::number instead of
+        String::numberToStringECMAScript, since that's now the default.
+        * parser/ParserArena.h:
+        (JSC::IdentifierArena::makeNumericIdentifier): Ditto.
+        * runtime/JSONObject.cpp:
+        (JSC::Stringifier::appendStringifiedValue): Use appendNumber instead of
+        builder.appendECMAScriptNumber, since that's now the default.
+        * runtime/NumberPrototype.cpp:
+        (JSC::toStringWithRadix): Use String::number instead of
+        String::numberToStringECMAScript, since that's now the default.
+        (JSC::numberProtoFuncToExponential): Ditto.
+        (JSC::numberProtoFuncToFixed): Ditto.
+        (JSC::numberProtoFuncToPrecision): Ditto.
+        (JSC::numberToStringInternal): Ditto.
+        * runtime/NumericStrings.h:
+        (JSC::NumericStrings::add): Ditto.
+        * wasm/WasmBBQPlan.cpp:
+        (JSC::Wasm::BBQPlan::prepare): Ditto.
+
 2019-06-02  Yusuke Suzuki  <[email protected]>
 
         [JSC] Crash explicitly if StructureIDs are exhausted

Modified: trunk/Source/_javascript_Core/dfg/DFGStrengthReductionPhase.cpp (246033 => 246034)


--- trunk/Source/_javascript_Core/dfg/DFGStrengthReductionPhase.cpp	2019-06-03 09:45:51 UTC (rev 246033)
+++ trunk/Source/_javascript_Core/dfg/DFGStrengthReductionPhase.cpp	2019-06-03 11:34:20 UTC (rev 246034)
@@ -350,7 +350,7 @@
                     if (value.isInt32())
                         return String::number(value.asInt32());
                     if (value.isNumber())
-                        return String::numberToStringECMAScript(value.asNumber());
+                        return String::number(value.asNumber());
                     if (value.isBoolean())
                         return value.asBoolean() ? "true"_s : "false"_s;
                     if (value.isNull())
@@ -421,7 +421,7 @@
                         if (value.isInt32())
                             result = String::number(value.asInt32());
                         else if (value.isNumber())
-                            result = String::numberToStringECMAScript(value.asNumber());
+                            result = String::number(value.asNumber());
 
                         if (!result.isNull()) {
                             convertToLazyJSValue(m_node, LazyJSValue::newString(m_graph, result));

Modified: trunk/Source/_javascript_Core/parser/ParserArena.h (246033 => 246034)


--- trunk/Source/_javascript_Core/parser/ParserArena.h	2019-06-03 09:45:51 UTC (rev 246033)
+++ trunk/Source/_javascript_Core/parser/ParserArena.h	2019-06-03 11:34:20 UTC (rev 246034)
@@ -130,7 +130,9 @@
     
     inline const Identifier& IdentifierArena::makeNumericIdentifier(VM* vm, double number)
     {
-        m_identifiers.append(Identifier::fromString(vm, String::numberToStringECMAScript(number)));
+        // FIXME: Why doesn't this use the Identifier::from overload that takes a double?
+        // Seems we are missing out on multiple optimizations by not using it.
+        m_identifiers.append(Identifier::fromString(vm, String::number(number)));
         return m_identifiers.last();
     }
 

Modified: trunk/Source/_javascript_Core/runtime/JSONObject.cpp (246033 => 246034)


--- trunk/Source/_javascript_Core/runtime/JSONObject.cpp	2019-06-03 09:45:51 UTC (rev 246033)
+++ trunk/Source/_javascript_Core/runtime/JSONObject.cpp	2019-06-03 11:34:20 UTC (rev 246034)
@@ -377,7 +377,7 @@
             if (!std::isfinite(number))
                 builder.appendLiteral("null");
             else
-                builder.appendECMAScriptNumber(number);
+                builder.appendNumber(number);
         }
         return StringifySucceeded;
     }

Modified: trunk/Source/_javascript_Core/runtime/NumberPrototype.cpp (246033 => 246034)


--- trunk/Source/_javascript_Core/runtime/NumberPrototype.cpp	2019-06-03 09:45:51 UTC (rev 246033)
+++ trunk/Source/_javascript_Core/runtime/NumberPrototype.cpp	2019-06-03 11:34:20 UTC (rev 246034)
@@ -395,7 +395,7 @@
         return toStringWithRadixInternal(integerValue, radix);
 
     if (radix == 10 || !std::isfinite(doubleValue))
-        return String::numberToStringECMAScript(doubleValue);
+        return String::number(doubleValue);
 
     RadixBuffer buffer;
     return toStringWithRadixInternal(buffer, doubleValue, radix);
@@ -422,7 +422,7 @@
 
     // Handle NaN and Infinity.
     if (!std::isfinite(x))
-        return JSValue::encode(jsNontrivialString(exec, String::numberToStringECMAScript(x)));
+        return JSValue::encode(jsNontrivialString(exec, String::number(x)));
 
     if (!inRange)
         return throwVMError(exec, scope, createRangeError(exec, "toExponential() argument must be between 0 and 20"_s));
@@ -463,7 +463,7 @@
     // This also covers Ininity, and structure the check so that NaN
     // values are also handled by numberToString
     if (!(fabs(x) < 1e+21))
-        return JSValue::encode(jsString(exec, String::numberToStringECMAScript(x)));
+        return JSValue::encode(jsString(exec, String::number(x)));
 
     // The check above will return false for NaN or Infinity, these will be
     // handled by numberToString.
@@ -496,11 +496,11 @@
 
     // To precision called with no argument is treated as ToString.
     if (isUndefined)
-        return JSValue::encode(jsString(exec, String::numberToStringECMAScript(x)));
+        return JSValue::encode(jsString(exec, String::number(x)));
 
     // Handle NaN and Infinity.
     if (!std::isfinite(x))
-        return JSValue::encode(jsNontrivialString(exec, String::numberToStringECMAScript(x)));
+        return JSValue::encode(jsNontrivialString(exec, String::number(x)));
 
     if (!inRange)
         return throwVMError(exec, scope, createRangeError(exec, "toPrecision() argument must be between 1 and 21"_s));
@@ -537,7 +537,7 @@
         return jsString(&vm, vm.numericStrings.add(doubleValue));
 
     if (!std::isfinite(doubleValue))
-        return jsNontrivialString(&vm, String::numberToStringECMAScript(doubleValue));
+        return jsNontrivialString(&vm, String::number(doubleValue));
 
     RadixBuffer buffer;
     return jsString(&vm, toStringWithRadixInternal(buffer, doubleValue, radix));

Modified: trunk/Source/_javascript_Core/runtime/NumericStrings.h (246033 => 246034)


--- trunk/Source/_javascript_Core/runtime/NumericStrings.h	2019-06-03 09:45:51 UTC (rev 246033)
+++ trunk/Source/_javascript_Core/runtime/NumericStrings.h	2019-06-03 11:34:20 UTC (rev 246034)
@@ -39,7 +39,7 @@
         if (d == entry.key && !entry.value.isNull())
             return entry.value;
         entry.key = d;
-        entry.value = String::numberToStringECMAScript(d);
+        entry.value = String::number(d);
         return entry.value;
     }
 

Modified: trunk/Source/_javascript_Core/wasm/WasmBBQPlan.cpp (246033 => 246034)


--- trunk/Source/_javascript_Core/wasm/WasmBBQPlan.cpp	2019-06-03 09:45:51 UTC (rev 246033)
+++ trunk/Source/_javascript_Core/wasm/WasmBBQPlan.cpp	2019-06-03 11:34:20 UTC (rev 246034)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2016-2018 Apple Inc. All rights reserved.
+ * Copyright (C) 2016-2019 Apple Inc. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -45,7 +45,7 @@
 #include <wtf/MonotonicTime.h>
 #include <wtf/StdLibExtras.h>
 #include <wtf/SystemTracing.h>
-#include <wtf/text/StringBuilder.h>
+#include <wtf/text/StringConcatenateNumbers.h>
 
 namespace JSC { namespace Wasm {
 
@@ -151,11 +151,7 @@
 
     auto tryReserveCapacity = [this] (auto& vector, size_t size, const char* what) {
         if (UNLIKELY(!vector.tryReserveCapacity(size))) {
-            StringBuilder builder;
-            builder.appendLiteral("Failed allocating enough space for ");
-            builder.appendNumber(size);
-            builder.append(what);
-            fail(holdLock(m_lock), builder.toString());
+            fail(holdLock(m_lock), WTF::makeString("Failed allocating enough space for ", size, what));
             return false;
         }
         return true;

Modified: trunk/Source/WTF/ChangeLog (246033 => 246034)


--- trunk/Source/WTF/ChangeLog	2019-06-03 09:45:51 UTC (rev 246033)
+++ trunk/Source/WTF/ChangeLog	2019-06-03 11:34:20 UTC (rev 246034)
@@ -1,3 +1,24 @@
+2019-06-03  Darin Adler  <[email protected]>
+
+        Finish cleanup of String::number for floating point
+        https://bugs.webkit.org/show_bug.cgi?id=198471
+
+        Reviewed by Yusuke Suzuki.
+
+        * wtf/JSONValues.cpp:
+        (WTF::JSONImpl::Value::writeJSON const): Use appendNumber instead of
+        appendECMAScriptNumber, since that's now the default.
+
+        * wtf/text/StringBuilder.cpp:
+        (WTF::StringBuilder::appendNumber): Renamed from appendShortestFormNumber.
+        * wtf/text/StringBuilder.h: Removed appendShortestFormNumber and
+        appendECMAScriptNumber, replacing both with overload of appendNumber.
+
+        * wtf/text/WTFString.cpp:
+        (WTF::String::number): Renamed from numberToStringShortest.
+        * wtf/text/WTFString.h: Removed numberToStringShortest and
+        numberToStringECMAScript, replacing both with overload of number.
+
 2019-06-02  Keith Miller  <[email protected]>
 
         Reenable Gigacage on ARM64.

Modified: trunk/Source/WTF/wtf/JSONValues.cpp (246033 => 246034)


--- trunk/Source/WTF/wtf/JSONValues.cpp	2019-06-03 09:45:51 UTC (rev 246033)
+++ trunk/Source/WTF/wtf/JSONValues.cpp	2019-06-03 11:34:20 UTC (rev 246034)
@@ -680,7 +680,7 @@
         if (!std::isfinite(m_value.number))
             output.appendLiteral("null");
         else
-            output.appendECMAScriptNumber(m_value.number);
+            output.appendNumber(m_value.number);
         break;
     }
     default:

Modified: trunk/Source/WTF/wtf/text/StringBuilder.cpp (246033 => 246034)


--- trunk/Source/WTF/wtf/text/StringBuilder.cpp	2019-06-03 09:45:51 UTC (rev 246033)
+++ trunk/Source/WTF/wtf/text/StringBuilder.cpp	2019-06-03 11:34:20 UTC (rev 246034)
@@ -415,13 +415,13 @@
     append(numberToFixedPrecisionString(number, precision, buffer, policy == TruncateTrailingZeros));
 }
 
-void StringBuilder::appendShortestFormNumber(float number)
+void StringBuilder::appendNumber(float number)
 {
     NumberToStringBuffer buffer;
     append(numberToString(number, buffer));
 }
 
-void StringBuilder::appendShortestFormNumber(double number)
+void StringBuilder::appendNumber(double number)
 {
     NumberToStringBuffer buffer;
     append(numberToString(number, buffer));

Modified: trunk/Source/WTF/wtf/text/StringBuilder.h (246033 => 246034)


--- trunk/Source/WTF/wtf/text/StringBuilder.h	2019-06-03 09:45:51 UTC (rev 246033)
+++ trunk/Source/WTF/wtf/text/StringBuilder.h	2019-06-03 11:34:20 UTC (rev 246034)
@@ -222,21 +222,14 @@
     WTF_EXPORT_PRIVATE void appendNumber(unsigned long);
     WTF_EXPORT_PRIVATE void appendNumber(long long);
     WTF_EXPORT_PRIVATE void appendNumber(unsigned long long);
-    // FIXME: Change to call appendShortestFormNumber.
-    void appendNumber(float) = delete;
-    void appendNumber(double) = delete;
+    WTF_EXPORT_PRIVATE void appendNumber(float);
+    WTF_EXPORT_PRIVATE void appendNumber(double);
 
-    WTF_EXPORT_PRIVATE void appendShortestFormNumber(float);
-    WTF_EXPORT_PRIVATE void appendShortestFormNumber(double);
     WTF_EXPORT_PRIVATE void appendFixedPrecisionNumber(float, unsigned precision = 6, TrailingZerosTruncatingPolicy = TruncateTrailingZeros);
     WTF_EXPORT_PRIVATE void appendFixedPrecisionNumber(double, unsigned precision = 6, TrailingZerosTruncatingPolicy = TruncateTrailingZeros);
     WTF_EXPORT_PRIVATE void appendFixedWidthNumber(float, unsigned decimalPlaces);
     WTF_EXPORT_PRIVATE void appendFixedWidthNumber(double, unsigned decimalPlaces);
 
-    // FIXME: Delete in favor of the name appendShortestFormNumber or just appendNumber.
-    void appendECMAScriptNumber(float) = delete;
-    void appendECMAScriptNumber(double);
-
     String toString()
     {
         if (!m_string.isNull()) {
@@ -394,11 +387,6 @@
     return m_bufferCharacters16;
 }
 
-inline void StringBuilder::appendECMAScriptNumber(double number)
-{
-    appendShortestFormNumber(number);
-}
-
 template <typename CharType>
 bool equal(const StringBuilder& s, const CharType* buffer, unsigned length)
 {

Modified: trunk/Source/WTF/wtf/text/WTFString.cpp (246033 => 246034)


--- trunk/Source/WTF/wtf/text/WTFString.cpp	2019-06-03 09:45:51 UTC (rev 246033)
+++ trunk/Source/WTF/wtf/text/WTFString.cpp	2019-06-03 11:34:20 UTC (rev 246034)
@@ -491,13 +491,13 @@
     return numberToFixedPrecisionString(number, precision, buffer, trailingZerosTruncatingPolicy == TruncateTrailingZeros);
 }
 
-String String::numberToStringShortest(float number)
+String String::number(float number)
 {
     NumberToStringBuffer buffer;
     return numberToString(number, buffer);
 }
 
-String String::numberToStringShortest(double number)
+String String::number(double number)
 {
     NumberToStringBuffer buffer;
     return numberToString(number, buffer);

Modified: trunk/Source/WTF/wtf/text/WTFString.h (246033 => 246034)


--- trunk/Source/WTF/wtf/text/WTFString.h	2019-06-03 09:45:51 UTC (rev 246033)
+++ trunk/Source/WTF/wtf/text/WTFString.h	2019-06-03 11:34:20 UTC (rev 246034)
@@ -124,12 +124,10 @@
     WTF_EXPORT_PRIVATE String(ASCIILiteral);
 
     // Construct a string from a constant string literal.
-    // This constructor is the "big" version, as it put the length in the function call and generate bigger code.
+    // This is the "big" version: puts the length in the function call and generates bigger code.
     enum ConstructFromLiteralTag { ConstructFromLiteral };
     template<unsigned characterCount> String(const char (&characters)[characterCount], ConstructFromLiteralTag) : m_impl(StringImpl::createFromLiteral<characterCount>(characters)) { }
 
-    // FIXME: Why do we have to define these explicitly given that we just want the default versions?
-    // We have verified empirically that we do.
     String(const String&) = default;
     String(String&&) = default;
     String& operator=(const String&) = default;
@@ -179,21 +177,14 @@
     WTF_EXPORT_PRIVATE static String number(unsigned long);
     WTF_EXPORT_PRIVATE static String number(long long);
     WTF_EXPORT_PRIVATE static String number(unsigned long long);
-    // FIXME: Change to call numberToStringShortest.
-    static String number(float) = delete;
-    static String number(double) = delete;
+    WTF_EXPORT_PRIVATE static String number(float);
+    WTF_EXPORT_PRIVATE static String number(double);
 
-    WTF_EXPORT_PRIVATE static String numberToStringShortest(float);
-    WTF_EXPORT_PRIVATE static String numberToStringShortest(double);
     WTF_EXPORT_PRIVATE static String numberToStringFixedPrecision(float, unsigned precision = 6, TrailingZerosTruncatingPolicy = TruncateTrailingZeros);
     WTF_EXPORT_PRIVATE static String numberToStringFixedPrecision(double, unsigned precision = 6, TrailingZerosTruncatingPolicy = TruncateTrailingZeros);
     WTF_EXPORT_PRIVATE static String numberToStringFixedWidth(float, unsigned decimalPlaces);
     WTF_EXPORT_PRIVATE static String numberToStringFixedWidth(double, unsigned decimalPlaces);
 
-    // FIXME: Delete in favor of the name numberToStringShortest or just number.
-    static String numberToStringECMAScript(float) = delete;
-    static String numberToStringECMAScript(double);
-
     // Find a single character or string, also with match function & latin1 forms.
     size_t find(UChar character, unsigned start = 0) const { return m_impl ? m_impl->find(character, start) : notFound; }
 
@@ -654,11 +645,6 @@
     return startsWithLettersIgnoringASCIICase(string.impl(), lowercaseLetters);
 }
 
-inline String String::numberToStringECMAScript(double number)
-{
-    return numberToStringShortest(number);
-}
-
 inline namespace StringLiterals {
 
 inline String operator"" _str(const char* characters, size_t)

Modified: trunk/Source/WebCore/ChangeLog (246033 => 246034)


--- trunk/Source/WebCore/ChangeLog	2019-06-03 09:45:51 UTC (rev 246033)
+++ trunk/Source/WebCore/ChangeLog	2019-06-03 11:34:20 UTC (rev 246034)
@@ -1,3 +1,57 @@
+2019-06-03  Darin Adler  <[email protected]>
+
+        Finish cleanup of String::number for floating point
+        https://bugs.webkit.org/show_bug.cgi?id=198471
+
+        Reviewed by Yusuke Suzuki.
+
+        * css/CSSCursorImageValue.cpp:
+        (WebCore::CSSCursorImageValue::customCSSText const): Use makeString instead
+        of StringBuilder since it is more terse and possibly more efficient as well.
+        * css/DOMMatrixReadOnly.cpp:
+        (WebCore::DOMMatrixReadOnly::toString const): Ditto.
+        * css/WebKitCSSMatrix.cpp:
+        (WebCore::WebKitCSSMatrix::toString const): Ditto.
+
+        * html/parser/HTMLParserIdioms.cpp:
+        (WebCore::serializeForNumberType): Use String::number instead of
+        String::numberToStringECMAScript since that is now the default.
+        * html/shadow/MediaControlElementTypes.cpp:
+        (WebCore::MediaControlVolumeSliderElement::setVolume): Ditto.
+        * html/shadow/MediaControlElements.cpp:
+        (WebCore::MediaControlTimelineElement::setPosition): Ditto.
+        * platform/Decimal.cpp:
+        (WebCore::Decimal::fromDouble): Ditto.
+
+        * rendering/RenderListMarker.cpp:
+        (WebCore::toRoman): Return a String instead of taking a StringBuilder argument.
+        Use LetterCase enum instead of bool for the uppercase vs. lowercase argument, to
+        be less mysterious at call sites. Use unsigned for string lengths since that's
+        what WTF::String uses.
+        (WebCore::toAlphabeticOrNumeric): Ditto. Also updated since SequenceType is now
+        an enum class.
+        (WebCore::toSymbolic): Use String::createUninitialized instead of StringBuilder.
+        Return a String instead of taking a StringBuilder argument. Straighten out the
+        algorithm so it's easier to understand.
+        (WebCore::toAlphabetic): Updated since SequenceType is now an enum class.
+        (WebCore::toNumeric): Ditto.
+        (WebCore::toHebrew): Return a String instead of taking a StringBuilder argument.
+        Use unsigned for string lengths since that's what WTF::String uses.
+        (WebCore::toArmenianUnder10000): Use unsigned and the LetterCase enum class.
+        (WebCore::toArmenian): Return a String instead of taking a StringBuilder argument.
+        Also use unsigned for string lengths since that's what WTF::String uses.
+        (WebCore::toGeorgian): Ditto.
+        (WebCore::toCJKIdeographic): Ditto.
+        (WebCore::listMarkerSuffix): Tweaked a comment.
+        (WebCore::listMarkerText): Use String return values instead of StringBuilder.
+        (WebCore::RenderListMarker::paint): Use String::createUninitialized instead of
+        StringBuilder since it's a bit more efficient. Use makeString instead of turning
+        single characters into strings since that's more efficient.
+
+        * svg/SVGPathUtilities.cpp:
+        (WebCore::buildStringFromPath): Use appendNumber instead of appendShortestFormNumber
+        since that is now the default.
+
 2019-06-03  Zan Dobersek  <[email protected]>
 
         [Nicosia] Disable async scrolling until implemented

Modified: trunk/Source/WebCore/css/CSSCursorImageValue.cpp (246033 => 246034)


--- trunk/Source/WebCore/css/CSSCursorImageValue.cpp	2019-06-03 09:45:51 UTC (rev 246033)
+++ trunk/Source/WebCore/css/CSSCursorImageValue.cpp	2019-06-03 11:34:20 UTC (rev 246034)
@@ -1,7 +1,7 @@
 /*
  * Copyright (C) 2006 Rob Buis <[email protected]>
  *           (C) 2008 Nikolas Zimmermann <[email protected]>
- * Copyright (C) 2008 Apple Inc. All rights reserved.
+ * Copyright (C) 2008-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
@@ -54,15 +54,10 @@
 
 String CSSCursorImageValue::customCSSText() const
 {
-    StringBuilder result;
-    result.append(m_imageValue.get().cssText());
-    if (m_hasHotSpot) {
-        result.append(' ');
-        result.appendNumber(m_hotSpot.x());
-        result.append(' ');
-        result.appendNumber(m_hotSpot.y());
-    }
-    return result.toString();
+    String text = m_imageValue.get().cssText();
+    if (!m_hasHotSpot)
+        return text;
+    return makeString(text, ' ', m_hotSpot.x(), ' ', m_hotSpot.y());
 }
 
 // FIXME: Should this function take a TreeScope instead?

Modified: trunk/Source/WebCore/css/DOMMatrixReadOnly.cpp (246033 => 246034)


--- trunk/Source/WebCore/css/DOMMatrixReadOnly.cpp	2019-06-03 09:45:51 UTC (rev 246033)
+++ trunk/Source/WebCore/css/DOMMatrixReadOnly.cpp	2019-06-03 11:34:20 UTC (rev 246034)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2017 Apple Inc. All rights reserved.
+ * Copyright (C) 2017-2019 Apple Inc. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -404,56 +404,10 @@
     if (!m_matrix.containsOnlyFiniteValues())
         return Exception { InvalidStateError, "Matrix contains non-finite values"_s };
 
-    StringBuilder builder;
-    if (is2D()) {
-        builder.appendLiteral("matrix(");
-        builder.appendECMAScriptNumber(m_matrix.a());
-        builder.appendLiteral(", ");
-        builder.appendECMAScriptNumber(m_matrix.b());
-        builder.appendLiteral(", ");
-        builder.appendECMAScriptNumber(m_matrix.c());
-        builder.appendLiteral(", ");
-        builder.appendECMAScriptNumber(m_matrix.d());
-        builder.appendLiteral(", ");
-        builder.appendECMAScriptNumber(m_matrix.e());
-        builder.appendLiteral(", ");
-        builder.appendECMAScriptNumber(m_matrix.f());
-    } else {
-        builder.appendLiteral("matrix3d(");
-        builder.appendECMAScriptNumber(m_matrix.m11());
-        builder.appendLiteral(", ");
-        builder.appendECMAScriptNumber(m_matrix.m12());
-        builder.appendLiteral(", ");
-        builder.appendECMAScriptNumber(m_matrix.m13());
-        builder.appendLiteral(", ");
-        builder.appendECMAScriptNumber(m_matrix.m14());
-        builder.appendLiteral(", ");
-        builder.appendECMAScriptNumber(m_matrix.m21());
-        builder.appendLiteral(", ");
-        builder.appendECMAScriptNumber(m_matrix.m22());
-        builder.appendLiteral(", ");
-        builder.appendECMAScriptNumber(m_matrix.m23());
-        builder.appendLiteral(", ");
-        builder.appendECMAScriptNumber(m_matrix.m24());
-        builder.appendLiteral(", ");
-        builder.appendECMAScriptNumber(m_matrix.m31());
-        builder.appendLiteral(", ");
-        builder.appendECMAScriptNumber(m_matrix.m32());
-        builder.appendLiteral(", ");
-        builder.appendECMAScriptNumber(m_matrix.m33());
-        builder.appendLiteral(", ");
-        builder.appendECMAScriptNumber(m_matrix.m34());
-        builder.appendLiteral(", ");
-        builder.appendECMAScriptNumber(m_matrix.m41());
-        builder.appendLiteral(", ");
-        builder.appendECMAScriptNumber(m_matrix.m42());
-        builder.appendLiteral(", ");
-        builder.appendECMAScriptNumber(m_matrix.m43());
-        builder.appendLiteral(", ");
-        builder.appendECMAScriptNumber(m_matrix.m44());
-    }
-    builder.append(')');
-    return builder.toString();
+    if (is2D())
+        return makeString("matrix(", m_matrix.a(), ", ", m_matrix.b(), ", ", m_matrix.c(), ", ", m_matrix.d(), ", ", m_matrix.e(), ", ", m_matrix.f(), ')');
+
+    return makeString("matrix3d(", m_matrix.m11(), ", ", m_matrix.m12(), ", ", m_matrix.m13(), ", ", m_matrix.m14(), ", ", m_matrix.m21(), ", ", m_matrix.m22(), ", ", m_matrix.m23(), ", ", m_matrix.m24(), ", ", m_matrix.m31(), ", ", m_matrix.m32(), ", ", m_matrix.m33(), ", ", m_matrix.m34(), ", ", m_matrix.m41(), ", ", m_matrix.m42(), ", ", m_matrix.m43(), ", ", m_matrix.m44(), ')');
 }
 
 } // namespace WebCore

Modified: trunk/Source/WebCore/css/WebKitCSSMatrix.cpp (246033 => 246034)


--- trunk/Source/WebCore/css/WebKitCSSMatrix.cpp	2019-06-03 09:45:51 UTC (rev 246033)
+++ trunk/Source/WebCore/css/WebKitCSSMatrix.cpp	2019-06-03 11:34:20 UTC (rev 246034)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2008 Apple Inc. All Rights Reserved.
+ * Copyright (C) 2008-2019 Apple Inc. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -35,7 +35,7 @@
 #include "TransformFunctions.h"
 #include <wtf/IsoMallocInlines.h>
 #include <wtf/MathExtras.h>
-#include <wtf/text/StringBuilder.h>
+#include <wtf/text/StringConcatenateNumbers.h>
 
 namespace WebCore {
 
@@ -203,56 +203,10 @@
     if (!m_matrix.containsOnlyFiniteValues())
         return Exception { InvalidStateError, "Matrix contains non-finite values"_s };
 
-    StringBuilder builder;
-    if (m_matrix.isAffine()) {
-        builder.appendLiteral("matrix(");
-        builder.appendECMAScriptNumber(m_matrix.a());
-        builder.appendLiteral(", ");
-        builder.appendECMAScriptNumber(m_matrix.b());
-        builder.appendLiteral(", ");
-        builder.appendECMAScriptNumber(m_matrix.c());
-        builder.appendLiteral(", ");
-        builder.appendECMAScriptNumber(m_matrix.d());
-        builder.appendLiteral(", ");
-        builder.appendECMAScriptNumber(m_matrix.e());
-        builder.appendLiteral(", ");
-        builder.appendECMAScriptNumber(m_matrix.f());
-    } else {
-        builder.appendLiteral("matrix3d(");
-        builder.appendECMAScriptNumber(m_matrix.m11());
-        builder.appendLiteral(", ");
-        builder.appendECMAScriptNumber(m_matrix.m12());
-        builder.appendLiteral(", ");
-        builder.appendECMAScriptNumber(m_matrix.m13());
-        builder.appendLiteral(", ");
-        builder.appendECMAScriptNumber(m_matrix.m14());
-        builder.appendLiteral(", ");
-        builder.appendECMAScriptNumber(m_matrix.m21());
-        builder.appendLiteral(", ");
-        builder.appendECMAScriptNumber(m_matrix.m22());
-        builder.appendLiteral(", ");
-        builder.appendECMAScriptNumber(m_matrix.m23());
-        builder.appendLiteral(", ");
-        builder.appendECMAScriptNumber(m_matrix.m24());
-        builder.appendLiteral(", ");
-        builder.appendECMAScriptNumber(m_matrix.m31());
-        builder.appendLiteral(", ");
-        builder.appendECMAScriptNumber(m_matrix.m32());
-        builder.appendLiteral(", ");
-        builder.appendECMAScriptNumber(m_matrix.m33());
-        builder.appendLiteral(", ");
-        builder.appendECMAScriptNumber(m_matrix.m34());
-        builder.appendLiteral(", ");
-        builder.appendECMAScriptNumber(m_matrix.m41());
-        builder.appendLiteral(", ");
-        builder.appendECMAScriptNumber(m_matrix.m42());
-        builder.appendLiteral(", ");
-        builder.appendECMAScriptNumber(m_matrix.m43());
-        builder.appendLiteral(", ");
-        builder.appendECMAScriptNumber(m_matrix.m44());
-    }
-    builder.append(')');
-    return builder.toString();
+    if (m_matrix.isAffine())
+        return makeString("matrix(", m_matrix.a(), ", ", m_matrix.b(), ", ", m_matrix.c(), ", ", m_matrix.d(), ", ", m_matrix.e(), ", ", m_matrix.f(), ')');
+
+    return makeString("matrix3d(", m_matrix.m11(), ", ", m_matrix.m12(), ", ", m_matrix.m13(), ", ", m_matrix.m14(), ", ", m_matrix.m21(), ", ", m_matrix.m22(), ", ", m_matrix.m23(), ", ", m_matrix.m24(), ", ", m_matrix.m31(), ", ", m_matrix.m32(), ", ", m_matrix.m33(), ", ", m_matrix.m34(), ", ", m_matrix.m41(), ", ", m_matrix.m42(), ", ", m_matrix.m43(), ", ", m_matrix.m44(), ')');
 }
 
 } // namespace WebCore

Modified: trunk/Source/WebCore/html/parser/HTMLParserIdioms.cpp (246033 => 246034)


--- trunk/Source/WebCore/html/parser/HTMLParserIdioms.cpp	2019-06-03 09:45:51 UTC (rev 246033)
+++ trunk/Source/WebCore/html/parser/HTMLParserIdioms.cpp	2019-06-03 11:34:20 UTC (rev 246034)
@@ -89,7 +89,7 @@
 {
     // According to HTML5, "the best representation of the number n as a floating
     // point number" is a string produced by applying ToString() to n.
-    return String::numberToStringECMAScript(number);
+    return String::number(number);
 }
 
 Decimal parseToDecimalForNumberType(const String& string, const Decimal& fallbackValue)

Modified: trunk/Source/WebCore/html/shadow/MediaControlElementTypes.cpp (246033 => 246034)


--- trunk/Source/WebCore/html/shadow/MediaControlElementTypes.cpp	2019-06-03 09:45:51 UTC (rev 246033)
+++ trunk/Source/WebCore/html/shadow/MediaControlElementTypes.cpp	2019-06-03 11:34:20 UTC (rev 246034)
@@ -242,7 +242,7 @@
 void MediaControlVolumeSliderElement::setVolume(double volume)
 {
     if (value().toDouble() != volume)
-        setValue(String::numberToStringECMAScript(volume));
+        setValue(String::number(volume));
 }
 
 void MediaControlVolumeSliderElement::setClearMutedOnUserInteraction(bool clearMute)

Modified: trunk/Source/WebCore/html/shadow/MediaControlElements.cpp (246033 => 246034)


--- trunk/Source/WebCore/html/shadow/MediaControlElements.cpp	2019-06-03 09:45:51 UTC (rev 246033)
+++ trunk/Source/WebCore/html/shadow/MediaControlElements.cpp	2019-06-03 11:34:20 UTC (rev 246034)
@@ -909,7 +909,7 @@
 
 void MediaControlTimelineElement::setPosition(double currentTime)
 {
-    setValue(String::numberToStringECMAScript(currentTime));
+    setValue(String::number(currentTime));
 }
 
 void MediaControlTimelineElement::setDuration(double duration)

Modified: trunk/Source/WebCore/platform/Decimal.cpp (246033 => 246034)


--- trunk/Source/WebCore/platform/Decimal.cpp	2019-06-03 09:45:51 UTC (rev 246033)
+++ trunk/Source/WebCore/platform/Decimal.cpp	2019-06-03 11:34:20 UTC (rev 246034)
@@ -681,8 +681,11 @@
 
 Decimal Decimal::fromDouble(double doubleValue)
 {
-    if (std::isfinite(doubleValue))
-        return fromString(String::numberToStringECMAScript(doubleValue));
+    if (std::isfinite(doubleValue)) {
+        // FIXME: Change fromString to take a StringView instead of a String and then
+        // use a fixed size stack buffer instead of allocating and deallocating a string.
+        return fromString(String::number(doubleValue));
+    }
 
     if (std::isinf(doubleValue))
         return infinity(doubleValue < 0 ? Negative : Positive);

Modified: trunk/Source/WebCore/rendering/RenderListMarker.cpp (246033 => 246034)


--- trunk/Source/WebCore/rendering/RenderListMarker.cpp	2019-06-03 09:45:51 UTC (rev 246033)
+++ trunk/Source/WebCore/rendering/RenderListMarker.cpp	2019-06-03 11:34:20 UTC (rev 246034)
@@ -1,7 +1,7 @@
 /*
  * Copyright (C) 1999 Lars Knoll ([email protected])
  *           (C) 1999 Antti Koivisto ([email protected])
- * Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008 Apple Inc. All rights reserved.
+ * Copyright (C) 2003-2019 Apple Inc. All rights reserved.
  * Copyright (C) 2006 Andrew Wellington ([email protected])
  * Copyright (C) 2010 Daniel Bates ([email protected])
  *
@@ -34,7 +34,7 @@
 #include "RenderView.h"
 #include <wtf/IsoMallocInlines.h>
 #include <wtf/StackStats.h>
-#include <wtf/text/StringBuilder.h>
+#include <wtf/text/StringConcatenateNumbers.h>
 #include <wtf/unicode/CharacterNames.h>
 
 namespace WebCore {
@@ -45,9 +45,10 @@
 
 const int cMarkerPadding = 7;
 
-enum SequenceType { NumericSequence, AlphabeticSequence };
+enum class LetterCase { Lower, Upper };
+enum class SequenceType { Numeric, Alphabetic };
 
-static NEVER_INLINE void toRoman(StringBuilder& builder, int number, bool upper)
+static NEVER_INLINE String toRoman(int number, LetterCase letterCase)
 {
     // FIXME: CSS3 describes how to make this work for much larger numbers,
     // using overbars and special characters. It also specifies the characters
@@ -56,13 +57,13 @@
 
     // Big enough to store largest roman number less than 3999 which
     // is 3888 (MMMDCCCLXXXVIII)
-    const int lettersSize = 15;
+    constexpr unsigned lettersSize = 15;
     LChar letters[lettersSize];
 
-    int length = 0;
+    unsigned length = 0;
     const LChar ldigits[] = { 'i', 'v', 'x', 'l', 'c', 'd', 'm' };
     const LChar udigits[] = { 'I', 'V', 'X', 'L', 'C', 'D', 'M' };
-    const LChar* digits = upper ? udigits : ldigits;
+    const LChar* digits = letterCase == LetterCase::Upper ? udigits : ldigits;
     int d = 0;
     do {
         int num = number % 10;
@@ -80,22 +81,22 @@
     } while (number);
 
     ASSERT(length <= lettersSize);
-    builder.append(&letters[lettersSize - length], length);
+    return String { &letters[lettersSize - length], length };
 }
 
-template <typename CharacterType>
-static inline void toAlphabeticOrNumeric(StringBuilder& builder, int number, const CharacterType* sequence, unsigned sequenceSize, SequenceType type)
+template<typename CharacterType>
+static inline String toAlphabeticOrNumeric(int number, const CharacterType* sequence, unsigned sequenceSize, SequenceType type)
 {
     ASSERT(sequenceSize >= 2);
 
     // Taking sizeof(number) in the _expression_ below doesn't work with some compilers.
-    const int lettersSize = sizeof(int) * 8 + 1; // Binary is the worst case; requires one character per bit plus a minus sign.
+    constexpr unsigned lettersSize = sizeof(int) * 8 + 1; // Binary is the worst case; requires one character per bit plus a minus sign.
 
     CharacterType letters[lettersSize];
 
     bool isNegativeNumber = false;
     unsigned numberShadow = number;
-    if (type == AlphabeticSequence) {
+    if (type == SequenceType::Alphabetic) {
         ASSERT(number > 0);
         --numberShadow;
     } else if (number < 0) {
@@ -103,9 +104,9 @@
         isNegativeNumber = true;
     }
     letters[lettersSize - 1] = sequence[numberShadow % sequenceSize];
-    int length = 1;
+    unsigned length = 1;
 
-    if (type == AlphabeticSequence) {
+    if (type == SequenceType::Alphabetic) {
         while ((numberShadow /= sequenceSize) > 0) {
             --numberShadow;
             letters[lettersSize - ++length] = sequence[numberShadow % sequenceSize];
@@ -118,52 +119,54 @@
         letters[lettersSize - ++length] = hyphenMinus;
 
     ASSERT(length <= lettersSize);
-    builder.append(&letters[lettersSize - length], length);
+    return String { &letters[lettersSize - length], length };
 }
 
-template <typename CharacterType>
-static NEVER_INLINE void toSymbolic(StringBuilder& builder, int number, const CharacterType* symbols, unsigned symbolsSize)
+template<typename CharacterType>
+static NEVER_INLINE String toSymbolic(int number, const CharacterType* symbols, unsigned symbolsSize)
 {
     ASSERT(number > 0);
     ASSERT(symbolsSize >= 1);
-    unsigned numberShadow = number;
-    --numberShadow;
 
-    // The asterisks list-style-type is the worst case; we show |numberShadow| asterisks.
-    builder.append(symbols[numberShadow % symbolsSize]);
-    unsigned numSymbols = numberShadow / symbolsSize;
-    while (numSymbols--)
-        builder.append(symbols[numberShadow % symbolsSize]);
+    // The asterisks list-style-type is the worst case; we show |number| asterisks.
+    CharacterType symbol = symbols[(number - 1) % symbolsSize];
+    unsigned count = (number - 1) / symbolsSize + 1;
+
+    CharacterType* characters;
+    String result = String::createUninitialized(count, characters);
+    for (unsigned i = 0; i < count; ++i)
+        characters[i] = symbol;
+    return result;
 }
 
-template <typename CharacterType>
-static NEVER_INLINE void toAlphabetic(StringBuilder& builder, int number, const CharacterType* alphabet, unsigned alphabetSize)
+template<typename CharacterType>
+static NEVER_INLINE String toAlphabetic(int number, const CharacterType* alphabet, unsigned alphabetSize)
 {
-    toAlphabeticOrNumeric(builder, number, alphabet, alphabetSize, AlphabeticSequence);
+    return toAlphabeticOrNumeric(number, alphabet, alphabetSize, SequenceType::Alphabetic);
 }
 
-template <typename CharacterType>
-static NEVER_INLINE void toNumeric(StringBuilder& builder, int number, const CharacterType* numerals, unsigned numeralsSize)
+template<typename CharacterType>
+static NEVER_INLINE String toNumeric(int number, const CharacterType* numerals, unsigned numeralsSize)
 {
-    toAlphabeticOrNumeric(builder, number, numerals, numeralsSize, NumericSequence);
+    return toAlphabeticOrNumeric(number, numerals, numeralsSize, SequenceType::Numeric);
 }
 
-template <typename CharacterType, size_t size>
-static inline void toAlphabetic(StringBuilder& builder, int number, const CharacterType(&alphabet)[size])
+template<typename CharacterType, size_t size>
+static inline String toAlphabetic(int number, const CharacterType(&alphabet)[size])
 {
-    toAlphabetic(builder, number, alphabet, size);
+    return toAlphabetic(number, alphabet, size);
 }
 
-template <typename CharacterType, size_t size>
-static inline void toNumeric(StringBuilder& builder, int number, const CharacterType(&alphabet)[size])
+template<typename CharacterType, size_t size>
+static inline String toNumeric(int number, const CharacterType(&alphabet)[size])
 {
-    toNumeric(builder, number, alphabet, size);
+    return toNumeric(number, alphabet, size);
 }
 
-template <typename CharacterType, size_t size>
-static inline void toSymbolic(StringBuilder& builder, int number, const CharacterType(&alphabet)[size])
+template<typename CharacterType, size_t size>
+static inline String toSymbolic(int number, const CharacterType(&alphabet)[size])
 {    
-    toSymbolic(builder, number, alphabet, size);
+    return toSymbolic(number, alphabet, size);
 }
 
 static NEVER_INLINE int toHebrewUnder1000(int number, UChar letters[5])
@@ -194,7 +197,7 @@
     return length;
 }
 
-static NEVER_INLINE void toHebrew(StringBuilder& builder, int number)
+static NEVER_INLINE String toHebrew(int number)
 {
     // FIXME: CSS3 mentions ways to make this work for much larger numbers.
     ASSERT(number >= 0 && number <= 999999);
@@ -201,14 +204,13 @@
 
     if (number == 0) {
         static const UChar hebrewZero[3] = { 0x05D0, 0x05E4, 0x05E1 };
-        builder.append(hebrewZero, 3);
-        return;
+        return String { hebrewZero, 3 };
     }
 
-    const int lettersSize = 11; // big enough for two 5-digit sequences plus a quote mark between
+    constexpr unsigned lettersSize = 11; // big enough for two 5-digit sequences plus a quote mark between
     UChar letters[lettersSize];
 
-    int length;
+    unsigned length;
     if (number < 1000)
         length = 0;
     else {
@@ -219,15 +221,15 @@
     length += toHebrewUnder1000(number, letters + length);
 
     ASSERT(length <= lettersSize);
-    builder.append(letters, length);
+    return String { letters, length };
 }
 
-static NEVER_INLINE int toArmenianUnder10000(int number, bool upper, bool addCircumflex, UChar letters[9])
+static NEVER_INLINE unsigned toArmenianUnder10000(int number, LetterCase letterCase, bool addCircumflex, UChar letters[9])
 {
     ASSERT(number >= 0 && number < 10000);
-    int length = 0;
+    unsigned length = 0;
 
-    int lowerOffset = upper ? 0 : 0x0030;
+    int lowerOffset = letterCase == LetterCase::Upper ? 0 : 0x0030;
 
     if (int thousands = number / 1000) {
         if (thousands == 7) {
@@ -262,28 +264,28 @@
     return length;
 }
 
-static NEVER_INLINE void toArmenian(StringBuilder& builder, int number, bool upper)
+static NEVER_INLINE String toArmenian(int number, LetterCase letterCase)
 {
     ASSERT(number >= 1 && number <= 99999999);
 
-    const int lettersSize = 18; // twice what toArmenianUnder10000 needs
+    constexpr unsigned lettersSize = 18; // twice what toArmenianUnder10000 needs
     UChar letters[lettersSize];
 
-    int length = toArmenianUnder10000(number / 10000, upper, true, letters);
-    length += toArmenianUnder10000(number % 10000, upper, false, letters + length);
+    unsigned length = toArmenianUnder10000(number / 10000, letterCase, true, letters);
+    length += toArmenianUnder10000(number % 10000, letterCase, false, letters + length);
 
     ASSERT(length <= lettersSize);
-    builder.append(letters, length);
+    return String { letters, length };
 }
 
-static NEVER_INLINE void toGeorgian(StringBuilder& builder, int number)
+static NEVER_INLINE String toGeorgian(int number)
 {
     ASSERT(number >= 1 && number <= 19999);
 
-    const int lettersSize = 5;
+    constexpr unsigned lettersSize = 5;
     UChar letters[lettersSize];
 
-    int length = 0;
+    unsigned length = 0;
 
     if (number > 9999)
         letters[length++] = 0x10F5;
@@ -317,12 +319,12 @@
     }
 
     ASSERT(length <= lettersSize);
-    builder.append(letters, length);
+    return String { letters, length };
 }
 
 // The table uses the order from the CSS3 specification:
 // first 3 group markers, then 3 digit markers, then ten digits.
-static NEVER_INLINE void toCJKIdeographic(StringBuilder& builder, int number, const UChar table[16])
+static NEVER_INLINE String toCJKIdeographic(int number, const UChar table[16])
 {
     ASSERT(number >= 0);
 
@@ -334,13 +336,11 @@
         digit5, digit6, digit7, digit8, digit9
     };
 
-    if (number == 0) {
-        builder.append(table[digit0 - 1]);
-        return;
-    }
+    if (!number)
+        return String { &table[digit0 - 1] , 1 };
 
-    const int groupLength = 8; // 4 digits, 3 digit markers, and a group marker
-    const int bufferLength = 4 * groupLength;
+    constexpr unsigned groupLength = 8; // 4 digits, 3 digit markers, and a group marker
+    constexpr unsigned bufferLength = 4 * groupLength;
     AbstractCJKChar buffer[bufferLength] = { noChar };
 
     for (int i = 0; i < 4; ++i) {
@@ -381,16 +381,15 @@
             group[4] = noChar;
         }
 
-        if (number == 0)
+        if (!number)
             break;
     }
 
-    // Convert into characters, omitting consecutive runs of digit0 and
-    // any trailing digit0.
-    int length = 0;
+    // Convert into characters, omitting consecutive runs of digit0 and trailing digit0.
+    unsigned length = 0;
     UChar characters[bufferLength];
     AbstractCJKChar last = noChar;
-    for (int i = 0; i < bufferLength; ++i) {
+    for (unsigned i = 0; i < bufferLength; ++i) {
         AbstractCJKChar a = buffer[i];
         if (a != noChar) {
             if (a != digit0 || last != digit0)
@@ -401,7 +400,7 @@
     if (last == digit0)
         --length;
 
-    builder.append(characters, length);
+    return String { characters, length };
 }
 
 static ListStyleType effectiveListMarkerType(ListStyleType type, int value)
@@ -506,7 +505,7 @@
 static UChar listMarkerSuffix(ListStyleType type, int value)
 {
     // If the list-style-type cannot represent |value| because it's outside its
-    // ordinal range then we fall back to some list style that can represent |value|.
+    // ordinal range then we fall back to another list style that can represent |value|.
     ListStyleType effectiveType = effectiveListMarkerType(type, value);
 
     // Note, the following switch statement has been explicitly
@@ -604,10 +603,8 @@
 
 String listMarkerText(ListStyleType type, int value)
 {
-    StringBuilder builder;
-
-    // If the list-style-type, say hebrew, cannot represent |value| because it's outside
-    // its ordinal range then we fallback to some list style that can represent |value|.
+    // If the list-style-type cannot represent |value| because it's outside its
+    // ordinal range then we fall back to another list style that can represent |value|.
     switch (effectiveListMarkerType(type, value)) {
     case ListStyleType::None:
         return emptyString();
@@ -614,58 +611,47 @@
 
     case ListStyleType::Asterisks: {
         static const LChar asterisksSymbols[1] = { 0x2A };
-        toSymbolic(builder, value, asterisksSymbols);
-        break;
+        return toSymbolic(value, asterisksSymbols);
     }
     // We use the same characters for text security.
     // See RenderText::setInternalString.
     case ListStyleType::Circle:
-        builder.append(whiteBullet);
-        break;
+        return String { &whiteBullet, 1 };
     case ListStyleType::Disc:
-        builder.append(bullet);
-        break;
+        return String { &bullet, 1 };
     case ListStyleType::Footnotes: {
         static const UChar footnotesSymbols[4] = { 0x002A, 0x2051, 0x2020, 0x2021 };
-        toSymbolic(builder, value, footnotesSymbols);
-        break;
+        return toSymbolic(value, footnotesSymbols);
     }
     case ListStyleType::Square:
-        // The CSS 2.1 test suite uses U+25EE BLACK MEDIUM SMALL SQUARE
-        // instead, but I think this looks better.
-        builder.append(blackSquare);
-        break;
+        // The CSS 2.1 test suite uses U+25EE BLACK MEDIUM SMALL SQUARE instead,
+        // but we used this because we thought it looked better.
+        return String { &blackSquare, 1 };
 
     case ListStyleType::Decimal:
-        builder.appendNumber(value);
-        break;
+        return String::number(value);
 
     case ListStyleType::DecimalLeadingZero:
-        if (value < -9 || value > 9) {
-            builder.appendNumber(value);
-            break;
+        if (value >= 0 && value <= 9) {
+            LChar characters[2] = { '0', static_cast<LChar>('0' + value) }; // 00 to 09
+            return String { characters, 2 };
         }
-        if (value < 0) {
-            builder.appendLiteral("-0");
-            builder.appendNumber(-value); // -01 to -09
-            break;
+        if (value >= -9 && value <= -1) {
+            LChar characters[3] = { '-', '0', static_cast<LChar>('0' - value) }; // -01 to -09
+            return String { characters, 3 };
         }
-        builder.append('0');
-        builder.appendNumber(value); // 00 to 09
-        break;
+        return String::number(value);
 
     case ListStyleType::ArabicIndic: {
         static const UChar arabicIndicNumerals[10] = {
             0x0660, 0x0661, 0x0662, 0x0663, 0x0664, 0x0665, 0x0666, 0x0667, 0x0668, 0x0669
         };
-        toNumeric(builder, value, arabicIndicNumerals);
-        break;
+        return toNumeric(value, arabicIndicNumerals);
     }
 
     case ListStyleType::Binary: {
         static const LChar binaryNumerals[2] = { '0', '1' };
-        toNumeric(builder, value, binaryNumerals);
-        break;
+        return toNumeric(value, binaryNumerals);
     }
 
     case ListStyleType::Bengali: {
@@ -672,8 +658,7 @@
         static const UChar bengaliNumerals[10] = {
             0x09E6, 0x09E7, 0x09E8, 0x09E9, 0x09EA, 0x09EB, 0x09EC, 0x09ED, 0x09EE, 0x09EF
         };
-        toNumeric(builder, value, bengaliNumerals);
-        break;
+        return toNumeric(value, bengaliNumerals);
     }
 
     case ListStyleType::Cambodian:
@@ -681,85 +666,73 @@
         static const UChar khmerNumerals[10] = {
             0x17E0, 0x17E1, 0x17E2, 0x17E3, 0x17E4, 0x17E5, 0x17E6, 0x17E7, 0x17E8, 0x17E9
         };
-        toNumeric(builder, value, khmerNumerals);
-        break;
+        return toNumeric(value, khmerNumerals);
     }
     case ListStyleType::Devanagari: {
         static const UChar devanagariNumerals[10] = {
             0x0966, 0x0967, 0x0968, 0x0969, 0x096A, 0x096B, 0x096C, 0x096D, 0x096E, 0x096F
         };
-        toNumeric(builder, value, devanagariNumerals);
-        break;
+        return toNumeric(value, devanagariNumerals);
     }
     case ListStyleType::Gujarati: {
         static const UChar gujaratiNumerals[10] = {
             0x0AE6, 0x0AE7, 0x0AE8, 0x0AE9, 0x0AEA, 0x0AEB, 0x0AEC, 0x0AED, 0x0AEE, 0x0AEF
         };
-        toNumeric(builder, value, gujaratiNumerals);
-        break;
+        return toNumeric(value, gujaratiNumerals);
     }
     case ListStyleType::Gurmukhi: {
         static const UChar gurmukhiNumerals[10] = {
             0x0A66, 0x0A67, 0x0A68, 0x0A69, 0x0A6A, 0x0A6B, 0x0A6C, 0x0A6D, 0x0A6E, 0x0A6F
         };
-        toNumeric(builder, value, gurmukhiNumerals);
-        break;
+        return toNumeric(value, gurmukhiNumerals);
     }
     case ListStyleType::Kannada: {
         static const UChar kannadaNumerals[10] = {
             0x0CE6, 0x0CE7, 0x0CE8, 0x0CE9, 0x0CEA, 0x0CEB, 0x0CEC, 0x0CED, 0x0CEE, 0x0CEF
         };
-        toNumeric(builder, value, kannadaNumerals);
-        break;
+        return toNumeric(value, kannadaNumerals);
     }
     case ListStyleType::LowerHexadecimal: {
         static const LChar lowerHexadecimalNumerals[16] = {
             '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f'
         };
-        toNumeric(builder, value, lowerHexadecimalNumerals);
-        break;
+        return toNumeric(value, lowerHexadecimalNumerals);
     }
     case ListStyleType::Lao: {
         static const UChar laoNumerals[10] = {
             0x0ED0, 0x0ED1, 0x0ED2, 0x0ED3, 0x0ED4, 0x0ED5, 0x0ED6, 0x0ED7, 0x0ED8, 0x0ED9
         };
-        toNumeric(builder, value, laoNumerals);
-        break;
+        return toNumeric(value, laoNumerals);
     }
     case ListStyleType::Malayalam: {
         static const UChar malayalamNumerals[10] = {
             0x0D66, 0x0D67, 0x0D68, 0x0D69, 0x0D6A, 0x0D6B, 0x0D6C, 0x0D6D, 0x0D6E, 0x0D6F
         };
-        toNumeric(builder, value, malayalamNumerals);
-        break;
+        return toNumeric(value, malayalamNumerals);
     }
     case ListStyleType::Mongolian: {
         static const UChar mongolianNumerals[10] = {
             0x1810, 0x1811, 0x1812, 0x1813, 0x1814, 0x1815, 0x1816, 0x1817, 0x1818, 0x1819
         };
-        toNumeric(builder, value, mongolianNumerals);
-        break;
+        return toNumeric(value, mongolianNumerals);
     }
     case ListStyleType::Myanmar: {
         static const UChar myanmarNumerals[10] = {
             0x1040, 0x1041, 0x1042, 0x1043, 0x1044, 0x1045, 0x1046, 0x1047, 0x1048, 0x1049
         };
-        toNumeric(builder, value, myanmarNumerals);
-        break;
+        return toNumeric(value, myanmarNumerals);
     }
     case ListStyleType::Octal: {
         static const LChar octalNumerals[8] = {
             '0', '1', '2', '3', '4', '5', '6', '7'
         };
-        toNumeric(builder, value, octalNumerals);
-        break;
+        return toNumeric(value, octalNumerals);
     }
     case ListStyleType::Oriya: {
         static const UChar oriyaNumerals[10] = {
             0x0B66, 0x0B67, 0x0B68, 0x0B69, 0x0B6A, 0x0B6B, 0x0B6C, 0x0B6D, 0x0B6E, 0x0B6F
         };
-        toNumeric(builder, value, oriyaNumerals);
-        break;
+        return toNumeric(value, oriyaNumerals);
     }
     case ListStyleType::Persian:
     case ListStyleType::Urdu: {
@@ -766,36 +739,31 @@
         static const UChar urduNumerals[10] = {
             0x06F0, 0x06F1, 0x06F2, 0x06F3, 0x06F4, 0x06F5, 0x06F6, 0x06F7, 0x06F8, 0x06F9
         };
-        toNumeric(builder, value, urduNumerals);
-        break;
+        return toNumeric(value, urduNumerals);
     }
     case ListStyleType::Telugu: {
         static const UChar teluguNumerals[10] = {
             0x0C66, 0x0C67, 0x0C68, 0x0C69, 0x0C6A, 0x0C6B, 0x0C6C, 0x0C6D, 0x0C6E, 0x0C6F
         };
-        toNumeric(builder, value, teluguNumerals);
-        break;
+        return toNumeric(value, teluguNumerals);
     }
     case ListStyleType::Tibetan: {
         static const UChar tibetanNumerals[10] = {
             0x0F20, 0x0F21, 0x0F22, 0x0F23, 0x0F24, 0x0F25, 0x0F26, 0x0F27, 0x0F28, 0x0F29
         };
-        toNumeric(builder, value, tibetanNumerals);
-        break;
+        return toNumeric(value, tibetanNumerals);
     }
     case ListStyleType::Thai: {
         static const UChar thaiNumerals[10] = {
             0x0E50, 0x0E51, 0x0E52, 0x0E53, 0x0E54, 0x0E55, 0x0E56, 0x0E57, 0x0E58, 0x0E59
         };
-        toNumeric(builder, value, thaiNumerals);
-        break;
+        return toNumeric(value, thaiNumerals);
     }
     case ListStyleType::UpperHexadecimal: {
         static const LChar upperHexadecimalNumerals[16] = {
             '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F'
         };
-        toNumeric(builder, value, upperHexadecimalNumerals);
-        break;
+        return toNumeric(value, upperHexadecimalNumerals);
     }
 
     case ListStyleType::LowerAlpha:
@@ -804,8 +772,7 @@
             'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm',
             'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z'
         };
-        toAlphabetic(builder, value, lowerLatinAlphabet);
-        break;
+        return toAlphabetic(value, lowerLatinAlphabet);
     }
     case ListStyleType::UpperAlpha:
     case ListStyleType::UpperLatin: {
@@ -813,8 +780,7 @@
             'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M',
             'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z'
         };
-        toAlphabetic(builder, value, upperLatinAlphabet);
-        break;
+        return toAlphabetic(value, upperLatinAlphabet);
     }
     case ListStyleType::LowerGreek: {
         static const UChar lowerGreekAlphabet[24] = {
@@ -822,8 +788,7 @@
             0x03B9, 0x03BA, 0x03BB, 0x03BC, 0x03BD, 0x03BE, 0x03BF, 0x03C0,
             0x03C1, 0x03C3, 0x03C4, 0x03C5, 0x03C6, 0x03C7, 0x03C8, 0x03C9
         };
-        toAlphabetic(builder, value, lowerGreekAlphabet);
-        break;
+        return toAlphabetic(value, lowerGreekAlphabet);
     }
 
     case ListStyleType::Hiragana: {
@@ -837,8 +802,7 @@
             0x3080, 0x3081, 0x3082, 0x3084, 0x3086, 0x3088, 0x3089, 0x308A,
             0x308B, 0x308C, 0x308D, 0x308F, 0x3090, 0x3091, 0x3092, 0x3093
         };
-        toAlphabetic(builder, value, hiraganaAlphabet);
-        break;
+        return toAlphabetic(value, hiraganaAlphabet);
     }
     case ListStyleType::HiraganaIroha: {
         // FIXME: This table comes from the CSS3 draft, and is probably
@@ -851,8 +815,7 @@
             0x3053, 0x3048, 0x3066, 0x3042, 0x3055, 0x304D, 0x3086, 0x3081,
             0x307F, 0x3057, 0x3091, 0x3072, 0x3082, 0x305B, 0x3059
         };
-        toAlphabetic(builder, value, hiraganaIrohaAlphabet);
-        break;
+        return toAlphabetic(value, hiraganaIrohaAlphabet);
     }
     case ListStyleType::Katakana: {
         // FIXME: This table comes from the CSS3 draft, and is probably
@@ -865,8 +828,7 @@
             0x30E0, 0x30E1, 0x30E2, 0x30E4, 0x30E6, 0x30E8, 0x30E9, 0x30EA,
             0x30EB, 0x30EC, 0x30ED, 0x30EF, 0x30F0, 0x30F1, 0x30F2, 0x30F3
         };
-        toAlphabetic(builder, value, katakanaAlphabet);
-        break;
+        return toAlphabetic(value, katakanaAlphabet);
     }
     case ListStyleType::KatakanaIroha: {
         // FIXME: This table comes from the CSS3 draft, and is probably
@@ -879,8 +841,7 @@
             0x30B3, 0x30A8, 0x30C6, 0x30A2, 0x30B5, 0x30AD, 0x30E6, 0x30E1,
             0x30DF, 0x30B7, 0x30F1, 0x30D2, 0x30E2, 0x30BB, 0x30B9
         };
-        toAlphabetic(builder, value, katakanaIrohaAlphabet);
-        break;
+        return toAlphabetic(value, katakanaIrohaAlphabet);
     }
 
     case ListStyleType::Afar:
@@ -890,8 +851,7 @@
             0x1200, 0x1208, 0x1210, 0x1218, 0x1228, 0x1230, 0x1260, 0x1270, 0x1290,
             0x12A0, 0x12A8, 0x12C8, 0x12D0, 0x12E8, 0x12F0, 0x1308, 0x1338, 0x1348
         };
-        toAlphabetic(builder, value, ethiopicHalehameAaErAlphabet);
-        break;
+        return toAlphabetic(value, ethiopicHalehameAaErAlphabet);
     }
     case ListStyleType::Amharic:
     case ListStyleType::EthiopicHalehameAmEt: {
@@ -901,8 +861,7 @@
             0x12C8, 0x12D0, 0x12D8, 0x12E0, 0x12E8, 0x12F0, 0x1300, 0x1308, 0x1320,
             0x1328, 0x1330, 0x1338, 0x1340, 0x1348, 0x1350
         };
-        toAlphabetic(builder, value, ethiopicHalehameAmEtAlphabet);
-        break;
+        return toAlphabetic(value, ethiopicHalehameAmEtAlphabet);
     }
     case ListStyleType::AmharicAbegede:
     case ListStyleType::EthiopicAbegedeAmEt: {
@@ -912,8 +871,7 @@
             0x1298, 0x1220, 0x12D0, 0x1348, 0x1338, 0x1240, 0x1228, 0x1230, 0x1238,
             0x1270, 0x1278, 0x1280, 0x1340, 0x1330, 0x1350
         };
-        toAlphabetic(builder, value, ethiopicAbegedeAmEtAlphabet);
-        break;
+        return toAlphabetic(value, ethiopicAbegedeAmEtAlphabet);
     }
     case ListStyleType::CjkEarthlyBranch: {
         static const UChar cjkEarthlyBranchAlphabet[12] = {
@@ -920,8 +878,7 @@
             0x5B50, 0x4E11, 0x5BC5, 0x536F, 0x8FB0, 0x5DF3, 0x5348, 0x672A, 0x7533,
             0x9149, 0x620C, 0x4EA5
         };
-        toAlphabetic(builder, value, cjkEarthlyBranchAlphabet);
-        break;
+        return toAlphabetic(value, cjkEarthlyBranchAlphabet);
     }
     case ListStyleType::CjkHeavenlyStem: {
         static const UChar cjkHeavenlyStemAlphabet[10] = {
@@ -928,8 +885,7 @@
             0x7532, 0x4E59, 0x4E19, 0x4E01, 0x620A, 0x5DF1, 0x5E9A, 0x8F9B, 0x58EC,
             0x7678
         };
-        toAlphabetic(builder, value, cjkHeavenlyStemAlphabet);
-        break;
+        return toAlphabetic(value, cjkHeavenlyStemAlphabet);
     }
     case ListStyleType::Ethiopic:
     case ListStyleType::EthiopicHalehameGez: {
@@ -938,8 +894,7 @@
             0x1270, 0x1280, 0x1290, 0x12A0, 0x12A8, 0x12C8, 0x12D0, 0x12D8, 0x12E8,
             0x12F0, 0x1308, 0x1320, 0x1330, 0x1338, 0x1340, 0x1348, 0x1350
         };
-        toAlphabetic(builder, value, ethiopicHalehameGezAlphabet);
-        break;
+        return toAlphabetic(value, ethiopicHalehameGezAlphabet);
     }
     case ListStyleType::EthiopicAbegede:
     case ListStyleType::EthiopicAbegedeGez: {
@@ -948,8 +903,7 @@
             0x12E8, 0x12A8, 0x1208, 0x1218, 0x1290, 0x1220, 0x12D0, 0x1348, 0x1338,
             0x1240, 0x1228, 0x1230, 0x1270, 0x1280, 0x1340, 0x1330, 0x1350
         };
-        toAlphabetic(builder, value, ethiopicAbegedeGezAlphabet);
-        break;
+        return toAlphabetic(value, ethiopicAbegedeGezAlphabet);
     }
     case ListStyleType::HangulConsonant: {
         static const UChar hangulConsonantAlphabet[14] = {
@@ -956,8 +910,7 @@
             0x3131, 0x3134, 0x3137, 0x3139, 0x3141, 0x3142, 0x3145, 0x3147, 0x3148,
             0x314A, 0x314B, 0x314C, 0x314D, 0x314E
         };
-        toAlphabetic(builder, value, hangulConsonantAlphabet);
-        break;
+        return toAlphabetic(value, hangulConsonantAlphabet);
     }
     case ListStyleType::Hangul: {
         static const UChar hangulAlphabet[14] = {
@@ -964,8 +917,7 @@
             0xAC00, 0xB098, 0xB2E4, 0xB77C, 0xB9C8, 0xBC14, 0xC0AC, 0xC544, 0xC790,
             0xCC28, 0xCE74, 0xD0C0, 0xD30C, 0xD558
         };
-        toAlphabetic(builder, value, hangulAlphabet);
-        break;
+        return toAlphabetic(value, hangulAlphabet);
     }
     case ListStyleType::Oromo:
     case ListStyleType::EthiopicHalehameOmEt: {
@@ -974,8 +926,7 @@
             0x1278, 0x1290, 0x1298, 0x12A0, 0x12A8, 0x12C8, 0x12E8, 0x12F0, 0x12F8,
             0x1300, 0x1308, 0x1320, 0x1328, 0x1338, 0x1330, 0x1348
         };
-        toAlphabetic(builder, value, ethiopicHalehameOmEtAlphabet);
-        break;
+        return toAlphabetic(value, ethiopicHalehameOmEtAlphabet);
     }
     case ListStyleType::Sidama:
     case ListStyleType::EthiopicHalehameSidEt: {
@@ -984,8 +935,7 @@
             0x1270, 0x1278, 0x1290, 0x1298, 0x12A0, 0x12A8, 0x12C8, 0x12E8, 0x12F0,
             0x12F8, 0x1300, 0x1308, 0x1320, 0x1328, 0x1338, 0x1330, 0x1348
         };
-        toAlphabetic(builder, value, ethiopicHalehameSidEtAlphabet);
-        break;
+        return toAlphabetic(value, ethiopicHalehameSidEtAlphabet);
     }
     case ListStyleType::Somali:
     case ListStyleType::EthiopicHalehameSoEt: {
@@ -994,8 +944,7 @@
             0x1270, 0x1290, 0x12A0, 0x12A8, 0x12B8, 0x12C8, 0x12D0, 0x12E8, 0x12F0,
             0x1300, 0x1308, 0x1338, 0x1348
         };
-        toAlphabetic(builder, value, ethiopicHalehameSoEtAlphabet);
-        break;
+        return toAlphabetic(value, ethiopicHalehameSoEtAlphabet);
     }
     case ListStyleType::Tigre:
     case ListStyleType::EthiopicHalehameTig: {
@@ -1004,8 +953,7 @@
             0x1270, 0x1278, 0x1290, 0x12A0, 0x12A8, 0x12C8, 0x12D0, 0x12D8, 0x12E8,
             0x12F0, 0x1300, 0x1308, 0x1320, 0x1328, 0x1338, 0x1330, 0x1348, 0x1350
         };
-        toAlphabetic(builder, value, ethiopicHalehameTigAlphabet);
-        break;
+        return toAlphabetic(value, ethiopicHalehameTigAlphabet);
     }
     case ListStyleType::TigrinyaEr:
     case ListStyleType::EthiopicHalehameTiEr: {
@@ -1015,8 +963,7 @@
             0x12D0, 0x12D8, 0x12E0, 0x12E8, 0x12F0, 0x1300, 0x1308, 0x1320, 0x1328,
             0x1330, 0x1338, 0x1348, 0x1350
         };
-        toAlphabetic(builder, value, ethiopicHalehameTiErAlphabet);
-        break;
+        return toAlphabetic(value, ethiopicHalehameTiErAlphabet);
     }
     case ListStyleType::TigrinyaErAbegede:
     case ListStyleType::EthiopicAbegedeTiEr: {
@@ -1026,8 +973,7 @@
             0x1298, 0x12D0, 0x1348, 0x1338, 0x1240, 0x1250, 0x1228, 0x1230, 0x1238,
             0x1270, 0x1278, 0x1330, 0x1350
         };
-        toAlphabetic(builder, value, ethiopicAbegedeTiErAlphabet);
-        break;
+        return toAlphabetic(value, ethiopicAbegedeTiErAlphabet);
     }
     case ListStyleType::TigrinyaEt:
     case ListStyleType::EthiopicHalehameTiEt: {
@@ -1037,8 +983,7 @@
             0x12B8, 0x12C8, 0x12D0, 0x12D8, 0x12E0, 0x12E8, 0x12F0, 0x1300, 0x1308,
             0x1320, 0x1328, 0x1330, 0x1338, 0x1340, 0x1348, 0x1350
         };
-        toAlphabetic(builder, value, ethiopicHalehameTiEtAlphabet);
-        break;
+        return toAlphabetic(value, ethiopicHalehameTiEtAlphabet);
     }
     case ListStyleType::TigrinyaEtAbegede:
     case ListStyleType::EthiopicAbegedeTiEt: {
@@ -1048,8 +993,7 @@
             0x1298, 0x1220, 0x12D0, 0x1348, 0x1338, 0x1240, 0x1250, 0x1228, 0x1230,
             0x1238, 0x1270, 0x1278, 0x1280, 0x1340, 0x1330, 0x1350
         };
-        toAlphabetic(builder, value, ethiopicAbegedeTiEtAlphabet);
-        break;
+        return toAlphabetic(value, ethiopicAbegedeTiEtAlphabet);
     }
     case ListStyleType::UpperGreek: {
         static const UChar upperGreekAlphabet[24] = {
@@ -1057,8 +1001,7 @@
             0x039A, 0x039B, 0x039C, 0x039D, 0x039E, 0x039F, 0x03A0, 0x03A1, 0x03A3,
             0x03A4, 0x03A5, 0x03A6, 0x03A7, 0x03A8, 0x03A9
         };
-        toAlphabetic(builder, value, upperGreekAlphabet);
-        break;
+        return toAlphabetic(value, upperGreekAlphabet);
     }
     case ListStyleType::LowerNorwegian: {
         static const LChar lowerNorwegianAlphabet[29] = {
@@ -1067,8 +1010,7 @@
             0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, 0x7A, 0xE6,
             0xF8, 0xE5
         };
-        toAlphabetic(builder, value, lowerNorwegianAlphabet);
-        break;
+        return toAlphabetic(value, lowerNorwegianAlphabet);
     }
     case ListStyleType::UpperNorwegian: {
         static const LChar upperNorwegianAlphabet[29] = {
@@ -1077,8 +1019,7 @@
             0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59, 0x5A, 0xC6,
             0xD8, 0xC5
         };
-        toAlphabetic(builder, value, upperNorwegianAlphabet);
-        break;
+        return toAlphabetic(value, upperNorwegianAlphabet);
     }
     case ListStyleType::CJKIdeographic: {
         static const UChar traditionalChineseInformalTable[16] = {
@@ -1087,36 +1028,30 @@
             0x96F6, 0x4E00, 0x4E8C, 0x4E09, 0x56DB,
             0x4E94, 0x516D, 0x4E03, 0x516B, 0x4E5D
         };
-        toCJKIdeographic(builder, value, traditionalChineseInformalTable);
-        break;
+        return toCJKIdeographic(value, traditionalChineseInformalTable);
     }
 
     case ListStyleType::LowerRoman:
-        toRoman(builder, value, false);
-        break;
+        return toRoman(value, LetterCase::Lower);
     case ListStyleType::UpperRoman:
-        toRoman(builder, value, true);
-        break;
+        return toRoman(value, LetterCase::Upper);
 
+    // A CSS3 draft said that "armenian" means "lower-armenian". But the CSS2.1 test
+    // suite contains uppercase test results for "armenian"; our behavior matches that.
     case ListStyleType::Armenian:
     case ListStyleType::UpperArmenian:
-        // CSS3 says "armenian" means "lower-armenian".
-        // But the CSS2.1 test suite contains uppercase test results for "armenian",
-        // so we'll match the test suite.
-        toArmenian(builder, value, true);
-        break;
+        return toArmenian(value, LetterCase::Upper);
     case ListStyleType::LowerArmenian:
-        toArmenian(builder, value, false);
-        break;
+        return toArmenian(value, LetterCase::Lower);
+
     case ListStyleType::Georgian:
-        toGeorgian(builder, value);
-        break;
+        return toGeorgian(value);
     case ListStyleType::Hebrew:
-        toHebrew(builder, value);
-        break;
+        return toHebrew(value);
     }
 
-    return builder.toString();
+    ASSERT_NOT_REACHED();
+    return emptyString();
 }
 
 RenderListMarker::RenderListMarker(RenderListItem& listItem, RenderStyle&& style)
@@ -1350,32 +1285,35 @@
     else {
         const UChar suffix = listMarkerSuffix(type, m_listItem->value());
 
-        // Text is not arbitrary. We can judge whether it's RTL from the first character,
-        // and we only need to handle the direction U_RIGHT_TO_LEFT for now.
-        bool textNeedsReversing = u_charDirection(m_text[0]) == U_RIGHT_TO_LEFT;
-        String toDraw;
-        if (textNeedsReversing) {
+        // FIXME: Could use a Vector with inline capacity instead of String to avoid
+        // memory allocation here.
+        String textToDraw;
+
+        // Since marker text is not arbitrary, we can judge its direction just by
+        // checking the first character, and only need to handle U_RIGHT_TO_LEFT.
+        // FIXME: Could check more efficiently than u_charDirection, since we know
+        // only certain characters are used and only need to check for U_RIGHT_TO_LEFT.
+        if (u_charDirection(m_text[0]) == U_RIGHT_TO_LEFT) {
             unsigned length = m_text.length();
-            StringBuilder buffer;
-            buffer.reserveCapacity(length + 2);
+            UChar* characters;
+            textToDraw = String::createUninitialized(length + 2, characters);
             if (!style().isLeftToRightDirection()) {
-                buffer.append(space);
-                buffer.append(suffix);
+                *characters++ = space;
+                *characters++ = suffix;
             }
             for (unsigned i = 0; i < length; ++i)
-                buffer.append(m_text[length - i - 1]);
+                *characters++ = m_text[length - i - 1];
             if (style().isLeftToRightDirection()) {
-                buffer.append(suffix);
-                buffer.append(space);
+                *characters++ = suffix;
+                *characters++ = space;
             }
-            toDraw = buffer.toString();
         } else {
             if (style().isLeftToRightDirection())
-                toDraw = m_text + String(&suffix, 1) + String(&space, 1);
+                textToDraw = makeString(m_text, suffix, space);
             else
-                toDraw = String(&space, 1) + String(&suffix, 1) + m_text;
+                textToDraw = makeString(space, suffix, m_text);
         }
-        textRun.setText(StringView(toDraw));
+        textRun.setText(textToDraw);
 
         context.drawText(font, textRun, textOrigin);
     }
@@ -1568,8 +1506,8 @@
     case ListStyleType::Footnotes: {
         TextRun run = RenderBlock::constructTextRun(m_text, style());
         logicalWidth = font.width(run); // no suffix for these types
+        break;
     }
-        break;
     case ListStyleType::Circle:
     case ListStyleType::Disc:
     case ListStyleType::Square:

Modified: trunk/Source/WebCore/svg/SVGPathUtilities.cpp (246033 => 246034)


--- trunk/Source/WebCore/svg/SVGPathUtilities.cpp	2019-06-03 09:45:51 UTC (rev 246033)
+++ trunk/Source/WebCore/svg/SVGPathUtilities.cpp	2019-06-03 11:34:20 UTC (rev 246034)
@@ -60,39 +60,39 @@
             switch (element.type) {
             case PathElementMoveToPoint:
                 builder.append('M');
-                builder.appendShortestFormNumber(element.points[0].x());
+                builder.appendNumber(element.points[0].x());
                 builder.append(' ');
-                builder.appendShortestFormNumber(element.points[0].y());
+                builder.appendNumber(element.points[0].y());
                 break;
             case PathElementAddLineToPoint:
                 builder.append('L');
-                builder.appendShortestFormNumber(element.points[0].x());
+                builder.appendNumber(element.points[0].x());
                 builder.append(' ');
-                builder.appendShortestFormNumber(element.points[0].y());
+                builder.appendNumber(element.points[0].y());
                 break;
             case PathElementAddQuadCurveToPoint:
                 builder.append('Q');
-                builder.appendShortestFormNumber(element.points[0].x());
+                builder.appendNumber(element.points[0].x());
                 builder.append(' ');
-                builder.appendShortestFormNumber(element.points[0].y());
+                builder.appendNumber(element.points[0].y());
                 builder.append(',');
-                builder.appendShortestFormNumber(element.points[1].x());
+                builder.appendNumber(element.points[1].x());
                 builder.append(' ');
-                builder.appendShortestFormNumber(element.points[1].y());
+                builder.appendNumber(element.points[1].y());
                 break;
             case PathElementAddCurveToPoint:
                 builder.append('C');
-                builder.appendShortestFormNumber(element.points[0].x());
+                builder.appendNumber(element.points[0].x());
                 builder.append(' ');
-                builder.appendShortestFormNumber(element.points[0].y());
+                builder.appendNumber(element.points[0].y());
                 builder.append(',');
-                builder.appendShortestFormNumber(element.points[1].x());
+                builder.appendNumber(element.points[1].x());
                 builder.append(' ');
-                builder.appendShortestFormNumber(element.points[1].y());
+                builder.appendNumber(element.points[1].y());
                 builder.append(',');
-                builder.appendShortestFormNumber(element.points[2].x());
+                builder.appendNumber(element.points[2].x());
                 builder.append(' ');
-                builder.appendShortestFormNumber(element.points[2].y());
+                builder.appendNumber(element.points[2].y());
                 break;
             case PathElementCloseSubpath:
                 builder.append('Z');

Modified: trunk/Source/WebKit/ChangeLog (246033 => 246034)


--- trunk/Source/WebKit/ChangeLog	2019-06-03 09:45:51 UTC (rev 246033)
+++ trunk/Source/WebKit/ChangeLog	2019-06-03 11:34:20 UTC (rev 246034)
@@ -1,3 +1,18 @@
+2019-06-03  Darin Adler  <[email protected]>
+
+        Finish cleanup of String::number for floating point
+        https://bugs.webkit.org/show_bug.cgi?id=198471
+
+        Reviewed by Yusuke Suzuki.
+
+        * NetworkProcess/Classifier/WebResourceLoadStatisticsTelemetry.cpp:
+        (WebKit::submitTopList): Use makeString instead of StringBuilder since it
+        is more terse and possibly more efficient as well.
+        * UIProcess/API/APIUserScript.cpp:
+        (API::UserScript::generateUniqueURL): Ditto.
+        * UIProcess/API/APIUserStyleSheet.cpp:
+        (API::UserStyleSheet::generateUniqueURL): Ditto.
+
 2019-06-03  Fujii Hironori  <[email protected]>
 
         REGRESSION(r240862) [WinCairo][WK2] position:fixed elements don't show

Modified: trunk/Source/WebKit/NetworkProcess/Classifier/WebResourceLoadStatisticsTelemetry.cpp (246033 => 246034)


--- trunk/Source/WebKit/NetworkProcess/Classifier/WebResourceLoadStatisticsTelemetry.cpp	2019-06-03 09:45:51 UTC (rev 246033)
+++ trunk/Source/WebKit/NetworkProcess/Classifier/WebResourceLoadStatisticsTelemetry.cpp	2019-06-03 11:34:20 UTC (rev 246034)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2017 Apple Inc. All rights reserved.
+ * Copyright (C) 2017-2019 Apple Inc. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -37,7 +37,7 @@
 #include <wtf/MainThread.h>
 #include <wtf/NeverDestroyed.h>
 #include <wtf/RunLoop.h>
-#include <wtf/text/StringBuilder.h>
+#include <wtf/text/StringConcatenateNumbers.h>
 
 namespace WebKit {
 using namespace WebCore;
@@ -159,11 +159,8 @@
     unsigned topNumberOfTimesAccessedAsFirstPartyDueToUserInteraction = median(sortedPrevalentResourcesWithoutUserInteraction, 0, numberOfResourcesFromTheTop - 1, numberOfTimesAccessedAsFirstPartyDueToUserInteractionGetter);
     unsigned topNumberOfTimesAccessedAsFirstPartyDueToStorageAccessAPI = median(sortedPrevalentResourcesWithoutUserInteraction, 0, numberOfResourcesFromTheTop - 1, numberOfTimesAccessedAsFirstPartyDueToStorageAccessAPIGetter);
 
-    StringBuilder preambleBuilder;
-    preambleBuilder.appendLiteral("top");
-    preambleBuilder.appendNumber(numberOfResourcesFromTheTop);
-    String descriptionPreamble = preambleBuilder.toString();
-    
+    String descriptionPreamble = makeString("top", numberOfResourcesFromTheTop);
+
     store.sendDiagnosticMessageWithValue(DiagnosticLoggingKeys::resourceLoadStatisticsTelemetryKey(), descriptionPreamble + "PrevalentResourcesWithUserInteraction",
         topPrevalentResourcesWithUserInteraction, significantFiguresForLoggedValues, ShouldSample::No);
     store.sendDiagnosticMessageWithValue(DiagnosticLoggingKeys::resourceLoadStatisticsTelemetryKey(), descriptionPreamble + "SubframeUnderTopFrameOrigins",

Modified: trunk/Source/WebKit/UIProcess/API/APIUserScript.cpp (246033 => 246034)


--- trunk/Source/WebKit/UIProcess/API/APIUserScript.cpp	2019-06-03 09:45:51 UTC (rev 246033)
+++ trunk/Source/WebKit/UIProcess/API/APIUserScript.cpp	2019-06-03 11:34:20 UTC (rev 246034)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2015 Apple Inc. All rights reserved.
+ * Copyright (C) 2015-2019 Apple Inc. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -26,7 +26,7 @@
 #include "config.h"
 #include "APIUserScript.h"
 
-#include <wtf/text/StringBuilder.h>
+#include <wtf/text/StringConcatenateNumbers.h>
 
 namespace API {
 
@@ -33,11 +33,7 @@
 WTF::URL UserScript::generateUniqueURL()
 {
     static uint64_t identifier;
-
-    StringBuilder urlStringBuilder;
-    urlStringBuilder.appendLiteral("user-script:");
-    urlStringBuilder.appendNumber(++identifier);
-    return { { }, urlStringBuilder.toString() };
+    return { { }, makeString("user-script:", ++identifier) };
 }
 
 UserScript::UserScript(WebCore::UserScript userScript, API::UserContentWorld& world)

Modified: trunk/Source/WebKit/UIProcess/API/APIUserStyleSheet.cpp (246033 => 246034)


--- trunk/Source/WebKit/UIProcess/API/APIUserStyleSheet.cpp	2019-06-03 09:45:51 UTC (rev 246033)
+++ trunk/Source/WebKit/UIProcess/API/APIUserStyleSheet.cpp	2019-06-03 11:34:20 UTC (rev 246034)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2015 Apple Inc. All rights reserved.
+ * Copyright (C) 2015-2019 Apple Inc. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -26,7 +26,7 @@
 #include "config.h"
 #include "APIUserStyleSheet.h"
 
-#include <wtf/text/StringBuilder.h>
+#include <wtf/text/StringConcatenateNumbers.h>
 
 namespace API {
 
@@ -33,11 +33,7 @@
 WTF::URL UserStyleSheet::generateUniqueURL()
 {
     static uint64_t identifier;
-
-    StringBuilder urlStringBuilder;
-    urlStringBuilder.appendLiteral("user-style-sheet:");
-    urlStringBuilder.appendNumber(++identifier);
-    return { { }, urlStringBuilder.toString() };
+    return { { }, makeString("user-style-sheet:", ++identifier) };
 }
 
 UserStyleSheet::UserStyleSheet(WebCore::UserStyleSheet userStyleSheet, API::UserContentWorld& world)

Modified: trunk/Tools/ChangeLog (246033 => 246034)


--- trunk/Tools/ChangeLog	2019-06-03 09:45:51 UTC (rev 246033)
+++ trunk/Tools/ChangeLog	2019-06-03 11:34:20 UTC (rev 246034)
@@ -1,3 +1,18 @@
+2019-06-03  Darin Adler  <[email protected]>
+
+        Finish cleanup of String::number for floating point
+        https://bugs.webkit.org/show_bug.cgi?id=198471
+
+        Reviewed by Yusuke Suzuki.
+
+        * TestWebKitAPI/Tests/WTF/WTFString.cpp:
+        (TestWebKitAPI::testStringNumber): Go back to calling String::number instead of
+        String::numberToStringECMAScript.
+
+        * WebKitTestRunner/InjectedBundle/InjectedBundlePage.cpp:
+        (WTR::dumpFrameScrollPosition): Use appendNumber instead of appendECMAScriptNumber
+        since that is now the default.
+
 2019-06-02  Fujii Hironori  <[email protected]>
 
         [WinCairo][MiniBrowser] WKViewSetIsInWindow should be called

Modified: trunk/Tools/TestWebKitAPI/Tests/WTF/WTFString.cpp (246033 => 246034)


--- trunk/Tools/TestWebKitAPI/Tests/WTF/WTFString.cpp	2019-06-03 09:45:51 UTC (rev 246033)
+++ trunk/Tools/TestWebKitAPI/Tests/WTF/WTFString.cpp	2019-06-03 11:34:20 UTC (rev 246034)
@@ -172,7 +172,7 @@
 static inline const char* testStringNumber(double number)
 {
     static char testBuffer[100] = { };
-    std::strncpy(testBuffer, String::numberToStringECMAScript(number).utf8().data(), 99);
+    std::strncpy(testBuffer, String::number(number).utf8().data(), 99);
     return testBuffer;
 }
 

Modified: trunk/Tools/WebKitTestRunner/InjectedBundle/InjectedBundlePage.cpp (246033 => 246034)


--- trunk/Tools/WebKitTestRunner/InjectedBundle/InjectedBundlePage.cpp	2019-06-03 09:45:51 UTC (rev 246033)
+++ trunk/Tools/WebKitTestRunner/InjectedBundle/InjectedBundlePage.cpp	2019-06-03 11:34:20 UTC (rev 246034)
@@ -782,9 +782,9 @@
         stringBuilder.appendLiteral("' ");
     }
     stringBuilder.appendLiteral("scrolled to ");
-    stringBuilder.appendECMAScriptNumber(x);
+    stringBuilder.appendNumber(x);
     stringBuilder.append(',');
-    stringBuilder.appendECMAScriptNumber(y);
+    stringBuilder.appendNumber(y);
     stringBuilder.append('\n');
 }
 
_______________________________________________
webkit-changes mailing list
[email protected]
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to