Changeset 52028 in webkit


Ignore:
Timestamp:
Dec 11, 2009, 3:34:10 PM (16 years ago)
Author:
[email protected]
Message:

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):

Location:
trunk/JavaScriptCore
Files:
17 edited

Legend:

Unmodified
Added
Removed
  • trunk/JavaScriptCore/ChangeLog

    r52026 r52028  
     12009-12-11  Gavin Barraclough  <[email protected]>
     2
     3        Reviewed by Oliver Hunt.
     4
     5        https://bugs.webkit.org/show_bug.cgi?id=32454
     6        Refactor construction of simple strings to avoid string concatenation.
     7
     8        Building strings through concatenation has a memory and performance cost -
     9        a memory cost since we must over-allocate the buffer to leave space to append
     10        into, and performance in that the string may still require reallocation (and
     11        thus copying during construction).  Instead move the full construction to
     12        within a single function call (makeString), so that the arguments' lengths
     13        can be calculated and an appropriate sized buffer allocated before copying
     14        any characters.
     15
     16        ~No performance change (~2% progression on date tests).
     17
     18        * bytecode/CodeBlock.cpp:
     19        (JSC::escapeQuotes):
     20        (JSC::valueToSourceString):
     21        (JSC::constantName):
     22        (JSC::idName):
     23        (JSC::CodeBlock::registerName):
     24        (JSC::regexpToSourceString):
     25        (JSC::regexpName):
     26        * bytecompiler/NodesCodegen.cpp:
     27        (JSC::substitute):
     28        * profiler/Profiler.cpp:
     29        (JSC::Profiler::createCallIdentifier):
     30        * runtime/DateConstructor.cpp:
     31        (JSC::callDate):
     32        * runtime/DateConversion.cpp:
     33        (JSC::formatDate):
     34        (JSC::formatDateUTCVariant):
     35        (JSC::formatTime):
     36        (JSC::formatTimeUTC):
     37        * runtime/DateConversion.h:
     38        (JSC::):
     39        * runtime/DatePrototype.cpp:
     40        (JSC::dateProtoFuncToString):
     41        (JSC::dateProtoFuncToUTCString):
     42        (JSC::dateProtoFuncToDateString):
     43        (JSC::dateProtoFuncToTimeString):
     44        (JSC::dateProtoFuncToGMTString):
     45        * runtime/ErrorPrototype.cpp:
     46        (JSC::errorProtoFuncToString):
     47        * runtime/ExceptionHelpers.cpp:
     48        (JSC::createUndefinedVariableError):
     49        (JSC::createErrorMessage):
     50        (JSC::createInvalidParamError):
     51        * runtime/FunctionPrototype.cpp:
     52        (JSC::insertSemicolonIfNeeded):
     53        (JSC::functionProtoFuncToString):
     54        * runtime/ObjectPrototype.cpp:
     55        (JSC::objectProtoFuncToString):
     56        * runtime/RegExpConstructor.cpp:
     57        (JSC::constructRegExp):
     58        * runtime/RegExpObject.cpp:
     59        (JSC::RegExpObject::match):
     60        * runtime/RegExpPrototype.cpp:
     61        (JSC::regExpProtoFuncCompile):
     62        (JSC::regExpProtoFuncToString):
     63        * runtime/StringPrototype.cpp:
     64        (JSC::stringProtoFuncBig):
     65        (JSC::stringProtoFuncSmall):
     66        (JSC::stringProtoFuncBlink):
     67        (JSC::stringProtoFuncBold):
     68        (JSC::stringProtoFuncFixed):
     69        (JSC::stringProtoFuncItalics):
     70        (JSC::stringProtoFuncStrike):
     71        (JSC::stringProtoFuncSub):
     72        (JSC::stringProtoFuncSup):
     73        (JSC::stringProtoFuncFontcolor):
     74        (JSC::stringProtoFuncFontsize):
     75        (JSC::stringProtoFuncAnchor):
     76        * runtime/UString.h:
     77        (JSC::):
     78        (JSC::makeString):
     79
    1802009-12-10  Gavin Barraclough  <[email protected]>
    281
  • trunk/JavaScriptCore/bytecode/CodeBlock.cpp

    r51735 r52028  
    5252    int pos = 0;
    5353    while ((pos = result.find('\"', pos)) >= 0) {
    54         result = result.substr(0, pos) + "\"\\\"\"" + result.substr(pos + 1);
     54        result = makeString(result.substr(0, pos), "\"\\\"\"", result.substr(pos + 1));
    5555        pos += 4;
    5656    }
     
    6363        return "0";
    6464
    65     if (val.isString()) {
    66         UString result("\"");
    67         result += escapeQuotes(val.toString(exec)) + "\"";
    68         return result;
    69     }
     65    if (val.isString())
     66        return makeString("\"", escapeQuotes(val.toString(exec)), "\"");
    7067
    7168    return val.toString(exec);
     
    7471static CString constantName(ExecState* exec, int k, JSValue value)
    7572{
    76     return (valueToSourceString(exec, value) + "(@k" + UString::from(k - FirstConstantRegisterIndex) + ")").UTF8String();
     73    return makeString(valueToSourceString(exec, value), "(@k", UString::from(k - FirstConstantRegisterIndex), ")").UTF8String();
    7774}
    7875
    7976static CString idName(int id0, const Identifier& ident)
    8077{
    81     return (ident.ustring() + "(@id" + UString::from(id0) +")").UTF8String();
     78    return makeString(ident.ustring(), "(@id", UString::from(id0), ")").UTF8String();
    8279}
    8380
     
    9087        return constantName(exec, r, getConstant(r));
    9188
    92     return (UString("r") + UString::from(r)).UTF8String();
     89    return makeString("r", UString::from(r)).UTF8String();
    9390}
    9491
    9592static UString regexpToSourceString(RegExp* regExp)
    9693{
    97     UString pattern = UString("/") + regExp->pattern() + "/";
     94    char postfix[5] = { '/', 0, 0, 0, 0 };
     95    int index = 1;
    9896    if (regExp->global())
    99         pattern += "g";
     97        postfix[index++] = 'g';
    10098    if (regExp->ignoreCase())
    101         pattern += "i";
     99        postfix[index++] = 'i';
    102100    if (regExp->multiline())
    103         pattern += "m";
    104 
    105     return pattern;
     101        postfix[index] = 'm';
     102
     103    return makeString("/", regExp->pattern(), postfix);
    106104}
    107105
    108106static CString regexpName(int re, RegExp* regexp)
    109107{
    110     return (regexpToSourceString(regexp) + "(@re" + UString::from(re) + ")").UTF8String();
     108    return makeString(regexpToSourceString(regexp), "(@re", UString::from(re), ")").UTF8String();
    111109}
    112110
  • trunk/JavaScriptCore/bytecompiler/NodesCodegen.cpp

    r51882 r52028  
    7979    int position = string.find("%s");
    8080    ASSERT(position != -1);
    81     UString newString = string.substr(0, position);
    82     newString.append(substring);
    83     newString.append(string.substr(position + 2));
    84     string = newString;
     81    string = makeString(string.substr(0, position), substring, string.substr(position + 2));
    8582}
    8683
  • trunk/JavaScriptCore/profiler/Profiler.cpp

    r51801 r52028  
    149149    if (asObject(functionValue)->inherits(&InternalFunction::info))
    150150        return CallIdentifier(static_cast<InternalFunction*>(asObject(functionValue))->name(exec), defaultSourceURL, defaultLineNumber);
    151     return CallIdentifier("(" + asObject(functionValue)->className() + " object)", defaultSourceURL, defaultLineNumber);
     151    return CallIdentifier(makeString("(", asObject(functionValue)->className(), " object)"), defaultSourceURL, defaultLineNumber);
    152152}
    153153
  • trunk/JavaScriptCore/runtime/DateConstructor.cpp

    r51801 r52028  
    134134    getLocalTime(&localTime, &localTM);
    135135    GregorianDateTime ts(exec, localTM);
    136     return jsNontrivialString(exec, formatDate(ts) + " " + formatTime(ts));
     136    DateConversionBuffer date;
     137    DateConversionBuffer time;
     138    formatDate(ts, date);
     139    formatTime(ts, time);
     140    return jsNontrivialString(exec, makeString(date, " ", time));
    137141}
    138142
  • trunk/JavaScriptCore/runtime/DateConversion.cpp

    r50708 r52028  
    6363}
    6464
    65 UString formatDate(const GregorianDateTime &t)
     65void formatDate(const GregorianDateTime &t, DateConversionBuffer& buffer)
    6666{
    67     char buffer[100];
    68     snprintf(buffer, sizeof(buffer), "%s %s %02d %04d",
     67    snprintf(buffer, DateConversionBufferSize, "%s %s %02d %04d",
    6968        weekdayName[(t.weekDay + 6) % 7],
    7069        monthName[t.month], t.monthDay, t.year + 1900);
    71     return buffer;
    7270}
    7371
    74 UString formatDateUTCVariant(const GregorianDateTime &t)
     72void formatDateUTCVariant(const GregorianDateTime &t, DateConversionBuffer& buffer)
    7573{
    76     char buffer[100];
    77     snprintf(buffer, sizeof(buffer), "%s, %02d %s %04d",
     74    snprintf(buffer, DateConversionBufferSize, "%s, %02d %s %04d",
    7875        weekdayName[(t.weekDay + 6) % 7],
    7976        t.monthDay, monthName[t.month], t.year + 1900);
    80     return buffer;
    8177}
    8278
    83 UString formatTime(const GregorianDateTime &t)
     79void formatTime(const GregorianDateTime &t, DateConversionBuffer& buffer)
    8480{
    85     char buffer[100];
    8681    int offset = abs(gmtoffset(t));
    8782    char timeZoneName[70];
     
    9085
    9186    if (timeZoneName[0]) {
    92         snprintf(buffer, sizeof(buffer), "%02d:%02d:%02d GMT%c%02d%02d (%s)",
     87        snprintf(buffer, DateConversionBufferSize, "%02d:%02d:%02d GMT%c%02d%02d (%s)",
    9388            t.hour, t.minute, t.second,
    9489            gmtoffset(t) < 0 ? '-' : '+', offset / (60*60), (offset / 60) % 60, timeZoneName);
    9590    } else {
    96         snprintf(buffer, sizeof(buffer), "%02d:%02d:%02d GMT%c%02d%02d",
     91        snprintf(buffer, DateConversionBufferSize, "%02d:%02d:%02d GMT%c%02d%02d",
    9792            t.hour, t.minute, t.second,
    9893            gmtoffset(t) < 0 ? '-' : '+', offset / (60*60), (offset / 60) % 60);
    9994    }
    100     return UString(buffer);
    10195}
    10296
    103 UString formatTimeUTC(const GregorianDateTime &t)
     97void formatTimeUTC(const GregorianDateTime &t, DateConversionBuffer& buffer)
    10498{
    105     char buffer[100];
    106     snprintf(buffer, sizeof(buffer), "%02d:%02d:%02d GMT", t.hour, t.minute, t.second);
    107     return UString(buffer);
     99    snprintf(buffer, DateConversionBufferSize, "%02d:%02d:%02d GMT", t.hour, t.minute, t.second);
    108100}
    109101
  • trunk/JavaScriptCore/runtime/DateConversion.h

    r50708 r52028  
    4343#define DateConversion_h
    4444
     45#include "UString.h"
     46
    4547namespace JSC {
    4648
    4749class ExecState;
    48 class UString;
    4950struct GregorianDateTime;
    5051
     52static const unsigned DateConversionBufferSize = 100;
     53typedef char DateConversionBuffer[DateConversionBufferSize];
     54
    5155double parseDate(ExecState* exec, const UString&);
    52 UString formatDate(const GregorianDateTime&);
    53 UString formatDateUTCVariant(const GregorianDateTime&);
    54 UString formatTime(const GregorianDateTime&);
    55 UString formatTimeUTC(const GregorianDateTime&);
     56void formatDate(const GregorianDateTime&, DateConversionBuffer&);
     57void formatDateUTCVariant(const GregorianDateTime&, DateConversionBuffer&);
     58void formatTime(const GregorianDateTime&, DateConversionBuffer&);
     59void formatTimeUTC(const GregorianDateTime&, DateConversionBuffer&);
    5660
    5761} // namespace JSC
  • trunk/JavaScriptCore/runtime/DatePrototype.cpp

    r51197 r52028  
    424424    if (!gregorianDateTime)
    425425        return jsNontrivialString(exec, "Invalid Date");
    426     return jsNontrivialString(exec, formatDate(*gregorianDateTime) + " " + formatTime(*gregorianDateTime));
     426    DateConversionBuffer date;
     427    DateConversionBuffer time;
     428    formatDate(*gregorianDateTime, date);
     429    formatTime(*gregorianDateTime, time);
     430    return jsNontrivialString(exec, makeString(date, " ", time));
    427431}
    428432
     
    437441    if (!gregorianDateTime)
    438442        return jsNontrivialString(exec, "Invalid Date");
    439     return jsNontrivialString(exec, formatDateUTCVariant(*gregorianDateTime) + " " + formatTimeUTC(*gregorianDateTime));
     443    DateConversionBuffer date;
     444    DateConversionBuffer time;
     445    formatDateUTCVariant(*gregorianDateTime, date);
     446    formatTimeUTC(*gregorianDateTime, time);
     447    return jsNontrivialString(exec, makeString(date, " ", time));
    440448}
    441449
     
    468476    if (!gregorianDateTime)
    469477        return jsNontrivialString(exec, "Invalid Date");
    470     return jsNontrivialString(exec, formatDate(*gregorianDateTime));
     478    DateConversionBuffer date;
     479    formatDate(*gregorianDateTime, date);
     480    return jsNontrivialString(exec, date);
    471481}
    472482
     
    481491    if (!gregorianDateTime)
    482492        return jsNontrivialString(exec, "Invalid Date");
    483     return jsNontrivialString(exec, formatTime(*gregorianDateTime));
     493    DateConversionBuffer time;
     494    formatTime(*gregorianDateTime, time);
     495    return jsNontrivialString(exec, time);
    484496}
    485497
     
    555567    if (!gregorianDateTime)
    556568        return jsNontrivialString(exec, "Invalid Date");
    557     return jsNontrivialString(exec, formatDateUTCVariant(*gregorianDateTime) + " " + formatTimeUTC(*gregorianDateTime));
     569    DateConversionBuffer date;
     570    DateConversionBuffer time;
     571    formatDateUTCVariant(*gregorianDateTime, date);
     572    formatTimeUTC(*gregorianDateTime, time);
     573    return jsNontrivialString(exec, makeString(date, " ", time));
    558574}
    559575
  • trunk/JavaScriptCore/runtime/ErrorPrototype.cpp

    r48836 r52028  
    4949{
    5050    JSObject* thisObj = thisValue.toThisObject(exec);
     51    JSValue name = thisObj->get(exec, exec->propertyNames().name);
     52    JSValue message = thisObj->get(exec, exec->propertyNames().message);
    5153
    52     UString s = "Error";
     54    // Mozilla-compatible format.
    5355
    54     JSValue v = thisObj->get(exec, exec->propertyNames().name);
    55     if (!v.isUndefined())
    56         s = v.toString(exec);
    57 
    58     v = thisObj->get(exec, exec->propertyNames().message);
    59     if (!v.isUndefined()) {
    60         // Mozilla-compatible format.
    61         s += ": ";
    62         s += v.toString(exec);
     56    if (!name.isUndefined()) {
     57        if (!message.isUndefined())
     58            return jsNontrivialString(exec, makeString(name.toString(exec), ": ", message.toString(exec)));
     59        return jsNontrivialString(exec, name.toString(exec));
    6360    }
    64 
    65     return jsNontrivialString(exec, s);
     61    if (!message.isUndefined())
     62        return jsNontrivialString(exec, makeString("Error: ", message.toString(exec)));
     63    return jsNontrivialString(exec, "Error");
    6664}
    6765
  • trunk/JavaScriptCore/runtime/ExceptionHelpers.cpp

    r49214 r52028  
    7878    int divotPoint = 0;
    7979    int line = codeBlock->expressionRangeForBytecodeOffset(exec, bytecodeOffset, divotPoint, startOffset, endOffset);
    80     UString message = "Can't find variable: ";
    81     message.append(ident.ustring());
    82     JSObject* exception = Error::create(exec, ReferenceError, message, line, codeBlock->ownerExecutable()->sourceID(), codeBlock->ownerExecutable()->sourceURL());
     80    JSObject* exception = Error::create(exec, ReferenceError, makeString("Can't find variable: ", ident.ustring()), line, codeBlock->ownerExecutable()->sourceID(), codeBlock->ownerExecutable()->sourceURL());
    8381    exception->putWithAttributes(exec, Identifier(exec, expressionBeginOffsetPropertyName), jsNumber(exec, divotPoint - startOffset), ReadOnly | DontDelete);
    8482    exception->putWithAttributes(exec, Identifier(exec, expressionCaretOffsetPropertyName), jsNumber(exec, divotPoint), ReadOnly | DontDelete);
     
    8987static UString createErrorMessage(ExecState* exec, CodeBlock* codeBlock, int, int expressionStart, int expressionStop, JSValue value, UString error)
    9088{
    91     if (!expressionStop || expressionStart > codeBlock->source()->length()) {
    92         UString errorText = value.toString(exec);
    93         errorText.append(" is ");
    94         errorText.append(error);
    95         return errorText;
    96     }
     89    if (!expressionStop || expressionStart > codeBlock->source()->length())
     90        return makeString(value.toString(exec), " is ", error);
     91    if (expressionStart < expressionStop)
     92        return makeString("Result of expression '", codeBlock->source()->getRange(expressionStart, expressionStop), "' [", value.toString(exec), "] is ", error, ".");
    9793
    98     UString errorText = "Result of expression ";
    99    
    100     if (expressionStart < expressionStop) {
    101         errorText.append('\'');
    102         errorText.append(codeBlock->source()->getRange(expressionStart, expressionStop));
    103         errorText.append("' [");
    104         errorText.append(value.toString(exec));
    105         errorText.append("] is ");
    106     } else {
    107         // No range information, so give a few characters of context
    108         const UChar* data = codeBlock->source()->data();
    109         int dataLength = codeBlock->source()->length();
    110         int start = expressionStart;
    111         int stop = expressionStart;
    112         // Get up to 20 characters of context to the left and right of the divot, clamping to the line.
    113         // then strip whitespace.
    114         while (start > 0 && (expressionStart - start < 20) && data[start - 1] != '\n')
    115             start--;
    116         while (start < (expressionStart - 1) && isStrWhiteSpace(data[start]))
    117             start++;
    118         while (stop < dataLength && (stop - expressionStart < 20) && data[stop] != '\n')
    119             stop++;
    120         while (stop > expressionStart && isStrWhiteSpace(data[stop]))
    121             stop--;
    122         errorText.append("near '...");
    123         errorText.append(codeBlock->source()->getRange(start, stop));
    124         errorText.append("...' [");
    125         errorText.append(value.toString(exec));
    126         errorText.append("] is ");
    127     }
    128     errorText.append(error);
    129     errorText.append(".");
    130     return errorText;
     94    // No range information, so give a few characters of context
     95    const UChar* data = codeBlock->source()->data();
     96    int dataLength = codeBlock->source()->length();
     97    int start = expressionStart;
     98    int stop = expressionStart;
     99    // Get up to 20 characters of context to the left and right of the divot, clamping to the line.
     100    // then strip whitespace.
     101    while (start > 0 && (expressionStart - start < 20) && data[start - 1] != '\n')
     102        start--;
     103    while (start < (expressionStart - 1) && isStrWhiteSpace(data[start]))
     104        start++;
     105    while (stop < dataLength && (stop - expressionStart < 20) && data[stop] != '\n')
     106        stop++;
     107    while (stop > expressionStart && isStrWhiteSpace(data[stop]))
     108        stop--;
     109    return makeString("Result of expression near '...", codeBlock->source()->getRange(start, stop), "...' [", value.toString(exec), "] is ", error, ".");
    131110}
    132111
    133112JSObject* createInvalidParamError(ExecState* exec, const char* op, JSValue value, unsigned bytecodeOffset, CodeBlock* codeBlock)
    134113{
    135     UString message = "not a valid argument for '";
    136     message.append(op);
    137     message.append("'");
    138    
    139114    int startOffset = 0;
    140115    int endOffset = 0;
    141116    int divotPoint = 0;
    142117    int line = codeBlock->expressionRangeForBytecodeOffset(exec, bytecodeOffset, divotPoint, startOffset, endOffset);
    143     UString errorMessage = createErrorMessage(exec, codeBlock, line, divotPoint, divotPoint + endOffset, value, message);
     118    UString errorMessage = createErrorMessage(exec, codeBlock, line, divotPoint, divotPoint + endOffset, value, makeString("not a valid argument for '", op, "'"));
    144119    JSObject* exception = Error::create(exec, TypeError, errorMessage, line, codeBlock->ownerExecutable()->sourceID(), codeBlock->ownerExecutable()->sourceURL());
    145120    exception->putWithAttributes(exec, Identifier(exec, expressionBeginOffsetPropertyName), jsNumber(exec, divotPoint - startOffset), ReadOnly | DontDelete);
  • trunk/JavaScriptCore/runtime/FunctionPrototype.cpp

    r51801 r52028  
    7777        if (!Lexer::isWhiteSpace(ch) && !Lexer::isLineTerminator(ch)) {
    7878            if (ch != ';' && ch != '}')
    79                 functionBody = functionBody.substr(0, i + 1) + ";" + functionBody.substr(i + 1, functionBody.size() - (i + 1));
     79                functionBody = makeString(functionBody.substr(0, i + 1), ";", functionBody.substr(i + 1, functionBody.size() - (i + 1)));
    8080            return;
    8181        }
     
    9191            UString sourceString = executable->source().toString();
    9292            insertSemicolonIfNeeded(sourceString);
    93             return jsString(exec, "function " + function->name(exec) + "(" + executable->paramString() + ") " + sourceString);
     93            return jsString(exec, makeString("function ", function->name(exec), "(", executable->paramString(), ") ", sourceString));
    9494        }
    9595    }
     
    9797    if (thisValue.inherits(&InternalFunction::info)) {
    9898        InternalFunction* function = asInternalFunction(thisValue);
    99         return jsString(exec, "function " + function->name(exec) + "() {\n    [native code]\n}");
     99        return jsString(exec, makeString("function ", function->name(exec), "() {\n    [native code]\n}"));
    100100    }
    101101
  • trunk/JavaScriptCore/runtime/ObjectPrototype.cpp

    r48836 r52028  
    150150JSValue JSC_HOST_CALL objectProtoFuncToString(ExecState* exec, JSObject*, JSValue thisValue, const ArgList&)
    151151{
    152     return jsNontrivialString(exec, "[object " + thisValue.toThisObject(exec)->className() + "]");
     152    return jsNontrivialString(exec, makeString("[object ", thisValue.toThisObject(exec)->className(), "]"));
    153153}
    154154
  • trunk/JavaScriptCore/runtime/RegExpConstructor.cpp

    r51369 r52028  
    303303    RefPtr<RegExp> regExp = RegExp::create(&exec->globalData(), pattern, flags);
    304304    if (!regExp->isValid())
    305         return throwError(exec, SyntaxError, UString("Invalid regular expression: ").append(regExp->errorMessage()));
     305        return throwError(exec, SyntaxError, makeString("Invalid regular expression: ", regExp->errorMessage()));
    306306    return new (exec) RegExpObject(exec->lexicalGlobalObject()->regExpStructure(), regExp.release());
    307307}
  • trunk/JavaScriptCore/runtime/RegExpObject.cpp

    r49368 r52028  
    143143    UString input = args.isEmpty() ? regExpConstructor->input() : args.at(0).toString(exec);
    144144    if (input.isNull()) {
    145         throwError(exec, GeneralError, "No input to " + toString(exec) + ".");
     145        throwError(exec, GeneralError, makeString("No input to ", toString(exec), "."));
    146146        return false;
    147147    }
  • trunk/JavaScriptCore/runtime/RegExpPrototype.cpp

    r48836 r52028  
    9292
    9393    if (!regExp->isValid())
    94         return throwError(exec, SyntaxError, UString("Invalid regular expression: ").append(regExp->errorMessage()));
     94        return throwError(exec, SyntaxError, makeString("Invalid regular expression: ", regExp->errorMessage()));
    9595
    9696    asRegExpObject(thisValue)->setRegExp(regExp.release());
     
    107107    }
    108108
    109     UString result = "/" + asRegExpObject(thisValue)->get(exec, exec->propertyNames().source).toString(exec);
    110     result.append('/');
     109    char postfix[5] = { '/', 0, 0, 0, 0 };
     110    int index = 1;
    111111    if (asRegExpObject(thisValue)->get(exec, exec->propertyNames().global).toBoolean(exec))
    112         result.append('g');
     112        postfix[index++] = 'g';
    113113    if (asRegExpObject(thisValue)->get(exec, exec->propertyNames().ignoreCase).toBoolean(exec))
    114         result.append('i');
     114        postfix[index++] = 'i';
    115115    if (asRegExpObject(thisValue)->get(exec, exec->propertyNames().multiline).toBoolean(exec))
    116         result.append('m');
    117     return jsNontrivialString(exec, result);
     116        postfix[index] = 'm';
     117   
     118    return jsNontrivialString(exec, makeString("/", asRegExpObject(thisValue)->get(exec, exec->propertyNames().source).toString(exec), postfix));
    118119}
    119120
  • trunk/JavaScriptCore/runtime/StringPrototype.cpp

    r51801 r52028  
    776776{
    777777    UString s = thisValue.toThisString(exec);
    778     return jsNontrivialString(exec, "<big>" + s + "</big>");
     778    return jsNontrivialString(exec, makeString("<big>", s, "</big>"));
    779779}
    780780
     
    782782{
    783783    UString s = thisValue.toThisString(exec);
    784     return jsNontrivialString(exec, "<small>" + s + "</small>");
     784    return jsNontrivialString(exec, makeString("<small>", s, "</small>"));
    785785}
    786786
     
    788788{
    789789    UString s = thisValue.toThisString(exec);
    790     return jsNontrivialString(exec, "<blink>" + s + "</blink>");
     790    return jsNontrivialString(exec, makeString("<blink>", s, "</blink>"));
    791791}
    792792
     
    794794{
    795795    UString s = thisValue.toThisString(exec);
    796     return jsNontrivialString(exec, "<b>" + s + "</b>");
     796    return jsNontrivialString(exec, makeString("<b>", s, "</b>"));
    797797}
    798798
     
    800800{
    801801    UString s = thisValue.toThisString(exec);
    802     return jsString(exec, "<tt>" + s + "</tt>");
     802    return jsString(exec, makeString("<tt>", s, "</tt>"));
    803803}
    804804
     
    806806{
    807807    UString s = thisValue.toThisString(exec);
    808     return jsNontrivialString(exec, "<i>" + s + "</i>");
     808    return jsNontrivialString(exec, makeString("<i>", s, "</i>"));
    809809}
    810810
     
    812812{
    813813    UString s = thisValue.toThisString(exec);
    814     return jsNontrivialString(exec, "<strike>" + s + "</strike>");
     814    return jsNontrivialString(exec, makeString("<strike>", s, "</strike>"));
    815815}
    816816
     
    818818{
    819819    UString s = thisValue.toThisString(exec);
    820     return jsNontrivialString(exec, "<sub>" + s + "</sub>");
     820    return jsNontrivialString(exec, makeString("<sub>", s, "</sub>"));
    821821}
    822822
     
    824824{
    825825    UString s = thisValue.toThisString(exec);
    826     return jsNontrivialString(exec, "<sup>" + s + "</sup>");
     826    return jsNontrivialString(exec, makeString("<sup>", s, "</sup>"));
    827827}
    828828
     
    831831    UString s = thisValue.toThisString(exec);
    832832    JSValue a0 = args.at(0);
    833     return jsNontrivialString(exec, "<font color=\"" + a0.toString(exec) + "\">" + s + "</font>");
     833    return jsNontrivialString(exec, makeString("<font color=\"", a0.toString(exec), "\">", s, "</font>"));
    834834}
    835835
     
    872872    }
    873873
    874     return jsNontrivialString(exec, "<font size=\"" + a0.toString(exec) + "\">" + s + "</font>");
     874    return jsNontrivialString(exec, makeString("<font size=\"", a0.toString(exec), "\">", s, "</font>"));
    875875}
    876876
     
    879879    UString s = thisValue.toThisString(exec);
    880880    JSValue a0 = args.at(0);
    881     return jsNontrivialString(exec, "<a name=\"" + a0.toString(exec) + "\">" + s + "</a>");
     881    return jsNontrivialString(exec, makeString("<a name=\"", a0.toString(exec), "\">", s, "</a>"));
    882882}
    883883
  • trunk/JavaScriptCore/runtime/UString.h

    r51168 r52028  
    538538
    539539    void initializeUString();
     540
     541    template<typename StringType>
     542    class StringTypeAdapter {
     543    };
     544
     545    template<>
     546    class StringTypeAdapter<char*>
     547    {
     548    public:
     549        StringTypeAdapter<char*>(char* buffer)
     550            : m_buffer((unsigned char*)buffer)
     551            , m_length(strlen(buffer))
     552        {
     553        }
     554
     555        unsigned length() { return m_length; }
     556
     557        void writeTo(UChar* destination)
     558        {
     559            for (unsigned i = 0; i < m_length; ++i)
     560                destination[i] = m_buffer[i];
     561        }
     562
     563    private:
     564        const unsigned char* m_buffer;
     565        unsigned m_length;
     566    };
     567
     568    template<>
     569    class StringTypeAdapter<const char*>
     570    {
     571    public:
     572        StringTypeAdapter<const char*>(const char* buffer)
     573            : m_buffer((unsigned char*)buffer)
     574            , m_length(strlen(buffer))
     575        {
     576        }
     577
     578        unsigned length() { return m_length; }
     579
     580        void writeTo(UChar* destination)
     581        {
     582            for (unsigned i = 0; i < m_length; ++i)
     583                destination[i] = m_buffer[i];
     584        }
     585
     586    private:
     587        const unsigned char* m_buffer;
     588        unsigned m_length;
     589    };
     590
     591    template<>
     592    class StringTypeAdapter<UString>
     593    {
     594    public:
     595        StringTypeAdapter<UString>(UString& string)
     596            : m_data(string.data())
     597            , m_length(string.size())
     598        {
     599        }
     600
     601        unsigned length() { return m_length; }
     602
     603        void writeTo(UChar* destination)
     604        {
     605            for (unsigned i = 0; i < m_length; ++i)
     606                destination[i] = m_data[i];
     607        }
     608
     609    private:
     610        const UChar* m_data;
     611        unsigned m_length;
     612    };
     613
     614    template<typename StringType1, typename StringType2>
     615    UString makeString(StringType1 string1, StringType2 string2)
     616    {
     617        StringTypeAdapter<StringType1> adapter1(string1);
     618        StringTypeAdapter<StringType2> adapter2(string2);
     619
     620        UChar* buffer;
     621        unsigned length = adapter1.length() + adapter2.length();
     622        if (!tryFastMalloc(length * sizeof(UChar)).getValue(buffer))
     623            return UString();
     624
     625        UChar* result = buffer;
     626        adapter1.writeTo(result);
     627        result += adapter1.length();
     628        adapter2.writeTo(result);
     629
     630        return UString(buffer, length, false);
     631    }
     632
     633    template<typename StringType1, typename StringType2, typename StringType3>
     634    UString makeString(StringType1 string1, StringType2 string2, StringType3 string3)
     635    {
     636        StringTypeAdapter<StringType1> adapter1(string1);
     637        StringTypeAdapter<StringType2> adapter2(string2);
     638        StringTypeAdapter<StringType3> adapter3(string3);
     639
     640        UChar* buffer;
     641        unsigned length = adapter1.length() + adapter2.length() + adapter3.length();
     642        if (!tryFastMalloc(length * sizeof(UChar)).getValue(buffer))
     643            return UString();
     644
     645        UChar* result = buffer;
     646        adapter1.writeTo(result);
     647        result += adapter1.length();
     648        adapter2.writeTo(result);
     649        result += adapter2.length();
     650        adapter3.writeTo(result);
     651
     652        return UString(buffer, length, false);
     653    }
     654
     655    template<typename StringType1, typename StringType2, typename StringType3, typename StringType4>
     656    UString makeString(StringType1 string1, StringType2 string2, StringType3 string3, StringType4 string4)
     657    {
     658        StringTypeAdapter<StringType1> adapter1(string1);
     659        StringTypeAdapter<StringType2> adapter2(string2);
     660        StringTypeAdapter<StringType3> adapter3(string3);
     661        StringTypeAdapter<StringType4> adapter4(string4);
     662
     663        UChar* buffer;
     664        unsigned length = adapter1.length() + adapter2.length() + adapter3.length() + adapter4.length();
     665        if (!tryFastMalloc(length * sizeof(UChar)).getValue(buffer))
     666            return UString();
     667
     668        UChar* result = buffer;
     669        adapter1.writeTo(result);
     670        result += adapter1.length();
     671        adapter2.writeTo(result);
     672        result += adapter2.length();
     673        adapter3.writeTo(result);
     674        result += adapter3.length();
     675        adapter4.writeTo(result);
     676
     677        return UString(buffer, length, false);
     678    }
     679
     680    template<typename StringType1, typename StringType2, typename StringType3, typename StringType4, typename StringType5>
     681    UString makeString(StringType1 string1, StringType2 string2, StringType3 string3, StringType4 string4, StringType5 string5)
     682    {
     683        StringTypeAdapter<StringType1> adapter1(string1);
     684        StringTypeAdapter<StringType2> adapter2(string2);
     685        StringTypeAdapter<StringType3> adapter3(string3);
     686        StringTypeAdapter<StringType4> adapter4(string4);
     687        StringTypeAdapter<StringType5> adapter5(string5);
     688
     689        UChar* buffer;
     690        unsigned length = adapter1.length() + adapter2.length() + adapter3.length() + adapter4.length() + adapter5.length();
     691        if (!tryFastMalloc(length * sizeof(UChar)).getValue(buffer))
     692            return UString();
     693
     694        UChar* result = buffer;
     695        adapter1.writeTo(result);
     696        result += adapter1.length();
     697        adapter2.writeTo(result);
     698        result += adapter2.length();
     699        adapter3.writeTo(result);
     700        result += adapter3.length();
     701        adapter4.writeTo(result);
     702        result += adapter4.length();
     703        adapter5.writeTo(result);
     704
     705        return UString(buffer, length, false);
     706    }
     707
     708    template<typename StringType1, typename StringType2, typename StringType3, typename StringType4, typename StringType5, typename StringType6>
     709    UString makeString(StringType1 string1, StringType2 string2, StringType3 string3, StringType4 string4, StringType5 string5, StringType6 string6)
     710    {
     711        StringTypeAdapter<StringType1> adapter1(string1);
     712        StringTypeAdapter<StringType2> adapter2(string2);
     713        StringTypeAdapter<StringType3> adapter3(string3);
     714        StringTypeAdapter<StringType4> adapter4(string4);
     715        StringTypeAdapter<StringType5> adapter5(string5);
     716        StringTypeAdapter<StringType6> adapter6(string6);
     717
     718        UChar* buffer;
     719        unsigned length = adapter1.length() + adapter2.length() + adapter3.length() + adapter4.length() + adapter5.length() + adapter6.length();
     720        if (!tryFastMalloc(length * sizeof(UChar)).getValue(buffer))
     721            return UString();
     722
     723        UChar* result = buffer;
     724        adapter1.writeTo(result);
     725        result += adapter1.length();
     726        adapter2.writeTo(result);
     727        result += adapter2.length();
     728        adapter3.writeTo(result);
     729        result += adapter3.length();
     730        adapter4.writeTo(result);
     731        result += adapter4.length();
     732        adapter5.writeTo(result);
     733        result += adapter5.length();
     734        adapter6.writeTo(result);
     735
     736        return UString(buffer, length, false);
     737    }
     738
     739    template<typename StringType1, typename StringType2, typename StringType3, typename StringType4, typename StringType5, typename StringType6, typename StringType7>
     740    UString makeString(StringType1 string1, StringType2 string2, StringType3 string3, StringType4 string4, StringType5 string5, StringType6 string6, StringType7 string7)
     741    {
     742        StringTypeAdapter<StringType1> adapter1(string1);
     743        StringTypeAdapter<StringType2> adapter2(string2);
     744        StringTypeAdapter<StringType3> adapter3(string3);
     745        StringTypeAdapter<StringType4> adapter4(string4);
     746        StringTypeAdapter<StringType5> adapter5(string5);
     747        StringTypeAdapter<StringType6> adapter6(string6);
     748        StringTypeAdapter<StringType7> adapter7(string7);
     749
     750        UChar* buffer;
     751        unsigned length = adapter1.length() + adapter2.length() + adapter3.length() + adapter4.length() + adapter5.length() + adapter6.length() + adapter7.length();
     752        if (!tryFastMalloc(length * sizeof(UChar)).getValue(buffer))
     753            return UString();
     754
     755        UChar* result = buffer;
     756        adapter1.writeTo(result);
     757        result += adapter1.length();
     758        adapter2.writeTo(result);
     759        result += adapter2.length();
     760        adapter3.writeTo(result);
     761        result += adapter3.length();
     762        adapter4.writeTo(result);
     763        result += adapter4.length();
     764        adapter5.writeTo(result);
     765        result += adapter5.length();
     766        adapter6.writeTo(result);
     767        result += adapter6.length();
     768        adapter7.writeTo(result);
     769
     770        return UString(buffer, length, false);
     771    }
     772
     773    template<typename StringType1, typename StringType2, typename StringType3, typename StringType4, typename StringType5, typename StringType6, typename StringType7, typename StringType8>
     774    UString makeString(StringType1 string1, StringType2 string2, StringType3 string3, StringType4 string4, StringType5 string5, StringType6 string6, StringType7 string7, StringType8 string8)
     775    {
     776        StringTypeAdapter<StringType1> adapter1(string1);
     777        StringTypeAdapter<StringType2> adapter2(string2);
     778        StringTypeAdapter<StringType3> adapter3(string3);
     779        StringTypeAdapter<StringType4> adapter4(string4);
     780        StringTypeAdapter<StringType5> adapter5(string5);
     781        StringTypeAdapter<StringType6> adapter6(string6);
     782        StringTypeAdapter<StringType7> adapter7(string7);
     783        StringTypeAdapter<StringType8> adapter8(string8);
     784
     785        UChar* buffer;
     786        unsigned length = adapter1.length() + adapter2.length() + adapter3.length() + adapter4.length() + adapter5.length() + adapter6.length() + adapter7.length() + adapter8.length();
     787        if (!tryFastMalloc(length * sizeof(UChar)).getValue(buffer))
     788            return UString();
     789
     790        UChar* result = buffer;
     791        adapter1.writeTo(result);
     792        result += adapter1.length();
     793        adapter2.writeTo(result);
     794        result += adapter2.length();
     795        adapter3.writeTo(result);
     796        result += adapter3.length();
     797        adapter4.writeTo(result);
     798        result += adapter4.length();
     799        adapter5.writeTo(result);
     800        result += adapter5.length();
     801        adapter6.writeTo(result);
     802        result += adapter6.length();
     803        adapter7.writeTo(result);
     804        result += adapter7.length();
     805        adapter8.writeTo(result);
     806
     807        return UString(buffer, length, false);
     808    }
     809
    540810} // namespace JSC
    541811
Note: See TracChangeset for help on using the changeset viewer.