[WTF] Turn tryMakeString(), makeString() into variadic templates
authorjfbastien@apple.com <jfbastien@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Tue, 13 Dec 2016 19:15:05 +0000 (19:15 +0000)
committerjfbastien@apple.com <jfbastien@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Tue, 13 Dec 2016 19:15:05 +0000 (19:15 +0000)
https://bugs.webkit.org/show_bug.cgi?id=147142

Reviewed by Mark Lam.

Source/JavaScriptCore:

* runtime/JSStringBuilder.h:
(JSC::jsMakeNontrivialString): remove WTF:: prefix, it isn't needed anymore
* runtime/Lookup.cpp:
(JSC::reifyStaticAccessor): remove WTF:: prefix, it isn't needed anymore
* runtime/ObjectPrototype.cpp:
(JSC::objectProtoFuncToString): remove WTF:: prefix, it isn't needed anymore

Source/WTF:

I wrote this patch while improving WebAssembly's error messages,
and only found this bug afterwards. My implementation does the
bare minimum to make this code variadic without changing
behavior. I think it's better to go with this baby step first, and
improve the code later.

Notable, for my WebAssembly patch I also taught the code to handle
integers and other types (including WebAssembly types). A
follow-up could rely on ADL magic to pretty-format these other
types.

* wtf/text/StringConcatenate.h:
(WTF::sumWithOverflow): This unconditionally does the sum for all
inputs, which the compiler is more likely to appreciate (because
it's the common case) compared to testing for overflow and bailing
on each addition
(WTF::are8Bit): are: the plural of is!
(WTF::makeStringAccumulator): accumulate strings
(WTF::tryMakeStringFromAdapters): a small helper which creates the string adapters
(WTF::tryMakeString): expose out of WTF, since it's part of this file's used API
(WTF::makeString): make it variadic

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

Source/JavaScriptCore/ChangeLog
Source/JavaScriptCore/runtime/JSStringBuilder.h
Source/JavaScriptCore/runtime/Lookup.cpp
Source/JavaScriptCore/runtime/ObjectPrototype.cpp
Source/WTF/ChangeLog
Source/WTF/wtf/text/StringConcatenate.h

index b669003..c89f038 100644 (file)
@@ -1,3 +1,17 @@
+2016-12-13  JF Bastien  <jfbastien@apple.com>
+
+        [WTF] Turn tryMakeString(), makeString() into variadic templates
+        https://bugs.webkit.org/show_bug.cgi?id=147142
+
+        Reviewed by Mark Lam.
+
+        * runtime/JSStringBuilder.h:
+        (JSC::jsMakeNontrivialString): remove WTF:: prefix, it isn't needed anymore
+        * runtime/Lookup.cpp:
+        (JSC::reifyStaticAccessor): remove WTF:: prefix, it isn't needed anymore
+        * runtime/ObjectPrototype.cpp:
+        (JSC::objectProtoFuncToString): remove WTF:: prefix, it isn't needed anymore
+
 2016-12-12  Mark Lam  <mark.lam@apple.com>
 
         Rename BytecodeGenerator's ControlFlowContext to ControlFlowScope.
index f7bacca..88ad6dd 100644 (file)
@@ -130,7 +130,7 @@ inline JSValue jsMakeNontrivialString(ExecState* exec, const StringType& string,
 {
     VM& vm = exec->vm();
     auto scope = DECLARE_THROW_SCOPE(vm);
-    String result = WTF::tryMakeString(string, strings...);
+    String result = tryMakeString(string, strings...);
     if (UNLIKELY(!result || !JSString::isValidLength(result.length())))
         return throwOutOfMemoryError(exec, scope);
     return jsNontrivialString(exec, WTFMove(result));
index 2b5404e..f40740e 100644 (file)
@@ -31,7 +31,7 @@ void reifyStaticAccessor(VM& vm, const HashTableValue& value, JSObject& thisObje
     JSGlobalObject* globalObject = thisObject.globalObject();
     GetterSetter* accessor = GetterSetter::create(vm, globalObject);
     if (value.accessorGetter()) {
-        String getterName = WTF::tryMakeString(ASCIILiteral("get "), String(*propertyName.publicName()));
+        String getterName = tryMakeString(ASCIILiteral("get "), String(*propertyName.publicName()));
         if (!getterName)
             return;
         accessor->setGetter(vm, globalObject, value.attributes() & Builtin
index 615a1e7..69d313f 100644 (file)
@@ -337,7 +337,7 @@ EncodedJSValue JSC_HOST_CALL objectProtoFuncToString(ExecState* exec)
 
         String tag = thisObject->methodTable(vm)->toStringName(thisObject, exec);
         RETURN_IF_EXCEPTION(scope, { });
-        String newString = WTF::tryMakeString("[object ", WTFMove(tag), "]");
+        String newString = tryMakeString("[object ", WTFMove(tag), "]");
         if (!newString)
             return throwOutOfMemoryError(exec, scope);
 
index 8529ebf..9c2ee55 100644 (file)
@@ -1,3 +1,32 @@
+2016-12-13  JF Bastien  <jfbastien@apple.com>
+
+        [WTF] Turn tryMakeString(), makeString() into variadic templates
+        https://bugs.webkit.org/show_bug.cgi?id=147142
+
+        Reviewed by Mark Lam.
+
+        I wrote this patch while improving WebAssembly's error messages,
+        and only found this bug afterwards. My implementation does the
+        bare minimum to make this code variadic without changing
+        behavior. I think it's better to go with this baby step first, and
+        improve the code later.
+
+        Notable, for my WebAssembly patch I also taught the code to handle
+        integers and other types (including WebAssembly types). A
+        follow-up could rely on ADL magic to pretty-format these other
+        types.
+
+        * wtf/text/StringConcatenate.h:
+        (WTF::sumWithOverflow): This unconditionally does the sum for all
+        inputs, which the compiler is more likely to appreciate (because
+        it's the common case) compared to testing for overflow and bailing
+        on each addition
+        (WTF::are8Bit): are: the plural of is!
+        (WTF::makeStringAccumulator): accumulate strings
+        (WTF::tryMakeStringFromAdapters): a small helper which creates the string adapters
+        (WTF::tryMakeString): expose out of WTF, since it's part of this file's used API
+        (WTF::makeString): make it variadic
+
 2016-12-13  Konstantin Tokarev  <annulen@yandex.ru>
 
         Unreviewed, silence -Wsuggest-attribute for GCC with pragmas
index 77f34df..affb7e1 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2010-2015 Apple Inc. All rights reserved.
+ * Copyright (C) 2010-2016 Apple Inc. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -141,7 +141,7 @@ public:
         while (m_characters[length])
             ++length;
 
-        if (length > std::numeric_limits<unsigned>::max())
+        if (length > std::numeric_limits<unsigned>::max()) // FIXME this is silly https://bugs.webkit.org/show_bug.cgi?id=165790
             CRASH();
 
         m_length = length;
@@ -152,7 +152,7 @@ public:
 
     NO_RETURN_DUE_TO_CRASH void writeTo(LChar*) const
     {
-        CRASH();
+        CRASH(); // FIXME make this a compile-time failure https://bugs.webkit.org/show_bug.cgi?id=165791
     }
 
     void writeTo(UChar* destination) const
@@ -259,7 +259,7 @@ public:
     }
 };
 
-inline void sumWithOverflow(unsigned& total, unsigned addend, bool& overflow)
+inline void sumWithOverflow(bool& overflow, unsigned& total, unsigned addend)
 {
     unsigned oldTotal = total;
     total = oldTotal + addend;
@@ -267,381 +267,57 @@ inline void sumWithOverflow(unsigned& total, unsigned addend, bool& overflow)
         overflow = true;
 }
 
-template<typename StringType1, typename StringType2>
-String tryMakeString(StringType1 string1, StringType2 string2)
-{
-    StringTypeAdapter<StringType1> adapter1(string1);
-    StringTypeAdapter<StringType2> adapter2(string2);
-
-    if (adapter1.length() && !adapter2.length())
-        return adapter1.toString();
-    if (!adapter1.length() && adapter2.length())
-        return adapter2.toString();
-
-    bool overflow = false;
-    unsigned length = adapter1.length();
-    sumWithOverflow(length, adapter2.length(), overflow);
-    if (overflow)
-        return String();
-
-    if (adapter1.is8Bit() && adapter2.is8Bit()) {
-        LChar* buffer;
-        RefPtr<StringImpl> resultImpl = StringImpl::tryCreateUninitialized(length, buffer);
-        if (!resultImpl)
-            return String();
-
-        LChar* result = buffer;
-        adapter1.writeTo(result);
-        result += adapter1.length();
-        adapter2.writeTo(result);
-
-        return WTFMove(resultImpl);
-    }
-
-    UChar* buffer;
-    RefPtr<StringImpl> resultImpl = StringImpl::tryCreateUninitialized(length, buffer);
-    if (!resultImpl)
-        return String();
-
-    UChar* result = buffer;
-    adapter1.writeTo(result);
-    result += adapter1.length();
-    adapter2.writeTo(result);
-
-    return WTFMove(resultImpl);
-}
-
-template<typename StringType1, typename StringType2, typename StringType3>
-String tryMakeString(StringType1 string1, StringType2 string2, StringType3 string3)
+template<typename... Unsigned>
+inline void sumWithOverflow(bool& overflow, unsigned& total, unsigned addend, Unsigned ...addends)
 {
-    StringTypeAdapter<StringType1> adapter1(string1);
-    StringTypeAdapter<StringType2> adapter2(string2);
-    StringTypeAdapter<StringType3> adapter3(string3);
-
-    bool overflow = false;
-    unsigned length = adapter1.length();
-    sumWithOverflow(length, adapter2.length(), overflow);
-    sumWithOverflow(length, adapter3.length(), overflow);
-    if (overflow)
-        return String();
-
-    if (adapter1.is8Bit() && adapter2.is8Bit() && adapter3.is8Bit()) {
-        LChar* buffer;
-        RefPtr<StringImpl> resultImpl = StringImpl::tryCreateUninitialized(length, buffer);
-        if (!resultImpl)
-            return String();
-
-        LChar* result = buffer;
-        adapter1.writeTo(result);
-        result += adapter1.length();
-        adapter2.writeTo(result);
-        result += adapter2.length();
-        adapter3.writeTo(result);
-
-        return WTFMove(resultImpl);
-    }
-
-    UChar* buffer = 0;
-    RefPtr<StringImpl> resultImpl = StringImpl::tryCreateUninitialized(length, buffer);
-    if (!resultImpl)
-        return String();
-
-    UChar* result = buffer;
-    adapter1.writeTo(result);
-    result += adapter1.length();
-    adapter2.writeTo(result);
-    result += adapter2.length();
-    adapter3.writeTo(result);
-
-    return WTFMove(resultImpl);
+    unsigned oldTotal = total;
+    total = oldTotal + addend;
+    if (total < oldTotal)
+        overflow = true;
+    sumWithOverflow(overflow, total, addends...);
 }
 
-template<typename StringType1, typename StringType2, typename StringType3, typename StringType4>
-String tryMakeString(StringType1 string1, StringType2 string2, StringType3 string3, StringType4 string4)
+template<typename Adapter>
+inline bool are8Bit(Adapter adapter)
 {
-    StringTypeAdapter<StringType1> adapter1(string1);
-    StringTypeAdapter<StringType2> adapter2(string2);
-    StringTypeAdapter<StringType3> adapter3(string3);
-    StringTypeAdapter<StringType4> adapter4(string4);
-
-    bool overflow = false;
-    unsigned length = adapter1.length();
-    sumWithOverflow(length, adapter2.length(), overflow);
-    sumWithOverflow(length, adapter3.length(), overflow);
-    sumWithOverflow(length, adapter4.length(), overflow);
-    if (overflow)
-        return String();
-
-    if (adapter1.is8Bit() && adapter2.is8Bit() && adapter3.is8Bit() && adapter4.is8Bit()) {
-        LChar* buffer;
-        RefPtr<StringImpl> resultImpl = StringImpl::tryCreateUninitialized(length, buffer);
-        if (!resultImpl)
-            return String();
-
-        LChar* result = buffer;
-        adapter1.writeTo(result);
-        result += adapter1.length();
-        adapter2.writeTo(result);
-        result += adapter2.length();
-        adapter3.writeTo(result);
-        result += adapter3.length();
-        adapter4.writeTo(result);
-
-        return WTFMove(resultImpl);
-    }
-
-    UChar* buffer;
-    RefPtr<StringImpl> resultImpl = StringImpl::tryCreateUninitialized(length, buffer);
-    if (!resultImpl)
-        return String();
-
-    UChar* result = buffer;
-    adapter1.writeTo(result);
-    result += adapter1.length();
-    adapter2.writeTo(result);
-    result += adapter2.length();
-    adapter3.writeTo(result);
-    result += adapter3.length();
-    adapter4.writeTo(result);
-
-    return WTFMove(resultImpl);
+    return adapter.is8Bit();
 }
 
-template<typename StringType1, typename StringType2, typename StringType3, typename StringType4, typename StringType5>
-String tryMakeString(StringType1 string1, StringType2 string2, StringType3 string3, StringType4 string4, StringType5 string5)
+template<typename Adapter, typename... Adapters>
+inline bool are8Bit(Adapter adapter, Adapters ...adapters)
 {
-    StringTypeAdapter<StringType1> adapter1(string1);
-    StringTypeAdapter<StringType2> adapter2(string2);
-    StringTypeAdapter<StringType3> adapter3(string3);
-    StringTypeAdapter<StringType4> adapter4(string4);
-    StringTypeAdapter<StringType5> adapter5(string5);
-
-    bool overflow = false;
-    unsigned length = adapter1.length();
-    sumWithOverflow(length, adapter2.length(), overflow);
-    sumWithOverflow(length, adapter3.length(), overflow);
-    sumWithOverflow(length, adapter4.length(), overflow);
-    sumWithOverflow(length, adapter5.length(), overflow);
-    if (overflow)
-        return String();
-
-    if (adapter1.is8Bit() && adapter2.is8Bit() && adapter3.is8Bit() && adapter4.is8Bit() && adapter5.is8Bit()) {
-        LChar* buffer;
-        RefPtr<StringImpl> resultImpl = StringImpl::tryCreateUninitialized(length, buffer);
-        if (!resultImpl)
-            return String();
-
-        LChar* result = buffer;
-        adapter1.writeTo(result);
-        result += adapter1.length();
-        adapter2.writeTo(result);
-        result += adapter2.length();
-        adapter3.writeTo(result);
-        result += adapter3.length();
-        adapter4.writeTo(result);
-        result += adapter4.length();
-        adapter5.writeTo(result);
-
-        return WTFMove(resultImpl);
-    }
-
-    UChar* buffer;
-    RefPtr<StringImpl> resultImpl = StringImpl::tryCreateUninitialized(length, buffer);
-    if (!resultImpl)
-        return String();
-
-    UChar* result = buffer;
-    adapter1.writeTo(result);
-    result += adapter1.length();
-    adapter2.writeTo(result);
-    result += adapter2.length();
-    adapter3.writeTo(result);
-    result += adapter3.length();
-    adapter4.writeTo(result);
-    result += adapter4.length();
-    adapter5.writeTo(result);
-
-    return WTFMove(resultImpl);
+    return adapter.is8Bit() && are8Bit(adapters...);
 }
 
-template<typename StringType1, typename StringType2, typename StringType3, typename StringType4, typename StringType5, typename StringType6>
-String tryMakeString(StringType1 string1, StringType2 string2, StringType3 string3, StringType4 string4, StringType5 string5, StringType6 string6)
+template<typename ResultType, typename Adapter>
+inline void makeStringAccumulator(ResultType* result, Adapter adapter)
 {
-    StringTypeAdapter<StringType1> adapter1(string1);
-    StringTypeAdapter<StringType2> adapter2(string2);
-    StringTypeAdapter<StringType3> adapter3(string3);
-    StringTypeAdapter<StringType4> adapter4(string4);
-    StringTypeAdapter<StringType5> adapter5(string5);
-    StringTypeAdapter<StringType6> adapter6(string6);
-
-    bool overflow = false;
-    unsigned length = adapter1.length();
-    sumWithOverflow(length, adapter2.length(), overflow);
-    sumWithOverflow(length, adapter3.length(), overflow);
-    sumWithOverflow(length, adapter4.length(), overflow);
-    sumWithOverflow(length, adapter5.length(), overflow);
-    sumWithOverflow(length, adapter6.length(), overflow);
-    if (overflow)
-        return String();
-
-    if (adapter1.is8Bit() && adapter2.is8Bit() && adapter3.is8Bit() && adapter4.is8Bit() && adapter5.is8Bit() && adapter6.is8Bit()) {
-        LChar* buffer;
-        RefPtr<StringImpl> resultImpl = StringImpl::tryCreateUninitialized(length, buffer);
-        if (!resultImpl)
-            return String();
-
-        LChar* result = buffer;
-        adapter1.writeTo(result);
-        result += adapter1.length();
-        adapter2.writeTo(result);
-        result += adapter2.length();
-        adapter3.writeTo(result);
-        result += adapter3.length();
-        adapter4.writeTo(result);
-        result += adapter4.length();
-        adapter5.writeTo(result);
-        result += adapter5.length();
-        adapter6.writeTo(result);
-
-        return WTFMove(resultImpl);
-    }
-
-    UChar* buffer;
-    RefPtr<StringImpl> resultImpl = StringImpl::tryCreateUninitialized(length, buffer);
-    if (!resultImpl)
-        return String();
-
-    UChar* result = buffer;
-    adapter1.writeTo(result);
-    result += adapter1.length();
-    adapter2.writeTo(result);
-    result += adapter2.length();
-    adapter3.writeTo(result);
-    result += adapter3.length();
-    adapter4.writeTo(result);
-    result += adapter4.length();
-    adapter5.writeTo(result);
-    result += adapter5.length();
-    adapter6.writeTo(result);
-
-    return WTFMove(resultImpl);
+    adapter.writeTo(result);
 }
 
-template<typename StringType1, typename StringType2, typename StringType3, typename StringType4, typename StringType5, typename StringType6, typename StringType7>
-String tryMakeString(StringType1 string1, StringType2 string2, StringType3 string3, StringType4 string4, StringType5 string5, StringType6 string6, StringType7 string7)
+template<typename ResultType, typename Adapter, typename... Adapters>
+inline void makeStringAccumulator(ResultType* result, Adapter adapter, Adapters ...adapters)
 {
-    StringTypeAdapter<StringType1> adapter1(string1);
-    StringTypeAdapter<StringType2> adapter2(string2);
-    StringTypeAdapter<StringType3> adapter3(string3);
-    StringTypeAdapter<StringType4> adapter4(string4);
-    StringTypeAdapter<StringType5> adapter5(string5);
-    StringTypeAdapter<StringType6> adapter6(string6);
-    StringTypeAdapter<StringType7> adapter7(string7);
-
-    bool overflow = false;
-    unsigned length = adapter1.length();
-    sumWithOverflow(length, adapter2.length(), overflow);
-    sumWithOverflow(length, adapter3.length(), overflow);
-    sumWithOverflow(length, adapter4.length(), overflow);
-    sumWithOverflow(length, adapter5.length(), overflow);
-    sumWithOverflow(length, adapter6.length(), overflow);
-    sumWithOverflow(length, adapter7.length(), overflow);
-    if (overflow)
-        return String();
-
-    if (adapter1.is8Bit() && adapter2.is8Bit() && adapter3.is8Bit() && adapter4.is8Bit() && adapter5.is8Bit() && adapter6.is8Bit() && adapter7.is8Bit()) {
-        LChar* buffer;
-        RefPtr<StringImpl> resultImpl = StringImpl::tryCreateUninitialized(length, buffer);
-        if (!resultImpl)
-            return String();
-
-        LChar* result = buffer;
-        adapter1.writeTo(result);
-        result += adapter1.length();
-        adapter2.writeTo(result);
-        result += adapter2.length();
-        adapter3.writeTo(result);
-        result += adapter3.length();
-        adapter4.writeTo(result);
-        result += adapter4.length();
-        adapter5.writeTo(result);
-        result += adapter5.length();
-        adapter6.writeTo(result);
-        result += adapter6.length();
-        adapter7.writeTo(result);
-
-        return WTFMove(resultImpl);
-    }
-
-    UChar* buffer;
-    RefPtr<StringImpl> resultImpl = StringImpl::tryCreateUninitialized(length, buffer);
-    if (!resultImpl)
-        return String();
-
-    UChar* result = buffer;
-    adapter1.writeTo(result);
-    result += adapter1.length();
-    adapter2.writeTo(result);
-    result += adapter2.length();
-    adapter3.writeTo(result);
-    result += adapter3.length();
-    adapter4.writeTo(result);
-    result += adapter4.length();
-    adapter5.writeTo(result);
-    result += adapter5.length();
-    adapter6.writeTo(result);
-    result += adapter6.length();
-    adapter7.writeTo(result);
-
-    return WTFMove(resultImpl);
+    adapter.writeTo(result);
+    makeStringAccumulator(result + adapter.length(), adapters...);
 }
 
-template<typename StringType1, typename StringType2, typename StringType3, typename StringType4, typename StringType5, typename StringType6, typename StringType7, typename StringType8>
-String tryMakeString(StringType1 string1, StringType2 string2, StringType3 string3, StringType4 string4, StringType5 string5, StringType6 string6, StringType7 string7, StringType8 string8)
+template<typename StringTypeAdapter, typename... StringTypeAdapters>
+String tryMakeStringFromAdapters(StringTypeAdapter adapter, StringTypeAdapters ...adapters)
 {
-    StringTypeAdapter<StringType1> adapter1(string1);
-    StringTypeAdapter<StringType2> adapter2(string2);
-    StringTypeAdapter<StringType3> adapter3(string3);
-    StringTypeAdapter<StringType4> adapter4(string4);
-    StringTypeAdapter<StringType5> adapter5(string5);
-    StringTypeAdapter<StringType6> adapter6(string6);
-    StringTypeAdapter<StringType7> adapter7(string7);
-    StringTypeAdapter<StringType8> adapter8(string8);
-
     bool overflow = false;
-    unsigned length = adapter1.length();
-    sumWithOverflow(length, adapter2.length(), overflow);
-    sumWithOverflow(length, adapter3.length(), overflow);
-    sumWithOverflow(length, adapter4.length(), overflow);
-    sumWithOverflow(length, adapter5.length(), overflow);
-    sumWithOverflow(length, adapter6.length(), overflow);
-    sumWithOverflow(length, adapter7.length(), overflow);
-    sumWithOverflow(length, adapter8.length(), overflow);
+    unsigned length = adapter.length();
+    sumWithOverflow(overflow, length, adapters.length()...);
     if (overflow)
         return String();
 
-    if (adapter1.is8Bit() && adapter2.is8Bit() && adapter3.is8Bit() && adapter4.is8Bit() && adapter5.is8Bit() && adapter6.is8Bit() && adapter7.is8Bit() && adapter8.is8Bit()) {
+    if (are8Bit(adapter, adapters...)) {
         LChar* buffer;
         RefPtr<StringImpl> resultImpl = StringImpl::tryCreateUninitialized(length, buffer);
         if (!resultImpl)
             return String();
 
-        LChar* result = buffer;
-        adapter1.writeTo(result);
-        result += adapter1.length();
-        adapter2.writeTo(result);
-        result += adapter2.length();
-        adapter3.writeTo(result);
-        result += adapter3.length();
-        adapter4.writeTo(result);
-        result += adapter4.length();
-        adapter5.writeTo(result);
-        result += adapter5.length();
-        adapter6.writeTo(result);
-        result += adapter6.length();
-        adapter7.writeTo(result);
-        result += adapter7.length();
-        adapter8.writeTo(result);
+        makeStringAccumulator(buffer, adapter, adapters...);
 
         return WTFMove(resultImpl);
     }
@@ -651,182 +327,28 @@ String tryMakeString(StringType1 string1, StringType2 string2, StringType3 strin
     if (!resultImpl)
         return String();
 
-    UChar* result = buffer;
-    adapter1.writeTo(result);
-    result += adapter1.length();
-    adapter2.writeTo(result);
-    result += adapter2.length();
-    adapter3.writeTo(result);
-    result += adapter3.length();
-    adapter4.writeTo(result);
-    result += adapter4.length();
-    adapter5.writeTo(result);
-    result += adapter5.length();
-    adapter6.writeTo(result);
-    result += adapter6.length();
-    adapter7.writeTo(result);
-    result += adapter7.length();
-    adapter8.writeTo(result);
+    makeStringAccumulator(buffer, adapter, adapters...);
 
     return WTFMove(resultImpl);
 }
 
-template<typename StringType1, typename StringType2, typename StringType3, typename StringType4, typename StringType5, typename StringType6, typename StringType7, typename StringType8, typename StringType9>
-String tryMakeString(StringType1 string1, StringType2 string2, StringType3 string3, StringType4 string4, StringType5 string5, StringType6 string6, StringType7 string7, StringType8 string8, StringType9 string9)
+template<typename... StringTypes>
+String tryMakeString(StringTypes ...strings)
 {
-    StringTypeAdapter<StringType1> adapter1(string1);
-    StringTypeAdapter<StringType2> adapter2(string2);
-    StringTypeAdapter<StringType3> adapter3(string3);
-    StringTypeAdapter<StringType4> adapter4(string4);
-    StringTypeAdapter<StringType5> adapter5(string5);
-    StringTypeAdapter<StringType6> adapter6(string6);
-    StringTypeAdapter<StringType7> adapter7(string7);
-    StringTypeAdapter<StringType8> adapter8(string8);
-    StringTypeAdapter<StringType9> adapter9(string9);
-
-    bool overflow = false;
-    unsigned length = adapter1.length();
-    sumWithOverflow(length, adapter2.length(), overflow);
-    sumWithOverflow(length, adapter3.length(), overflow);
-    sumWithOverflow(length, adapter4.length(), overflow);
-    sumWithOverflow(length, adapter5.length(), overflow);
-    sumWithOverflow(length, adapter6.length(), overflow);
-    sumWithOverflow(length, adapter7.length(), overflow);
-    sumWithOverflow(length, adapter8.length(), overflow);
-    sumWithOverflow(length, adapter9.length(), overflow);
-    if (overflow)
-        return String();
-
-    if (adapter1.is8Bit() && adapter2.is8Bit() && adapter3.is8Bit() && adapter4.is8Bit() && adapter5.is8Bit() && adapter6.is8Bit() && adapter7.is8Bit() && adapter8.is8Bit() && adapter9.is8Bit()) {
-        LChar* buffer;
-        RefPtr<StringImpl> resultImpl = StringImpl::tryCreateUninitialized(length, buffer);
-        if (!resultImpl)
-            return String();
-
-        LChar* result = buffer;
-        adapter1.writeTo(result);
-        result += adapter1.length();
-        adapter2.writeTo(result);
-        result += adapter2.length();
-        adapter3.writeTo(result);
-        result += adapter3.length();
-        adapter4.writeTo(result);
-        result += adapter4.length();
-        adapter5.writeTo(result);
-        result += adapter5.length();
-        adapter6.writeTo(result);
-        result += adapter6.length();
-        adapter7.writeTo(result);
-        result += adapter7.length();
-        adapter8.writeTo(result);
-        result += adapter8.length();
-        adapter9.writeTo(result);
-
-        return WTFMove(resultImpl);
-    }
-
-    UChar* buffer;
-    RefPtr<StringImpl> resultImpl = StringImpl::tryCreateUninitialized(length, buffer);
-    if (!resultImpl)
-        return String();
-
-    UChar* result = buffer;
-    adapter1.writeTo(result);
-    result += adapter1.length();
-    adapter2.writeTo(result);
-    result += adapter2.length();
-    adapter3.writeTo(result);
-    result += adapter3.length();
-    adapter4.writeTo(result);
-    result += adapter4.length();
-    adapter5.writeTo(result);
-    result += adapter5.length();
-    adapter6.writeTo(result);
-    result += adapter6.length();
-    adapter7.writeTo(result);
-    result += adapter7.length();
-    adapter8.writeTo(result);
-    result += adapter8.length();
-    adapter9.writeTo(result);
-
-    return WTFMove(resultImpl);
+    return tryMakeStringFromAdapters(StringTypeAdapter<StringTypes>(strings)...);
 }
 
-
 // Convenience only.
-template<typename StringType1>
-String makeString(StringType1 string1)
-{
-    return String(string1);
-}
-
-template<typename StringType1, typename StringType2>
-String makeString(StringType1 string1, StringType2 string2)
-{
-    String result = tryMakeString(string1, string2);
-    if (!result)
-        CRASH();
-    return result;
-}
-
-template<typename StringType1, typename StringType2, typename StringType3>
-String makeString(StringType1 string1, StringType2 string2, StringType3 string3)
-{
-    String result = tryMakeString(string1, string2, string3);
-    if (!result)
-        CRASH();
-    return result;
-}
-
-template<typename StringType1, typename StringType2, typename StringType3, typename StringType4>
-String makeString(StringType1 string1, StringType2 string2, StringType3 string3, StringType4 string4)
-{
-    String result = tryMakeString(string1, string2, string3, string4);
-    if (!result)
-        CRASH();
-    return result;
-}
-
-template<typename StringType1, typename StringType2, typename StringType3, typename StringType4, typename StringType5>
-String makeString(StringType1 string1, StringType2 string2, StringType3 string3, StringType4 string4, StringType5 string5)
-{
-    String result = tryMakeString(string1, string2, string3, string4, string5);
-    if (!result)
-        CRASH();
-    return result;
-}
-
-template<typename StringType1, typename StringType2, typename StringType3, typename StringType4, typename StringType5, typename StringType6>
-String makeString(StringType1 string1, StringType2 string2, StringType3 string3, StringType4 string4, StringType5 string5, StringType6 string6)
-{
-    String result = tryMakeString(string1, string2, string3, string4, string5, string6);
-    if (!result)
-        CRASH();
-    return result;
-}
-
-template<typename StringType1, typename StringType2, typename StringType3, typename StringType4, typename StringType5, typename StringType6, typename StringType7>
-String makeString(StringType1 string1, StringType2 string2, StringType3 string3, StringType4 string4, StringType5 string5, StringType6 string6, StringType7 string7)
-{
-    String result = tryMakeString(string1, string2, string3, string4, string5, string6, string7);
-    if (!result)
-        CRASH();
-    return result;
-}
-
-template<typename StringType1, typename StringType2, typename StringType3, typename StringType4, typename StringType5, typename StringType6, typename StringType7, typename StringType8>
-String makeString(StringType1 string1, StringType2 string2, StringType3 string3, StringType4 string4, StringType5 string5, StringType6 string6, StringType7 string7, StringType8 string8)
+template<typename StringType>
+String makeString(StringType string)
 {
-    String result = tryMakeString(string1, string2, string3, string4, string5, string6, string7, string8);
-    if (!result)
-        CRASH();
-    return result;
+    return String(string);
 }
 
-template<typename StringType1, typename StringType2, typename StringType3, typename StringType4, typename StringType5, typename StringType6, typename StringType7, typename StringType8, typename StringType9>
-String makeString(StringType1 string1, StringType2 string2, StringType3 string3, StringType4 string4, StringType5 string5, StringType6 string6, StringType7 string7, StringType8 string8, StringType9 string9)
+template<typename... StringTypes>
+String makeString(StringTypes... strings)
 {
-    String result = tryMakeString(string1, string2, string3, string4, string5, string6, string7, string8, string9);
+    String result = tryMakeString(strings...);
     if (!result)
         CRASH();
     return result;
@@ -835,6 +357,7 @@ String makeString(StringType1 string1, StringType2 string2, StringType3 string3,
 } // namespace WTF
 
 using WTF::makeString;
+using WTF::tryMakeString;
 
 #include <wtf/text/StringOperators.h>
 #endif