Use more efficient makeString() instead of StringBuilder
https://bugs.webkit.org/show_bug.cgi?id=213708
Reviewed by Sam Weinig.
Source/WebCore:
This patch refactors throwRequiredMemberTypeError() and throwArgument*Error()
methods, replacing all StringBuilder usages with more efficient makeString().
Extracts makeArgumentTypeErrorMessage(), similiar to existing helpers,
which can be reused if neccessary.
No new tests, no behavior change.
* bindings/js/JSDOMExceptionHandling.cpp:
(WebCore::makeArgumentTypeErrorMessage):
(WebCore::throwArgumentMustBeEnumError):
(WebCore::throwArgumentMustBeFunctionError):
(WebCore::throwArgumentMustBeObjectError):
(WebCore::throwArgumentTypeError):
(WebCore::throwRequiredMemberTypeError):
(WebCore::appendArgumentMustBe): Deleted.
Source/WTF:
Introduces StringTypeAdapter<std::tuple> overload, which enables using
makeString() instead of StringBuilder in more cases.
* wtf/text/StringConcatenate.h:
(WTF::StringTypeAdapter<std::tuple<StringTypes...>, void>): Added.
git-svn-id: http://svn.webkit.org/repository/webkit/trunk@263795 268f45cc-cd09-0410-ab3c-d52691b4dbfc
diff --git a/Source/WTF/ChangeLog b/Source/WTF/ChangeLog
index 891ce31..13ddb98 100644
--- a/Source/WTF/ChangeLog
+++ b/Source/WTF/ChangeLog
@@ -1,3 +1,16 @@
+2020-07-01 Alexey Shvayka <shvaikalesh@gmail.com>
+
+ Use more efficient makeString() instead of StringBuilder
+ https://bugs.webkit.org/show_bug.cgi?id=213708
+
+ Reviewed by Sam Weinig.
+
+ Introduces StringTypeAdapter<std::tuple> overload, which enables using
+ makeString() instead of StringBuilder in more cases.
+
+ * wtf/text/StringConcatenate.h:
+ (WTF::StringTypeAdapter<std::tuple<StringTypes...>, void>): Added.
+
2020-06-30 Geoffrey Garen <ggaren@apple.com>
[Cocoa] [GTK] RunLoop::Timer::isActive() is incorrect for timers while they are firing
diff --git a/Source/WTF/wtf/text/StringConcatenate.h b/Source/WTF/wtf/text/StringConcatenate.h
index 37c2850..26902e0 100644
--- a/Source/WTF/wtf/text/StringConcatenate.h
+++ b/Source/WTF/wtf/text/StringConcatenate.h
@@ -197,6 +197,44 @@
}
};
+template<typename... StringTypes> class StringTypeAdapter<std::tuple<StringTypes...>, void> {
+public:
+ StringTypeAdapter(std::tuple<StringTypes...> tuple)
+ : m_tuple { tuple }
+ , m_length { std::apply(computeLength, tuple) }
+ , m_is8Bit { std::apply(computeIs8Bit, tuple) }
+ {
+ }
+
+ unsigned length() const { return m_length; }
+ bool is8Bit() const { return m_is8Bit; }
+ template<typename CharacterType> void writeTo(CharacterType* destination) const
+ {
+ std::apply([&](StringTypes... strings) {
+ unsigned offset = 0;
+ (..., (
+ StringTypeAdapter<StringTypes>(strings).writeTo(destination + (offset * sizeof(CharacterType))),
+ offset += StringTypeAdapter<StringTypes>(strings).length()
+ ));
+ }, m_tuple);
+ }
+
+private:
+ static unsigned computeLength(StringTypes... strings)
+ {
+ return (... + StringTypeAdapter<StringTypes>(strings).length());
+ }
+
+ static bool computeIs8Bit(StringTypes... strings)
+ {
+ return (... && StringTypeAdapter<StringTypes>(strings).is8Bit());
+ }
+
+ std::tuple<StringTypes...> m_tuple;
+ unsigned m_length;
+ bool m_is8Bit;
+};
+
template<typename UnderlyingElementType> struct PaddingSpecification {
LChar character;
unsigned length;
diff --git a/Source/WebCore/ChangeLog b/Source/WebCore/ChangeLog
index e960e5a..0baa142 100644
--- a/Source/WebCore/ChangeLog
+++ b/Source/WebCore/ChangeLog
@@ -1,3 +1,27 @@
+2020-07-01 Alexey Shvayka <shvaikalesh@gmail.com>
+
+ Use more efficient makeString() instead of StringBuilder
+ https://bugs.webkit.org/show_bug.cgi?id=213708
+
+ Reviewed by Sam Weinig.
+
+ This patch refactors throwRequiredMemberTypeError() and throwArgument*Error()
+ methods, replacing all StringBuilder usages with more efficient makeString().
+
+ Extracts makeArgumentTypeErrorMessage(), similiar to existing helpers,
+ which can be reused if neccessary.
+
+ No new tests, no behavior change.
+
+ * bindings/js/JSDOMExceptionHandling.cpp:
+ (WebCore::makeArgumentTypeErrorMessage):
+ (WebCore::throwArgumentMustBeEnumError):
+ (WebCore::throwArgumentMustBeFunctionError):
+ (WebCore::throwArgumentMustBeObjectError):
+ (WebCore::throwArgumentTypeError):
+ (WebCore::throwRequiredMemberTypeError):
+ (WebCore::appendArgumentMustBe): Deleted.
+
2020-06-29 Sergio Villar Senin <svillar@igalia.com>
[css-flexbox] Don't include scrollbar extents when computing sizes for percentage resolution
diff --git a/Source/WebCore/bindings/js/JSDOMExceptionHandling.cpp b/Source/WebCore/bindings/js/JSDOMExceptionHandling.cpp
index c240890..2392966 100644
--- a/Source/WebCore/bindings/js/JSDOMExceptionHandling.cpp
+++ b/Source/WebCore/bindings/js/JSDOMExceptionHandling.cpp
@@ -34,7 +34,6 @@
#include <JavaScriptCore/ExceptionHelpers.h>
#include <JavaScriptCore/ScriptCallStack.h>
#include <JavaScriptCore/ScriptCallStackFactory.h>
-#include <wtf/text/StringBuilder.h>
namespace WebCore {
using namespace JSC;
@@ -168,14 +167,13 @@
return throwVMTypeError(&lexicalGlobalObject, scope, errorMessage);
}
-static void appendArgumentMustBe(StringBuilder& builder, unsigned argumentIndex, const char* argumentName, const char* interfaceName, const char* functionName)
+template<typename... StringTypes> static String makeArgumentTypeErrorMessage(unsigned argumentIndex, const char* argumentName, const char* interfaceName, const char* functionName, StringTypes ...strings)
{
- builder.append("Argument ", argumentIndex + 1, " ('", argumentName, "') to ");
- if (!functionName)
- builder.append("the ", interfaceName, " constructor");
- else
- builder.append(interfaceName, '.', functionName);
- builder.appendLiteral(" must be ");
+ return makeString(
+ "Argument ", argumentIndex + 1, " ('", argumentName, "') to ",
+ functionName ? std::make_tuple(interfaceName, ".", functionName) : std::make_tuple("the ", interfaceName, " constructor"),
+ " must be ", strings...
+ );
}
void throwNotSupportedError(JSC::JSGlobalObject& lexicalGlobalObject, JSC::ThrowScope& scope, ASCIILiteral message)
@@ -198,34 +196,22 @@
JSC::EncodedJSValue throwArgumentMustBeEnumError(JSC::JSGlobalObject& lexicalGlobalObject, JSC::ThrowScope& scope, unsigned argumentIndex, const char* argumentName, const char* functionInterfaceName, const char* functionName, const char* expectedValues)
{
- StringBuilder builder;
- appendArgumentMustBe(builder, argumentIndex, argumentName, functionInterfaceName, functionName);
- builder.append("one of: ", expectedValues);
- return throwVMTypeError(&lexicalGlobalObject, scope, builder.toString());
+ return throwVMTypeError(&lexicalGlobalObject, scope, makeArgumentTypeErrorMessage(argumentIndex, argumentName, functionInterfaceName, functionName, "one of: ", expectedValues));
}
JSC::EncodedJSValue throwArgumentMustBeFunctionError(JSC::JSGlobalObject& lexicalGlobalObject, JSC::ThrowScope& scope, unsigned argumentIndex, const char* argumentName, const char* interfaceName, const char* functionName)
{
- StringBuilder builder;
- appendArgumentMustBe(builder, argumentIndex, argumentName, interfaceName, functionName);
- builder.appendLiteral("a function");
- return throwVMTypeError(&lexicalGlobalObject, scope, builder.toString());
+ return throwVMTypeError(&lexicalGlobalObject, scope, makeArgumentTypeErrorMessage(argumentIndex, argumentName, interfaceName, functionName, "a function"));
}
JSC::EncodedJSValue throwArgumentMustBeObjectError(JSC::JSGlobalObject& lexicalGlobalObject, JSC::ThrowScope& scope, unsigned argumentIndex, const char* argumentName, const char* interfaceName, const char* functionName)
{
- StringBuilder builder;
- appendArgumentMustBe(builder, argumentIndex, argumentName, interfaceName, functionName);
- builder.appendLiteral("an object");
- return throwVMTypeError(&lexicalGlobalObject, scope, builder.toString());
+ return throwVMTypeError(&lexicalGlobalObject, scope, makeArgumentTypeErrorMessage(argumentIndex, argumentName, interfaceName, functionName, "an object"));
}
JSC::EncodedJSValue throwArgumentTypeError(JSC::JSGlobalObject& lexicalGlobalObject, JSC::ThrowScope& scope, unsigned argumentIndex, const char* argumentName, const char* functionInterfaceName, const char* functionName, const char* expectedType)
{
- StringBuilder builder;
- appendArgumentMustBe(builder, argumentIndex, argumentName, functionInterfaceName, functionName);
- builder.append("an instance of ", expectedType);
- return throwVMTypeError(&lexicalGlobalObject, scope, builder.toString());
+ return throwVMTypeError(&lexicalGlobalObject, scope, makeArgumentTypeErrorMessage(argumentIndex, argumentName, functionInterfaceName, functionName, "an instance of ", expectedType));
}
void throwAttributeTypeError(JSC::JSGlobalObject& lexicalGlobalObject, JSC::ThrowScope& scope, const char* interfaceName, const char* attributeName, const char* expectedType)
@@ -235,14 +221,7 @@
JSC::EncodedJSValue throwRequiredMemberTypeError(JSC::JSGlobalObject& lexicalGlobalObject, JSC::ThrowScope& scope, const char* memberName, const char* dictionaryName, const char* expectedType)
{
- StringBuilder builder;
- builder.appendLiteral("Member ");
- builder.append(dictionaryName);
- builder.append('.');
- builder.append(memberName);
- builder.appendLiteral(" is required and must be an instance of ");
- builder.append(expectedType);
- return throwVMTypeError(&lexicalGlobalObject, scope, builder.toString());
+ return throwVMTypeError(&lexicalGlobalObject, scope, makeString("Member ", dictionaryName, '.', memberName, " is required and must be an instance of ", expectedType));
}
JSC::EncodedJSValue throwConstructorScriptExecutionContextUnavailableError(JSC::JSGlobalObject& lexicalGlobalObject, JSC::ThrowScope& scope, const char* interfaceName)