[SCM] WebKit Debian packaging branch, webkit-1.2, updated. upstream/1.1.90-6072-g9a69373

barraclough at apple.com barraclough at apple.com
Thu Apr 8 00:33:29 UTC 2010


The following commit has been merged in the webkit-1.2 branch:
commit e82d3905fbde2787c0dde9d88766fd347b2c326e
Author: barraclough at apple.com <barraclough at apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Date:   Fri Dec 11 23:34:10 2009 +0000

    https://bugs.webkit.org/show_bug.cgi?id=32454
    Refactor construction of simple strings to avoid string concatenation.
    
    Reviewed by Oliver Hunt.
    
    Building strings through concatenation has a memory and performance cost -
    a memory cost since we must over-allocate the buffer to leave space to append
    into, and performance in that the string may still require reallocation (and
    thus copying during construction).  Instead move the full construction to
    within a single function call (makeString), so that the arguments' lengths
    can be calculated and an appropriate sized buffer allocated before copying
    any characters.
    
    ~No performance change (~2% progression on date tests).
    
    * bytecode/CodeBlock.cpp:
    (JSC::escapeQuotes):
    (JSC::valueToSourceString):
    (JSC::constantName):
    (JSC::idName):
    (JSC::CodeBlock::registerName):
    (JSC::regexpToSourceString):
    (JSC::regexpName):
    * bytecompiler/NodesCodegen.cpp:
    (JSC::substitute):
    * profiler/Profiler.cpp:
    (JSC::Profiler::createCallIdentifier):
    * runtime/DateConstructor.cpp:
    (JSC::callDate):
    * runtime/DateConversion.cpp:
    (JSC::formatDate):
    (JSC::formatDateUTCVariant):
    (JSC::formatTime):
    (JSC::formatTimeUTC):
    * runtime/DateConversion.h:
    (JSC::):
    * runtime/DatePrototype.cpp:
    (JSC::dateProtoFuncToString):
    (JSC::dateProtoFuncToUTCString):
    (JSC::dateProtoFuncToDateString):
    (JSC::dateProtoFuncToTimeString):
    (JSC::dateProtoFuncToGMTString):
    * runtime/ErrorPrototype.cpp:
    (JSC::errorProtoFuncToString):
    * runtime/ExceptionHelpers.cpp:
    (JSC::createUndefinedVariableError):
    (JSC::createErrorMessage):
    (JSC::createInvalidParamError):
    * runtime/FunctionPrototype.cpp:
    (JSC::insertSemicolonIfNeeded):
    (JSC::functionProtoFuncToString):
    * runtime/ObjectPrototype.cpp:
    (JSC::objectProtoFuncToString):
    * runtime/RegExpConstructor.cpp:
    (JSC::constructRegExp):
    * runtime/RegExpObject.cpp:
    (JSC::RegExpObject::match):
    * runtime/RegExpPrototype.cpp:
    (JSC::regExpProtoFuncCompile):
    (JSC::regExpProtoFuncToString):
    * runtime/StringPrototype.cpp:
    (JSC::stringProtoFuncBig):
    (JSC::stringProtoFuncSmall):
    (JSC::stringProtoFuncBlink):
    (JSC::stringProtoFuncBold):
    (JSC::stringProtoFuncFixed):
    (JSC::stringProtoFuncItalics):
    (JSC::stringProtoFuncStrike):
    (JSC::stringProtoFuncSub):
    (JSC::stringProtoFuncSup):
    (JSC::stringProtoFuncFontcolor):
    (JSC::stringProtoFuncFontsize):
    (JSC::stringProtoFuncAnchor):
    * runtime/UString.h:
    (JSC::):
    (JSC::makeString):
    
    
    
    git-svn-id: http://svn.webkit.org/repository/webkit/trunk@52028 268f45cc-cd09-0410-ab3c-d52691b4dbfc

diff --git a/JavaScriptCore/ChangeLog b/JavaScriptCore/ChangeLog
index 9654157..1bdc94e 100644
--- a/JavaScriptCore/ChangeLog
+++ b/JavaScriptCore/ChangeLog
@@ -1,3 +1,82 @@
+2009-12-11  Gavin Barraclough  <barraclough at apple.com>
+
+        Reviewed by Oliver Hunt.
+
+        https://bugs.webkit.org/show_bug.cgi?id=32454
+        Refactor construction of simple strings to avoid string concatenation.
+
+        Building strings through concatenation has a memory and performance cost -
+        a memory cost since we must over-allocate the buffer to leave space to append
+        into, and performance in that the string may still require reallocation (and
+        thus copying during construction).  Instead move the full construction to
+        within a single function call (makeString), so that the arguments' lengths
+        can be calculated and an appropriate sized buffer allocated before copying
+        any characters.
+
+        ~No performance change (~2% progression on date tests).
+
+        * bytecode/CodeBlock.cpp:
+        (JSC::escapeQuotes):
+        (JSC::valueToSourceString):
+        (JSC::constantName):
+        (JSC::idName):
+        (JSC::CodeBlock::registerName):
+        (JSC::regexpToSourceString):
+        (JSC::regexpName):
+        * bytecompiler/NodesCodegen.cpp:
+        (JSC::substitute):
+        * profiler/Profiler.cpp:
+        (JSC::Profiler::createCallIdentifier):
+        * runtime/DateConstructor.cpp:
+        (JSC::callDate):
+        * runtime/DateConversion.cpp:
+        (JSC::formatDate):
+        (JSC::formatDateUTCVariant):
+        (JSC::formatTime):
+        (JSC::formatTimeUTC):
+        * runtime/DateConversion.h:
+        (JSC::):
+        * runtime/DatePrototype.cpp:
+        (JSC::dateProtoFuncToString):
+        (JSC::dateProtoFuncToUTCString):
+        (JSC::dateProtoFuncToDateString):
+        (JSC::dateProtoFuncToTimeString):
+        (JSC::dateProtoFuncToGMTString):
+        * runtime/ErrorPrototype.cpp:
+        (JSC::errorProtoFuncToString):
+        * runtime/ExceptionHelpers.cpp:
+        (JSC::createUndefinedVariableError):
+        (JSC::createErrorMessage):
+        (JSC::createInvalidParamError):
+        * runtime/FunctionPrototype.cpp:
+        (JSC::insertSemicolonIfNeeded):
+        (JSC::functionProtoFuncToString):
+        * runtime/ObjectPrototype.cpp:
+        (JSC::objectProtoFuncToString):
+        * runtime/RegExpConstructor.cpp:
+        (JSC::constructRegExp):
+        * runtime/RegExpObject.cpp:
+        (JSC::RegExpObject::match):
+        * runtime/RegExpPrototype.cpp:
+        (JSC::regExpProtoFuncCompile):
+        (JSC::regExpProtoFuncToString):
+        * runtime/StringPrototype.cpp:
+        (JSC::stringProtoFuncBig):
+        (JSC::stringProtoFuncSmall):
+        (JSC::stringProtoFuncBlink):
+        (JSC::stringProtoFuncBold):
+        (JSC::stringProtoFuncFixed):
+        (JSC::stringProtoFuncItalics):
+        (JSC::stringProtoFuncStrike):
+        (JSC::stringProtoFuncSub):
+        (JSC::stringProtoFuncSup):
+        (JSC::stringProtoFuncFontcolor):
+        (JSC::stringProtoFuncFontsize):
+        (JSC::stringProtoFuncAnchor):
+        * runtime/UString.h:
+        (JSC::):
+        (JSC::makeString):
+
 2009-12-10  Gavin Barraclough  <barraclough at apple.com>
 
         Reviewed by Oliver Hunt.
diff --git a/JavaScriptCore/bytecode/CodeBlock.cpp b/JavaScriptCore/bytecode/CodeBlock.cpp
index 13bed8c..fd56ece 100644
--- a/JavaScriptCore/bytecode/CodeBlock.cpp
+++ b/JavaScriptCore/bytecode/CodeBlock.cpp
@@ -51,7 +51,7 @@ static UString escapeQuotes(const UString& str)
     UString result = str;
     int pos = 0;
     while ((pos = result.find('\"', pos)) >= 0) {
-        result = result.substr(0, pos) + "\"\\\"\"" + result.substr(pos + 1);
+        result = makeString(result.substr(0, pos), "\"\\\"\"", result.substr(pos + 1));
         pos += 4;
     }
     return result;
@@ -62,23 +62,20 @@ static UString valueToSourceString(ExecState* exec, JSValue val)
     if (!val)
         return "0";
 
-    if (val.isString()) {
-        UString result("\"");
-        result += escapeQuotes(val.toString(exec)) + "\"";
-        return result;
-    } 
+    if (val.isString())
+        return makeString("\"", escapeQuotes(val.toString(exec)), "\"");
 
     return val.toString(exec);
 }
 
 static CString constantName(ExecState* exec, int k, JSValue value)
 {
-    return (valueToSourceString(exec, value) + "(@k" + UString::from(k - FirstConstantRegisterIndex) + ")").UTF8String();
+    return makeString(valueToSourceString(exec, value), "(@k", UString::from(k - FirstConstantRegisterIndex), ")").UTF8String();
 }
 
 static CString idName(int id0, const Identifier& ident)
 {
-    return (ident.ustring() + "(@id" + UString::from(id0) +")").UTF8String();
+    return makeString(ident.ustring(), "(@id", UString::from(id0), ")").UTF8String();
 }
 
 CString CodeBlock::registerName(ExecState* exec, int r) const
@@ -89,25 +86,26 @@ CString CodeBlock::registerName(ExecState* exec, int r) const
     if (isConstantRegisterIndex(r))
         return constantName(exec, r, getConstant(r));
 
-    return (UString("r") + UString::from(r)).UTF8String();
+    return makeString("r", UString::from(r)).UTF8String();
 }
 
 static UString regexpToSourceString(RegExp* regExp)
 {
-    UString pattern = UString("/") + regExp->pattern() + "/";
+    char postfix[5] = { '/', 0, 0, 0, 0 };
+    int index = 1;
     if (regExp->global())
-        pattern += "g";
+        postfix[index++] = 'g';
     if (regExp->ignoreCase())
-        pattern += "i";
+        postfix[index++] = 'i';
     if (regExp->multiline())
-        pattern += "m";
+        postfix[index] = 'm';
 
-    return pattern;
+    return makeString("/", regExp->pattern(), postfix);
 }
 
 static CString regexpName(int re, RegExp* regexp)
 {
-    return (regexpToSourceString(regexp) + "(@re" + UString::from(re) + ")").UTF8String();
+    return makeString(regexpToSourceString(regexp), "(@re", UString::from(re), ")").UTF8String();
 }
 
 static UString pointerToSourceString(void* p)
diff --git a/JavaScriptCore/bytecompiler/NodesCodegen.cpp b/JavaScriptCore/bytecompiler/NodesCodegen.cpp
index 80a7a2f..b66c50d 100644
--- a/JavaScriptCore/bytecompiler/NodesCodegen.cpp
+++ b/JavaScriptCore/bytecompiler/NodesCodegen.cpp
@@ -78,10 +78,7 @@ static void substitute(UString& string, const UString& substring)
 {
     int position = string.find("%s");
     ASSERT(position != -1);
-    UString newString = string.substr(0, position);
-    newString.append(substring);
-    newString.append(string.substr(position + 2));
-    string = newString;
+    string = makeString(string.substr(0, position), substring, string.substr(position + 2));
 }
 
 RegisterID* ThrowableExpressionData::emitThrowError(BytecodeGenerator& generator, ErrorType type, const char* message)
diff --git a/JavaScriptCore/profiler/Profiler.cpp b/JavaScriptCore/profiler/Profiler.cpp
index 5585d2e..fe8727a 100644
--- a/JavaScriptCore/profiler/Profiler.cpp
+++ b/JavaScriptCore/profiler/Profiler.cpp
@@ -148,7 +148,7 @@ CallIdentifier Profiler::createCallIdentifier(ExecState* exec, JSValue functionV
     }
     if (asObject(functionValue)->inherits(&InternalFunction::info))
         return CallIdentifier(static_cast<InternalFunction*>(asObject(functionValue))->name(exec), defaultSourceURL, defaultLineNumber);
-    return CallIdentifier("(" + asObject(functionValue)->className() + " object)", defaultSourceURL, defaultLineNumber);
+    return CallIdentifier(makeString("(", asObject(functionValue)->className(), " object)"), defaultSourceURL, defaultLineNumber);
 }
 
 CallIdentifier createCallIdentifierFromFunctionImp(ExecState* exec, JSFunction* function)
diff --git a/JavaScriptCore/runtime/DateConstructor.cpp b/JavaScriptCore/runtime/DateConstructor.cpp
index 61ec4c5..e25765b 100644
--- a/JavaScriptCore/runtime/DateConstructor.cpp
+++ b/JavaScriptCore/runtime/DateConstructor.cpp
@@ -133,7 +133,11 @@ static JSValue JSC_HOST_CALL callDate(ExecState* exec, JSObject*, JSValue, const
     tm localTM;
     getLocalTime(&localTime, &localTM);
     GregorianDateTime ts(exec, localTM);
-    return jsNontrivialString(exec, formatDate(ts) + " " + formatTime(ts));
+    DateConversionBuffer date;
+    DateConversionBuffer time;
+    formatDate(ts, date);
+    formatTime(ts, time);
+    return jsNontrivialString(exec, makeString(date, " ", time));
 }
 
 CallType DateConstructor::getCallData(CallData& callData)
diff --git a/JavaScriptCore/runtime/DateConversion.cpp b/JavaScriptCore/runtime/DateConversion.cpp
index b9d0e02..f129407 100644
--- a/JavaScriptCore/runtime/DateConversion.cpp
+++ b/JavaScriptCore/runtime/DateConversion.cpp
@@ -62,49 +62,41 @@ double parseDate(ExecState* exec, const UString &date)
     return value;
 }
 
-UString formatDate(const GregorianDateTime &t)
+void formatDate(const GregorianDateTime &t, DateConversionBuffer& buffer)
 {
-    char buffer[100];
-    snprintf(buffer, sizeof(buffer), "%s %s %02d %04d",
+    snprintf(buffer, DateConversionBufferSize, "%s %s %02d %04d",
         weekdayName[(t.weekDay + 6) % 7],
         monthName[t.month], t.monthDay, t.year + 1900);
-    return buffer;
 }
 
-UString formatDateUTCVariant(const GregorianDateTime &t)
+void formatDateUTCVariant(const GregorianDateTime &t, DateConversionBuffer& buffer)
 {
-    char buffer[100];
-    snprintf(buffer, sizeof(buffer), "%s, %02d %s %04d",
+    snprintf(buffer, DateConversionBufferSize, "%s, %02d %s %04d",
         weekdayName[(t.weekDay + 6) % 7],
         t.monthDay, monthName[t.month], t.year + 1900);
-    return buffer;
 }
 
-UString formatTime(const GregorianDateTime &t)
+void formatTime(const GregorianDateTime &t, DateConversionBuffer& buffer)
 {
-    char buffer[100];
     int offset = abs(gmtoffset(t));
     char timeZoneName[70];
     struct tm gtm = t;
     strftime(timeZoneName, sizeof(timeZoneName), "%Z", &gtm);
 
     if (timeZoneName[0]) {
-        snprintf(buffer, sizeof(buffer), "%02d:%02d:%02d GMT%c%02d%02d (%s)",
+        snprintf(buffer, DateConversionBufferSize, "%02d:%02d:%02d GMT%c%02d%02d (%s)",
             t.hour, t.minute, t.second,
             gmtoffset(t) < 0 ? '-' : '+', offset / (60*60), (offset / 60) % 60, timeZoneName);
     } else {
-        snprintf(buffer, sizeof(buffer), "%02d:%02d:%02d GMT%c%02d%02d",
+        snprintf(buffer, DateConversionBufferSize, "%02d:%02d:%02d GMT%c%02d%02d",
             t.hour, t.minute, t.second,
             gmtoffset(t) < 0 ? '-' : '+', offset / (60*60), (offset / 60) % 60);
     }
-    return UString(buffer);
 }
 
-UString formatTimeUTC(const GregorianDateTime &t)
+void formatTimeUTC(const GregorianDateTime &t, DateConversionBuffer& buffer)
 {
-    char buffer[100];
-    snprintf(buffer, sizeof(buffer), "%02d:%02d:%02d GMT", t.hour, t.minute, t.second);
-    return UString(buffer);
+    snprintf(buffer, DateConversionBufferSize, "%02d:%02d:%02d GMT", t.hour, t.minute, t.second);
 }
 
 } // namespace JSC
diff --git a/JavaScriptCore/runtime/DateConversion.h b/JavaScriptCore/runtime/DateConversion.h
index dc980d3..ff32b50 100644
--- a/JavaScriptCore/runtime/DateConversion.h
+++ b/JavaScriptCore/runtime/DateConversion.h
@@ -42,17 +42,21 @@
 #ifndef DateConversion_h
 #define DateConversion_h
 
+#include "UString.h"
+
 namespace JSC {
 
 class ExecState;
-class UString;
 struct GregorianDateTime;
 
+static const unsigned DateConversionBufferSize = 100;
+typedef char DateConversionBuffer[DateConversionBufferSize];
+
 double parseDate(ExecState* exec, const UString&);
-UString formatDate(const GregorianDateTime&);
-UString formatDateUTCVariant(const GregorianDateTime&);
-UString formatTime(const GregorianDateTime&);
-UString formatTimeUTC(const GregorianDateTime&);
+void formatDate(const GregorianDateTime&, DateConversionBuffer&);
+void formatDateUTCVariant(const GregorianDateTime&, DateConversionBuffer&);
+void formatTime(const GregorianDateTime&, DateConversionBuffer&);
+void formatTimeUTC(const GregorianDateTime&, DateConversionBuffer&);
 
 } // namespace JSC
 
diff --git a/JavaScriptCore/runtime/DatePrototype.cpp b/JavaScriptCore/runtime/DatePrototype.cpp
index 7a2e802..2b5e0d0 100644
--- a/JavaScriptCore/runtime/DatePrototype.cpp
+++ b/JavaScriptCore/runtime/DatePrototype.cpp
@@ -423,7 +423,11 @@ JSValue JSC_HOST_CALL dateProtoFuncToString(ExecState* exec, JSObject*, JSValue
     const GregorianDateTime* gregorianDateTime = thisDateObj->gregorianDateTime(exec);
     if (!gregorianDateTime)
         return jsNontrivialString(exec, "Invalid Date");
-    return jsNontrivialString(exec, formatDate(*gregorianDateTime) + " " + formatTime(*gregorianDateTime));
+    DateConversionBuffer date;
+    DateConversionBuffer time;
+    formatDate(*gregorianDateTime, date);
+    formatTime(*gregorianDateTime, time);
+    return jsNontrivialString(exec, makeString(date, " ", time));
 }
 
 JSValue JSC_HOST_CALL dateProtoFuncToUTCString(ExecState* exec, JSObject*, JSValue thisValue, const ArgList&)
@@ -436,7 +440,11 @@ JSValue JSC_HOST_CALL dateProtoFuncToUTCString(ExecState* exec, JSObject*, JSVal
     const GregorianDateTime* gregorianDateTime = thisDateObj->gregorianDateTimeUTC(exec);
     if (!gregorianDateTime)
         return jsNontrivialString(exec, "Invalid Date");
-    return jsNontrivialString(exec, formatDateUTCVariant(*gregorianDateTime) + " " + formatTimeUTC(*gregorianDateTime));
+    DateConversionBuffer date;
+    DateConversionBuffer time;
+    formatDateUTCVariant(*gregorianDateTime, date);
+    formatTimeUTC(*gregorianDateTime, time);
+    return jsNontrivialString(exec, makeString(date, " ", time));
 }
 
 JSValue JSC_HOST_CALL dateProtoFuncToISOString(ExecState* exec, JSObject*, JSValue thisValue, const ArgList&)
@@ -467,7 +475,9 @@ JSValue JSC_HOST_CALL dateProtoFuncToDateString(ExecState* exec, JSObject*, JSVa
     const GregorianDateTime* gregorianDateTime = thisDateObj->gregorianDateTime(exec);
     if (!gregorianDateTime)
         return jsNontrivialString(exec, "Invalid Date");
-    return jsNontrivialString(exec, formatDate(*gregorianDateTime));
+    DateConversionBuffer date;
+    formatDate(*gregorianDateTime, date);
+    return jsNontrivialString(exec, date);
 }
 
 JSValue JSC_HOST_CALL dateProtoFuncToTimeString(ExecState* exec, JSObject*, JSValue thisValue, const ArgList&)
@@ -480,7 +490,9 @@ JSValue JSC_HOST_CALL dateProtoFuncToTimeString(ExecState* exec, JSObject*, JSVa
     const GregorianDateTime* gregorianDateTime = thisDateObj->gregorianDateTime(exec);
     if (!gregorianDateTime)
         return jsNontrivialString(exec, "Invalid Date");
-    return jsNontrivialString(exec, formatTime(*gregorianDateTime));
+    DateConversionBuffer time;
+    formatTime(*gregorianDateTime, time);
+    return jsNontrivialString(exec, time);
 }
 
 JSValue JSC_HOST_CALL dateProtoFuncToLocaleString(ExecState* exec, JSObject*, JSValue thisValue, const ArgList& args)
@@ -554,7 +566,11 @@ JSValue JSC_HOST_CALL dateProtoFuncToGMTString(ExecState* exec, JSObject*, JSVal
     const GregorianDateTime* gregorianDateTime = thisDateObj->gregorianDateTimeUTC(exec);
     if (!gregorianDateTime)
         return jsNontrivialString(exec, "Invalid Date");
-    return jsNontrivialString(exec, formatDateUTCVariant(*gregorianDateTime) + " " + formatTimeUTC(*gregorianDateTime));
+    DateConversionBuffer date;
+    DateConversionBuffer time;
+    formatDateUTCVariant(*gregorianDateTime, date);
+    formatTimeUTC(*gregorianDateTime, time);
+    return jsNontrivialString(exec, makeString(date, " ", time));
 }
 
 JSValue JSC_HOST_CALL dateProtoFuncGetMonth(ExecState* exec, JSObject*, JSValue thisValue, const ArgList&)
diff --git a/JavaScriptCore/runtime/ErrorPrototype.cpp b/JavaScriptCore/runtime/ErrorPrototype.cpp
index a9a7a43..be9e4b8 100644
--- a/JavaScriptCore/runtime/ErrorPrototype.cpp
+++ b/JavaScriptCore/runtime/ErrorPrototype.cpp
@@ -48,21 +48,19 @@ ErrorPrototype::ErrorPrototype(ExecState* exec, NonNullPassRefPtr<Structure> str
 JSValue JSC_HOST_CALL errorProtoFuncToString(ExecState* exec, JSObject*, JSValue thisValue, const ArgList&)
 {
     JSObject* thisObj = thisValue.toThisObject(exec);
+    JSValue name = thisObj->get(exec, exec->propertyNames().name);
+    JSValue message = thisObj->get(exec, exec->propertyNames().message);
 
-    UString s = "Error";
+    // Mozilla-compatible format.
 
-    JSValue v = thisObj->get(exec, exec->propertyNames().name);
-    if (!v.isUndefined())
-        s = v.toString(exec);
-
-    v = thisObj->get(exec, exec->propertyNames().message);
-    if (!v.isUndefined()) {
-        // Mozilla-compatible format.
-        s += ": ";
-        s += v.toString(exec);
+    if (!name.isUndefined()) {
+        if (!message.isUndefined())
+            return jsNontrivialString(exec, makeString(name.toString(exec), ": ", message.toString(exec)));
+        return jsNontrivialString(exec, name.toString(exec));
     }
-
-    return jsNontrivialString(exec, s);
+    if (!message.isUndefined())
+        return jsNontrivialString(exec, makeString("Error: ", message.toString(exec)));
+    return jsNontrivialString(exec, "Error");
 }
 
 } // namespace JSC
diff --git a/JavaScriptCore/runtime/ExceptionHelpers.cpp b/JavaScriptCore/runtime/ExceptionHelpers.cpp
index 5bead90..9bb740e 100644
--- a/JavaScriptCore/runtime/ExceptionHelpers.cpp
+++ b/JavaScriptCore/runtime/ExceptionHelpers.cpp
@@ -77,9 +77,7 @@ JSValue createUndefinedVariableError(ExecState* exec, const Identifier& ident, u
     int endOffset = 0;
     int divotPoint = 0;
     int line = codeBlock->expressionRangeForBytecodeOffset(exec, bytecodeOffset, divotPoint, startOffset, endOffset);
-    UString message = "Can't find variable: ";
-    message.append(ident.ustring());
-    JSObject* exception = Error::create(exec, ReferenceError, message, line, codeBlock->ownerExecutable()->sourceID(), codeBlock->ownerExecutable()->sourceURL());
+    JSObject* exception = Error::create(exec, ReferenceError, makeString("Can't find variable: ", ident.ustring()), line, codeBlock->ownerExecutable()->sourceID(), codeBlock->ownerExecutable()->sourceURL());
     exception->putWithAttributes(exec, Identifier(exec, expressionBeginOffsetPropertyName), jsNumber(exec, divotPoint - startOffset), ReadOnly | DontDelete);
     exception->putWithAttributes(exec, Identifier(exec, expressionCaretOffsetPropertyName), jsNumber(exec, divotPoint), ReadOnly | DontDelete);
     exception->putWithAttributes(exec, Identifier(exec, expressionEndOffsetPropertyName), jsNumber(exec, divotPoint + endOffset), ReadOnly | DontDelete);
@@ -88,59 +86,36 @@ JSValue createUndefinedVariableError(ExecState* exec, const Identifier& ident, u
     
 static UString createErrorMessage(ExecState* exec, CodeBlock* codeBlock, int, int expressionStart, int expressionStop, JSValue value, UString error)
 {
-    if (!expressionStop || expressionStart > codeBlock->source()->length()) {
-        UString errorText = value.toString(exec);
-        errorText.append(" is ");
-        errorText.append(error);
-        return errorText;
-    }
+    if (!expressionStop || expressionStart > codeBlock->source()->length())
+        return makeString(value.toString(exec), " is ", error);
+    if (expressionStart < expressionStop)
+        return makeString("Result of expression '", codeBlock->source()->getRange(expressionStart, expressionStop), "' [", value.toString(exec), "] is ", error, ".");
 
-    UString errorText = "Result of expression ";
-    
-    if (expressionStart < expressionStop) {
-        errorText.append('\'');
-        errorText.append(codeBlock->source()->getRange(expressionStart, expressionStop));
-        errorText.append("' [");
-        errorText.append(value.toString(exec));
-        errorText.append("] is ");
-    } else {
-        // No range information, so give a few characters of context
-        const UChar* data = codeBlock->source()->data();
-        int dataLength = codeBlock->source()->length();
-        int start = expressionStart;
-        int stop = expressionStart;
-        // Get up to 20 characters of context to the left and right of the divot, clamping to the line.
-        // then strip whitespace.
-        while (start > 0 && (expressionStart - start < 20) && data[start - 1] != '\n')
-            start--;
-        while (start < (expressionStart - 1) && isStrWhiteSpace(data[start]))
-            start++;
-        while (stop < dataLength && (stop - expressionStart < 20) && data[stop] != '\n')
-            stop++;
-        while (stop > expressionStart && isStrWhiteSpace(data[stop]))
-            stop--;
-        errorText.append("near '...");
-        errorText.append(codeBlock->source()->getRange(start, stop));
-        errorText.append("...' [");
-        errorText.append(value.toString(exec));
-        errorText.append("] is ");
-    }
-    errorText.append(error);
-    errorText.append(".");
-    return errorText;
+    // No range information, so give a few characters of context
+    const UChar* data = codeBlock->source()->data();
+    int dataLength = codeBlock->source()->length();
+    int start = expressionStart;
+    int stop = expressionStart;
+    // Get up to 20 characters of context to the left and right of the divot, clamping to the line.
+    // then strip whitespace.
+    while (start > 0 && (expressionStart - start < 20) && data[start - 1] != '\n')
+        start--;
+    while (start < (expressionStart - 1) && isStrWhiteSpace(data[start]))
+        start++;
+    while (stop < dataLength && (stop - expressionStart < 20) && data[stop] != '\n')
+        stop++;
+    while (stop > expressionStart && isStrWhiteSpace(data[stop]))
+        stop--;
+    return makeString("Result of expression near '...", codeBlock->source()->getRange(start, stop), "...' [", value.toString(exec), "] is ", error, ".");
 }
 
 JSObject* createInvalidParamError(ExecState* exec, const char* op, JSValue value, unsigned bytecodeOffset, CodeBlock* codeBlock)
 {
-    UString message = "not a valid argument for '";
-    message.append(op);
-    message.append("'");
-    
     int startOffset = 0;
     int endOffset = 0;
     int divotPoint = 0;
     int line = codeBlock->expressionRangeForBytecodeOffset(exec, bytecodeOffset, divotPoint, startOffset, endOffset);
-    UString errorMessage = createErrorMessage(exec, codeBlock, line, divotPoint, divotPoint + endOffset, value, message);
+    UString errorMessage = createErrorMessage(exec, codeBlock, line, divotPoint, divotPoint + endOffset, value, makeString("not a valid argument for '", op, "'"));
     JSObject* exception = Error::create(exec, TypeError, errorMessage, line, codeBlock->ownerExecutable()->sourceID(), codeBlock->ownerExecutable()->sourceURL());
     exception->putWithAttributes(exec, Identifier(exec, expressionBeginOffsetPropertyName), jsNumber(exec, divotPoint - startOffset), ReadOnly | DontDelete);
     exception->putWithAttributes(exec, Identifier(exec, expressionCaretOffsetPropertyName), jsNumber(exec, divotPoint), ReadOnly | DontDelete);
diff --git a/JavaScriptCore/runtime/FunctionPrototype.cpp b/JavaScriptCore/runtime/FunctionPrototype.cpp
index a3a7479..f08bd5e 100644
--- a/JavaScriptCore/runtime/FunctionPrototype.cpp
+++ b/JavaScriptCore/runtime/FunctionPrototype.cpp
@@ -76,7 +76,7 @@ static inline void insertSemicolonIfNeeded(UString& functionBody)
         UChar ch = functionBody[i];
         if (!Lexer::isWhiteSpace(ch) && !Lexer::isLineTerminator(ch)) {
             if (ch != ';' && ch != '}')
-                functionBody = functionBody.substr(0, i + 1) + ";" + functionBody.substr(i + 1, functionBody.size() - (i + 1));
+                functionBody = makeString(functionBody.substr(0, i + 1), ";", functionBody.substr(i + 1, functionBody.size() - (i + 1)));
             return;
         }
     }
@@ -90,13 +90,13 @@ JSValue JSC_HOST_CALL functionProtoFuncToString(ExecState* exec, JSObject*, JSVa
             FunctionExecutable* executable = function->jsExecutable();
             UString sourceString = executable->source().toString();
             insertSemicolonIfNeeded(sourceString);
-            return jsString(exec, "function " + function->name(exec) + "(" + executable->paramString() + ") " + sourceString);
+            return jsString(exec, makeString("function ", function->name(exec), "(", executable->paramString(), ") ", sourceString));
         }
     }
 
     if (thisValue.inherits(&InternalFunction::info)) {
         InternalFunction* function = asInternalFunction(thisValue);
-        return jsString(exec, "function " + function->name(exec) + "() {\n    [native code]\n}");
+        return jsString(exec, makeString("function ", function->name(exec), "() {\n    [native code]\n}"));
     }
 
     return throwError(exec, TypeError);
diff --git a/JavaScriptCore/runtime/ObjectPrototype.cpp b/JavaScriptCore/runtime/ObjectPrototype.cpp
index 0970b7c..3065c6d 100644
--- a/JavaScriptCore/runtime/ObjectPrototype.cpp
+++ b/JavaScriptCore/runtime/ObjectPrototype.cpp
@@ -148,7 +148,7 @@ JSValue JSC_HOST_CALL objectProtoFuncToLocaleString(ExecState* exec, JSObject*,
 
 JSValue JSC_HOST_CALL objectProtoFuncToString(ExecState* exec, JSObject*, JSValue thisValue, const ArgList&)
 {
-    return jsNontrivialString(exec, "[object " + thisValue.toThisObject(exec)->className() + "]");
+    return jsNontrivialString(exec, makeString("[object ", thisValue.toThisObject(exec)->className(), "]"));
 }
 
 } // namespace JSC
diff --git a/JavaScriptCore/runtime/RegExpConstructor.cpp b/JavaScriptCore/runtime/RegExpConstructor.cpp
index e5c6909..6f00142 100644
--- a/JavaScriptCore/runtime/RegExpConstructor.cpp
+++ b/JavaScriptCore/runtime/RegExpConstructor.cpp
@@ -302,7 +302,7 @@ JSObject* constructRegExp(ExecState* exec, const ArgList& args)
 
     RefPtr<RegExp> regExp = RegExp::create(&exec->globalData(), pattern, flags);
     if (!regExp->isValid())
-        return throwError(exec, SyntaxError, UString("Invalid regular expression: ").append(regExp->errorMessage()));
+        return throwError(exec, SyntaxError, makeString("Invalid regular expression: ", regExp->errorMessage()));
     return new (exec) RegExpObject(exec->lexicalGlobalObject()->regExpStructure(), regExp.release());
 }
 
diff --git a/JavaScriptCore/runtime/RegExpObject.cpp b/JavaScriptCore/runtime/RegExpObject.cpp
index 679d072..42bfcef 100644
--- a/JavaScriptCore/runtime/RegExpObject.cpp
+++ b/JavaScriptCore/runtime/RegExpObject.cpp
@@ -142,7 +142,7 @@ bool RegExpObject::match(ExecState* exec, const ArgList& args)
 
     UString input = args.isEmpty() ? regExpConstructor->input() : args.at(0).toString(exec);
     if (input.isNull()) {
-        throwError(exec, GeneralError, "No input to " + toString(exec) + ".");
+        throwError(exec, GeneralError, makeString("No input to ", toString(exec), "."));
         return false;
     }
 
diff --git a/JavaScriptCore/runtime/RegExpPrototype.cpp b/JavaScriptCore/runtime/RegExpPrototype.cpp
index bbc9e85..c3ee565 100644
--- a/JavaScriptCore/runtime/RegExpPrototype.cpp
+++ b/JavaScriptCore/runtime/RegExpPrototype.cpp
@@ -91,7 +91,7 @@ JSValue JSC_HOST_CALL regExpProtoFuncCompile(ExecState* exec, JSObject*, JSValue
     }
 
     if (!regExp->isValid())
-        return throwError(exec, SyntaxError, UString("Invalid regular expression: ").append(regExp->errorMessage()));
+        return throwError(exec, SyntaxError, makeString("Invalid regular expression: ", regExp->errorMessage()));
 
     asRegExpObject(thisValue)->setRegExp(regExp.release());
     asRegExpObject(thisValue)->setLastIndex(0);
@@ -106,15 +106,16 @@ JSValue JSC_HOST_CALL regExpProtoFuncToString(ExecState* exec, JSObject*, JSValu
         return throwError(exec, TypeError);
     }
 
-    UString result = "/" + asRegExpObject(thisValue)->get(exec, exec->propertyNames().source).toString(exec);
-    result.append('/');
+    char postfix[5] = { '/', 0, 0, 0, 0 };
+    int index = 1;
     if (asRegExpObject(thisValue)->get(exec, exec->propertyNames().global).toBoolean(exec))
-        result.append('g');
+        postfix[index++] = 'g';
     if (asRegExpObject(thisValue)->get(exec, exec->propertyNames().ignoreCase).toBoolean(exec))
-        result.append('i');
+        postfix[index++] = 'i';
     if (asRegExpObject(thisValue)->get(exec, exec->propertyNames().multiline).toBoolean(exec))
-        result.append('m');
-    return jsNontrivialString(exec, result);
+        postfix[index] = 'm';
+    
+    return jsNontrivialString(exec, makeString("/", asRegExpObject(thisValue)->get(exec, exec->propertyNames().source).toString(exec), postfix));
 }
 
 } // namespace JSC
diff --git a/JavaScriptCore/runtime/StringPrototype.cpp b/JavaScriptCore/runtime/StringPrototype.cpp
index 32f9e6b..be5a671 100644
--- a/JavaScriptCore/runtime/StringPrototype.cpp
+++ b/JavaScriptCore/runtime/StringPrototype.cpp
@@ -775,62 +775,62 @@ JSValue JSC_HOST_CALL stringProtoFuncLocaleCompare(ExecState* exec, JSObject*, J
 JSValue JSC_HOST_CALL stringProtoFuncBig(ExecState* exec, JSObject*, JSValue thisValue, const ArgList&)
 {
     UString s = thisValue.toThisString(exec);
-    return jsNontrivialString(exec, "<big>" + s + "</big>");
+    return jsNontrivialString(exec, makeString("<big>", s, "</big>"));
 }
 
 JSValue JSC_HOST_CALL stringProtoFuncSmall(ExecState* exec, JSObject*, JSValue thisValue, const ArgList&)
 {
     UString s = thisValue.toThisString(exec);
-    return jsNontrivialString(exec, "<small>" + s + "</small>");
+    return jsNontrivialString(exec, makeString("<small>", s, "</small>"));
 }
 
 JSValue JSC_HOST_CALL stringProtoFuncBlink(ExecState* exec, JSObject*, JSValue thisValue, const ArgList&)
 {
     UString s = thisValue.toThisString(exec);
-    return jsNontrivialString(exec, "<blink>" + s + "</blink>");
+    return jsNontrivialString(exec, makeString("<blink>", s, "</blink>"));
 }
 
 JSValue JSC_HOST_CALL stringProtoFuncBold(ExecState* exec, JSObject*, JSValue thisValue, const ArgList&)
 {
     UString s = thisValue.toThisString(exec);
-    return jsNontrivialString(exec, "<b>" + s + "</b>");
+    return jsNontrivialString(exec, makeString("<b>", s, "</b>"));
 }
 
 JSValue JSC_HOST_CALL stringProtoFuncFixed(ExecState* exec, JSObject*, JSValue thisValue, const ArgList&)
 {
     UString s = thisValue.toThisString(exec);
-    return jsString(exec, "<tt>" + s + "</tt>");
+    return jsString(exec, makeString("<tt>", s, "</tt>"));
 }
 
 JSValue JSC_HOST_CALL stringProtoFuncItalics(ExecState* exec, JSObject*, JSValue thisValue, const ArgList&)
 {
     UString s = thisValue.toThisString(exec);
-    return jsNontrivialString(exec, "<i>" + s + "</i>");
+    return jsNontrivialString(exec, makeString("<i>", s, "</i>"));
 }
 
 JSValue JSC_HOST_CALL stringProtoFuncStrike(ExecState* exec, JSObject*, JSValue thisValue, const ArgList&)
 {
     UString s = thisValue.toThisString(exec);
-    return jsNontrivialString(exec, "<strike>" + s + "</strike>");
+    return jsNontrivialString(exec, makeString("<strike>", s, "</strike>"));
 }
 
 JSValue JSC_HOST_CALL stringProtoFuncSub(ExecState* exec, JSObject*, JSValue thisValue, const ArgList&)
 {
     UString s = thisValue.toThisString(exec);
-    return jsNontrivialString(exec, "<sub>" + s + "</sub>");
+    return jsNontrivialString(exec, makeString("<sub>", s, "</sub>"));
 }
 
 JSValue JSC_HOST_CALL stringProtoFuncSup(ExecState* exec, JSObject*, JSValue thisValue, const ArgList&)
 {
     UString s = thisValue.toThisString(exec);
-    return jsNontrivialString(exec, "<sup>" + s + "</sup>");
+    return jsNontrivialString(exec, makeString("<sup>", s, "</sup>"));
 }
 
 JSValue JSC_HOST_CALL stringProtoFuncFontcolor(ExecState* exec, JSObject*, JSValue thisValue, const ArgList& args)
 {
     UString s = thisValue.toThisString(exec);
     JSValue a0 = args.at(0);
-    return jsNontrivialString(exec, "<font color=\"" + a0.toString(exec) + "\">" + s + "</font>");
+    return jsNontrivialString(exec, makeString("<font color=\"", a0.toString(exec), "\">", s, "</font>"));
 }
 
 JSValue JSC_HOST_CALL stringProtoFuncFontsize(ExecState* exec, JSObject*, JSValue thisValue, const ArgList& args)
@@ -871,14 +871,14 @@ JSValue JSC_HOST_CALL stringProtoFuncFontsize(ExecState* exec, JSObject*, JSValu
         return jsNontrivialString(exec, UString(buffer, bufferSize, false));
     }
 
-    return jsNontrivialString(exec, "<font size=\"" + a0.toString(exec) + "\">" + s + "</font>");
+    return jsNontrivialString(exec, makeString("<font size=\"", a0.toString(exec), "\">", s, "</font>"));
 }
 
 JSValue JSC_HOST_CALL stringProtoFuncAnchor(ExecState* exec, JSObject*, JSValue thisValue, const ArgList& args)
 {
     UString s = thisValue.toThisString(exec);
     JSValue a0 = args.at(0);
-    return jsNontrivialString(exec, "<a name=\"" + a0.toString(exec) + "\">" + s + "</a>");
+    return jsNontrivialString(exec, makeString("<a name=\"", a0.toString(exec), "\">", s, "</a>"));
 }
 
 JSValue JSC_HOST_CALL stringProtoFuncLink(ExecState* exec, JSObject*, JSValue thisValue, const ArgList& args)
diff --git a/JavaScriptCore/runtime/UString.h b/JavaScriptCore/runtime/UString.h
index 9b046f2..9c2433b 100644
--- a/JavaScriptCore/runtime/UString.h
+++ b/JavaScriptCore/runtime/UString.h
@@ -537,6 +537,276 @@ namespace JSC {
     };
 
     void initializeUString();
+
+    template<typename StringType>
+    class StringTypeAdapter {
+    };
+
+    template<>
+    class StringTypeAdapter<char*>
+    {
+    public:
+        StringTypeAdapter<char*>(char* buffer)
+            : m_buffer((unsigned char*)buffer)
+            , m_length(strlen(buffer))
+        {
+        }
+
+        unsigned length() { return m_length; }
+
+        void writeTo(UChar* destination)
+        {
+            for (unsigned i = 0; i < m_length; ++i)
+                destination[i] = m_buffer[i];
+        }
+
+    private:
+        const unsigned char* m_buffer;
+        unsigned m_length;
+    };
+
+    template<>
+    class StringTypeAdapter<const char*>
+    {
+    public:
+        StringTypeAdapter<const char*>(const char* buffer)
+            : m_buffer((unsigned char*)buffer)
+            , m_length(strlen(buffer))
+        {
+        }
+
+        unsigned length() { return m_length; }
+
+        void writeTo(UChar* destination)
+        {
+            for (unsigned i = 0; i < m_length; ++i)
+                destination[i] = m_buffer[i];
+        }
+
+    private:
+        const unsigned char* m_buffer;
+        unsigned m_length;
+    };
+
+    template<>
+    class StringTypeAdapter<UString>
+    {
+    public:
+        StringTypeAdapter<UString>(UString& string)
+            : m_data(string.data())
+            , m_length(string.size())
+        {
+        }
+
+        unsigned length() { return m_length; }
+
+        void writeTo(UChar* destination)
+        {
+            for (unsigned i = 0; i < m_length; ++i)
+                destination[i] = m_data[i];
+        }
+
+    private:
+        const UChar* m_data;
+        unsigned m_length;
+    };
+
+    template<typename StringType1, typename StringType2>
+    UString makeString(StringType1 string1, StringType2 string2)
+    {
+        StringTypeAdapter<StringType1> adapter1(string1);
+        StringTypeAdapter<StringType2> adapter2(string2);
+
+        UChar* buffer;
+        unsigned length = adapter1.length() + adapter2.length();
+        if (!tryFastMalloc(length * sizeof(UChar)).getValue(buffer))
+            return UString();
+
+        UChar* result = buffer;
+        adapter1.writeTo(result);
+        result += adapter1.length();
+        adapter2.writeTo(result);
+
+        return UString(buffer, length, false);
+    }
+
+    template<typename StringType1, typename StringType2, typename StringType3>
+    UString makeString(StringType1 string1, StringType2 string2, StringType3 string3)
+    {
+        StringTypeAdapter<StringType1> adapter1(string1);
+        StringTypeAdapter<StringType2> adapter2(string2);
+        StringTypeAdapter<StringType3> adapter3(string3);
+
+        UChar* buffer;
+        unsigned length = adapter1.length() + adapter2.length() + adapter3.length();
+        if (!tryFastMalloc(length * sizeof(UChar)).getValue(buffer))
+            return UString();
+
+        UChar* result = buffer;
+        adapter1.writeTo(result);
+        result += adapter1.length();
+        adapter2.writeTo(result);
+        result += adapter2.length();
+        adapter3.writeTo(result);
+
+        return UString(buffer, length, false);
+    }
+
+    template<typename StringType1, typename StringType2, typename StringType3, typename StringType4>
+    UString makeString(StringType1 string1, StringType2 string2, StringType3 string3, StringType4 string4)
+    {
+        StringTypeAdapter<StringType1> adapter1(string1);
+        StringTypeAdapter<StringType2> adapter2(string2);
+        StringTypeAdapter<StringType3> adapter3(string3);
+        StringTypeAdapter<StringType4> adapter4(string4);
+
+        UChar* buffer;
+        unsigned length = adapter1.length() + adapter2.length() + adapter3.length() + adapter4.length();
+        if (!tryFastMalloc(length * sizeof(UChar)).getValue(buffer))
+            return UString();
+
+        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 UString(buffer, length, false);
+    }
+
+    template<typename StringType1, typename StringType2, typename StringType3, typename StringType4, typename StringType5>
+    UString makeString(StringType1 string1, StringType2 string2, StringType3 string3, StringType4 string4, StringType5 string5)
+    {
+        StringTypeAdapter<StringType1> adapter1(string1);
+        StringTypeAdapter<StringType2> adapter2(string2);
+        StringTypeAdapter<StringType3> adapter3(string3);
+        StringTypeAdapter<StringType4> adapter4(string4);
+        StringTypeAdapter<StringType5> adapter5(string5);
+
+        UChar* buffer;
+        unsigned length = adapter1.length() + adapter2.length() + adapter3.length() + adapter4.length() + adapter5.length();
+        if (!tryFastMalloc(length * sizeof(UChar)).getValue(buffer))
+            return UString();
+
+        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 UString(buffer, length, false);
+    }
+
+    template<typename StringType1, typename StringType2, typename StringType3, typename StringType4, typename StringType5, typename StringType6>
+    UString makeString(StringType1 string1, StringType2 string2, StringType3 string3, StringType4 string4, StringType5 string5, StringType6 string6)
+    {
+        StringTypeAdapter<StringType1> adapter1(string1);
+        StringTypeAdapter<StringType2> adapter2(string2);
+        StringTypeAdapter<StringType3> adapter3(string3);
+        StringTypeAdapter<StringType4> adapter4(string4);
+        StringTypeAdapter<StringType5> adapter5(string5);
+        StringTypeAdapter<StringType6> adapter6(string6);
+
+        UChar* buffer;
+        unsigned length = adapter1.length() + adapter2.length() + adapter3.length() + adapter4.length() + adapter5.length() + adapter6.length();
+        if (!tryFastMalloc(length * sizeof(UChar)).getValue(buffer))
+            return UString();
+
+        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 UString(buffer, length, false);
+    }
+
+    template<typename StringType1, typename StringType2, typename StringType3, typename StringType4, typename StringType5, typename StringType6, typename StringType7>
+    UString makeString(StringType1 string1, StringType2 string2, StringType3 string3, StringType4 string4, StringType5 string5, StringType6 string6, StringType7 string7)
+    {
+        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);
+
+        UChar* buffer;
+        unsigned length = adapter1.length() + adapter2.length() + adapter3.length() + adapter4.length() + adapter5.length() + adapter6.length() + adapter7.length();
+        if (!tryFastMalloc(length * sizeof(UChar)).getValue(buffer))
+            return UString();
+
+        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 UString(buffer, length, false);
+    }
+
+    template<typename StringType1, typename StringType2, typename StringType3, typename StringType4, typename StringType5, typename StringType6, typename StringType7, typename StringType8>
+    UString makeString(StringType1 string1, StringType2 string2, StringType3 string3, StringType4 string4, StringType5 string5, StringType6 string6, StringType7 string7, StringType8 string8)
+    {
+        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);
+
+        UChar* buffer;
+        unsigned length = adapter1.length() + adapter2.length() + adapter3.length() + adapter4.length() + adapter5.length() + adapter6.length() + adapter7.length() + adapter8.length();
+        if (!tryFastMalloc(length * sizeof(UChar)).getValue(buffer))
+            return UString();
+
+        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);
+
+        return UString(buffer, length, false);
+    }
+
 } // namespace JSC
 
 namespace WTF {

-- 
WebKit Debian packaging



More information about the Pkg-webkit-commits mailing list