Changeset 52075 in webkit


Ignore:
Timestamp:
Dec 13, 2009 4:27:07 PM (14 years ago)
Author:
barraclough@apple.com
Message:

https://bugs.webkit.org/show_bug.cgi?id=32496
Switch remaining cases of string construction to use StringBuilder.
Builds strings using a vector rather than using string append / addition.

Reviewed by Sam Weinig.

(JSC::FunctionExecutable::paramString):

  • runtime/FunctionConstructor.cpp:

(JSC::constructFunction):

  • runtime/JSGlobalObjectFunctions.cpp:

(JSC::encode):
(JSC::decode):
(JSC::globalFuncEscape):
(JSC::globalFuncUnescape):

  • runtime/JSONObject.cpp:

(JSC::Stringifier::stringify):
(JSC::Stringifier::indent):

  • runtime/JSString.h:
  • runtime/LiteralParser.cpp:

(JSC::LiteralParser::Lexer::lexString):

  • runtime/NumberPrototype.cpp:

(JSC::integerPartNoExp):
(JSC::numberProtoFuncToFixed):
(JSC::numberProtoFuncToPrecision):

  • runtime/Operations.h:

(JSC::jsString):

  • runtime/StringPrototype.cpp:

(JSC::substituteBackreferencesSlow):
(JSC::substituteBackreferences):
(JSC::stringProtoFuncConcat):

Location:
trunk/JavaScriptCore
Files:
1 added
12 edited

Legend:

Unmodified
Added
Removed
  • trunk/JavaScriptCore/ChangeLog

    r52067 r52075  
     12009-12-13  Gavin Barraclough  <barraclough@apple.com>
     2
     3        Reviewed by Sam Weinig.
     4
     5        https://bugs.webkit.org/show_bug.cgi?id=32496
     6        Switch remaining cases of string construction to use StringBuilder.
     7        Builds strings using a vector rather than using string append / addition.
     8
     9        * JavaScriptCore.exp:
     10        * JavaScriptCore.xcodeproj/project.pbxproj:
     11        * runtime/Executable.cpp:
     12        (JSC::FunctionExecutable::paramString):
     13        * runtime/FunctionConstructor.cpp:
     14        (JSC::constructFunction):
     15        * runtime/JSGlobalObjectFunctions.cpp:
     16        (JSC::encode):
     17        (JSC::decode):
     18        (JSC::globalFuncEscape):
     19        (JSC::globalFuncUnescape):
     20        * runtime/JSONObject.cpp:
     21        (JSC::Stringifier::stringify):
     22        (JSC::Stringifier::indent):
     23        * runtime/JSString.h:
     24        * runtime/LiteralParser.cpp:
     25        (JSC::LiteralParser::Lexer::lexString):
     26        * runtime/NumberPrototype.cpp:
     27        (JSC::integerPartNoExp):
     28        (JSC::numberProtoFuncToFixed):
     29        (JSC::numberProtoFuncToPrecision):
     30        * runtime/Operations.h:
     31        (JSC::jsString):
     32        * runtime/StringPrototype.cpp:
     33        (JSC::substituteBackreferencesSlow):
     34        (JSC::substituteBackreferences):
     35        (JSC::stringProtoFuncConcat):
     36
    1372009-12-08  Jeremy Moskovich  <jeremy@chromium.org>
    238
  • trunk/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj

    r52047 r52075  
    205205                869083150E6518D7000D36ED /* WREC.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 869083130E6518D7000D36ED /* WREC.cpp */; };
    206206                869083160E6518D7000D36ED /* WREC.h in Headers */ = {isa = PBXBuildFile; fileRef = 869083140E6518D7000D36ED /* WREC.h */; settings = {ATTRIBUTES = (Private, ); }; };
     207                8698B86910D44D9400D8D01B /* StringBuilder.h in Headers */ = {isa = PBXBuildFile; fileRef = 8698B86810D44D9400D8D01B /* StringBuilder.h */; };
    207208                869EBCB70E8C6D4A008722CC /* ResultType.h in Headers */ = {isa = PBXBuildFile; fileRef = 869EBCB60E8C6D4A008722CC /* ResultType.h */; settings = {ATTRIBUTES = (Private, ); }; };
    208209                86A90ED00EE7D51F00AB350D /* JITArithmetic.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 86A90ECF0EE7D51F00AB350D /* JITArithmetic.cpp */; };
     
    729730                869083130E6518D7000D36ED /* WREC.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = WREC.cpp; sourceTree = "<group>"; };
    730731                869083140E6518D7000D36ED /* WREC.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = WREC.h; sourceTree = "<group>"; };
     732                8698B86810D44D9400D8D01B /* StringBuilder.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = StringBuilder.h; sourceTree = "<group>"; };
    731733                869EBCB60E8C6D4A008722CC /* ResultType.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ResultType.h; sourceTree = "<group>"; };
    732734                86A90ECF0EE7D51F00AB350D /* JITArithmetic.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = JITArithmetic.cpp; sourceTree = "<group>"; };
     
    15311533                                65C7A1710A8EAACB00FA37EA /* JSWrapperObject.cpp */,
    15321534                                65C7A1720A8EAACB00FA37EA /* JSWrapperObject.h */,
     1535                                A7C2216810C745E000F97913 /* JSZombie.h */,
     1536                                A7C2216B10C7469C00F97913 /* JSZombie.cpp */,
    15331537                                A7E2EA6A0FB460CF00601F06 /* LiteralParser.cpp */,
    15341538                                A7E2EA690FB460CF00601F06 /* LiteralParser.h */,
     
    15831587                                93303FE80E6A72B500786E6A /* SmallStrings.cpp */,
    15841588                                93303FEA0E6A72C000786E6A /* SmallStrings.h */,
     1589                                8698B86810D44D9400D8D01B /* StringBuilder.h */,
    15851590                                BC18C3C00E16EE3300B34460 /* StringConstructor.cpp */,
    15861591                                BC18C3C10E16EE3300B34460 /* StringConstructor.h */,
     
    16031608                                F692A8860255597D01FF60F7 /* UString.h */,
    16041609                                1420BE7A10AA6DDB00F455D2 /* WeakRandom.h */,
    1605                                 A7C2216810C745E000F97913 /* JSZombie.h */,
    1606                                 A7C2216B10C7469C00F97913 /* JSZombie.cpp */,
    16071610                        );
    16081611                        path = runtime;
     
    20152018                                14A1563210966365006FA260 /* DateInstanceCache.h in Headers */,
    20162019                                1420BE7B10AA6DDB00F455D2 /* WeakRandom.h in Headers */,
     2020                                8698B86910D44D9400D8D01B /* StringBuilder.h in Headers */,
    20172021                        );
    20182022                        runOnlyForDeploymentPostprocessing = 0;
  • trunk/JavaScriptCore/runtime/Executable.cpp

    r48662 r52075  
    3131#include "JIT.h"
    3232#include "Parser.h"
     33#include "StringBuilder.h"
    3334#include "Vector.h"
    3435
     
    266267{
    267268    FunctionParameters& parameters = *m_parameters;
    268     UString s("");
     269    StringBuilder builder;
    269270    for (size_t pos = 0; pos < parameters.size(); ++pos) {
    270         if (!s.isEmpty())
    271             s += ", ";
    272         s += parameters[pos].ustring();
     271        if (!builder.isEmpty())
     272            builder.append(", ");
     273        builder.append(parameters[pos].ustring());
    273274    }
    274 
    275     return s;
     275    return builder.release();
    276276}
    277277
  • trunk/JavaScriptCore/runtime/FunctionConstructor.cpp

    r48836 r52075  
    2222#include "FunctionConstructor.h"
    2323
     24#include "Debugger.h"
    2425#include "FunctionPrototype.h"
    2526#include "JSFunction.h"
    2627#include "JSGlobalObject.h"
    2728#include "JSString.h"
    28 #include "Parser.h"
    29 #include "Debugger.h"
    3029#include "Lexer.h"
    3130#include "Nodes.h"
     31#include "Parser.h"
     32#include "StringBuilder.h"
    3233
    3334namespace JSC {
     
    7778        program = "(function() { \n})";
    7879    else if (args.size() == 1)
    79         program = "(function() { " + args.at(0).toString(exec) + "\n})";
     80        program = makeString("(function() { ", args.at(0).toString(exec), "\n})");
    8081    else {
    81         program = "(function(" + args.at(0).toString(exec);
    82         for (size_t i = 1; i < args.size() - 1; i++)
    83             program += "," + args.at(i).toString(exec);
    84         program += ") { " + args.at(args.size() - 1).toString(exec) + "\n})";
     82        StringBuilder builder;
     83        builder.append("(function(");
     84        builder.append(args.at(0).toString(exec));
     85        for (size_t i = 1; i < args.size() - 1; i++) {
     86            builder.append(",");
     87            builder.append(args.at(i).toString(exec));
     88        }
     89        builder.append(") { ");
     90        builder.append(args.at(args.size() - 1).toString(exec));
     91        builder.append("\n})");
     92        program = builder.release();
    8593    }
    8694
  • trunk/JavaScriptCore/runtime/JSGlobalObjectFunctions.cpp

    r48905 r52075  
    2828#include "CallFrame.h"
    2929#include "GlobalEvalFunction.h"
     30#include "Interpreter.h"
    3031#include "JSGlobalObject.h"
     32#include "JSString.h"
     33#include "Lexer.h"
    3134#include "LiteralParser.h"
    32 #include "JSString.h"
    33 #include "Interpreter.h"
     35#include "Nodes.h"
    3436#include "Parser.h"
     37#include "StringBuilder.h"
    3538#include "dtoa.h"
    36 #include "Lexer.h"
    37 #include "Nodes.h"
    3839#include <stdio.h>
    3940#include <stdlib.h>
     
    5657        return throwError(exec, URIError, "String contained an illegal UTF-16 sequence.");
    5758
    58     UString result = "";
     59    StringBuilder builder;
    5960    const char* p = cstr.c_str();
    6061    for (size_t k = 0; k < cstr.size(); k++, p++) {
    6162        char c = *p;
    6263        if (c && strchr(doNotEscape, c))
    63             result.append(c);
     64            builder.append(c);
    6465        else {
    6566            char tmp[4];
    66             sprintf(tmp, "%%%02X", static_cast<unsigned char>(c));
    67             result += tmp;
    68         }
    69     }
    70     return jsString(exec, result);
     67            snprintf(tmp, 4, "%%%02X", static_cast<unsigned char>(c));
     68            builder.append((const char*)tmp);
     69        }
     70    }
     71    return jsString(exec, builder.release());
    7172}
    7273
    7374static JSValue decode(ExecState* exec, const ArgList& args, const char* doNotUnescape, bool strict)
    7475{
    75     UString result = "";
     76    StringBuilder builder;
    7677    UString str = args.at(0).toString(exec);
    7778    int k = 0;
     
    107108                        else if (character >= 0x10000) {
    108109                            // Convert to surrogate pair.
    109                             result.append(static_cast<UChar>(0xD800 | ((character - 0x10000) >> 10)));
     110                            builder.append(static_cast<UChar>(0xD800 | ((character - 0x10000) >> 10)));
    110111                            u = static_cast<UChar>(0xDC00 | ((character - 0x10000) & 0x3FF));
    111112                        } else
     
    132133        }
    133134        k++;
    134         result.append(c);
    135     }
    136     return jsString(exec, result);
     135        builder.append(c);
     136    }
     137    return jsString(exec, builder.release());
    137138}
    138139
     
    377378        "*+-./@_";
    378379
    379     UString result = "";
     380    StringBuilder builder;
    380381    UString s;
    381382    UString str = args.at(0).toString(exec);
     
    394395            s = UString(tmp);
    395396        }
    396         result += s;
    397     }
    398 
    399     return jsString(exec, result);
     397        builder.append(s);
     398    }
     399
     400    return jsString(exec, builder.release());
    400401}
    401402
    402403JSValue JSC_HOST_CALL globalFuncUnescape(ExecState* exec, JSObject*, JSValue, const ArgList& args)
    403404{
    404     UString result = "";
     405    StringBuilder builder;
    405406    UString str = args.at(0).toString(exec);
    406407    int k = 0;
     
    421422        }
    422423        k++;
    423         result.append(*c);
    424     }
    425 
    426     return jsString(exec, result);
     424        builder.append(*c);
     425    }
     426
     427    return jsString(exec, builder.release());
    427428}
    428429
  • trunk/JavaScriptCore/runtime/JSONObject.cpp

    r51801 r52075  
    3333#include "LiteralParser.h"
    3434#include "PropertyNameArray.h"
     35#include "StringBuilder.h"
    3536#include <wtf/MathExtras.h>
    3637
     
    7172
    7273private:
    73     class StringBuilder : public Vector<UChar> {
    74     public:
    75         using Vector<UChar>::append;
    76 
    77         inline void append(const char* str)
    78         {
    79             size_t len = strlen(str);
    80             reserveCapacity(size() + len);
    81             for (size_t i = 0; i < len; i++)
    82                 Vector<UChar>::append(str[i]);
    83         }
    84 
    85         inline void append(const UString& str)
    86         {
    87             append(str.data(), str.size());
    88         }
    89     };
    90 
    9174    class Holder {
    9275    public:
     
    286269        return jsNull();
    287270
    288     result.shrinkToFit();
    289     size_t length = result.size();
    290     return jsString(m_exec, UString(result.releaseBuffer(), length, false));
     271    return jsString(m_exec, result.release());
    291272}
    292273
     
    478459    int newSize = m_indent.size() + m_gap.size();
    479460    if (newSize > m_repeatedGap.size())
    480         m_repeatedGap.append(m_gap);
     461        m_repeatedGap = makeString(m_repeatedGap, m_gap);
    481462    ASSERT(newSize <= m_repeatedGap.size());
    482463    m_indent = m_repeatedGap.substr(0, newSize);
  • trunk/JavaScriptCore/runtime/JSString.h

    r52047 r52075  
    346346        friend JSValue jsString(ExecState* exec, JSString* s1, const UString& u2);
    347347        friend JSValue jsString(ExecState* exec, Register* strings, unsigned count);
     348        friend JSValue jsString(ExecState* exec, JSValue thisValue, const ArgList& args);
    348349    };
    349350
  • trunk/JavaScriptCore/runtime/LiteralParser.cpp

    r47828 r52075  
    3030#include "JSString.h"
    3131#include "Lexer.h"
     32#include "StringBuilder.h"
    3233#include <wtf/ASCIICType.h>
    3334#include <wtf/dtoa.h>
     
    135136    ++m_ptr;
    136137    const UChar* runStart;
    137     token.stringToken = UString();
     138    StringBuilder builder;
    138139    do {
    139140        runStart = m_ptr;
     
    141142            ++m_ptr;
    142143        if (runStart < m_ptr)
    143             token.stringToken.append(runStart, m_ptr - runStart);
     144            builder.append(runStart, m_ptr - runStart);
    144145        if ((mode == StrictJSON) && m_ptr < m_end && *m_ptr == '\\') {
    145146            ++m_ptr;
     
    148149            switch (*m_ptr) {
    149150                case '"':
    150                     token.stringToken.append('"');
     151                    builder.append('"');
    151152                    m_ptr++;
    152153                    break;
    153154                case '\\':
    154                     token.stringToken.append('\\');
     155                    builder.append('\\');
    155156                    m_ptr++;
    156157                    break;
    157158                case '/':
    158                     token.stringToken.append('/');
     159                    builder.append('/');
    159160                    m_ptr++;
    160161                    break;
    161162                case 'b':
    162                     token.stringToken.append('\b');
     163                    builder.append('\b');
    163164                    m_ptr++;
    164165                    break;
    165166                case 'f':
    166                     token.stringToken.append('\f');
     167                    builder.append('\f');
    167168                    m_ptr++;
    168169                    break;
    169170                case 'n':
    170                     token.stringToken.append('\n');
     171                    builder.append('\n');
    171172                    m_ptr++;
    172173                    break;
    173174                case 'r':
    174                     token.stringToken.append('\r');
     175                    builder.append('\r');
    175176                    m_ptr++;
    176177                    break;
    177178                case 't':
    178                     token.stringToken.append('\t');
     179                    builder.append('\t');
    179180                    m_ptr++;
    180181                    break;
     
    187188                            return TokError;
    188189                    }
    189                     token.stringToken.append(JSC::Lexer::convertUnicode(m_ptr[1], m_ptr[2], m_ptr[3], m_ptr[4]));
     190                    builder.append(JSC::Lexer::convertUnicode(m_ptr[1], m_ptr[2], m_ptr[3], m_ptr[4]));
    190191                    m_ptr += 5;
    191192                    break;
     
    200201        return TokError;
    201202
     203    token.stringToken = builder.release();
    202204    token.type = TokString;
    203205    token.end = ++m_ptr;
  • trunk/JavaScriptCore/runtime/NumberPrototype.cpp

    r49335 r52075  
    2626#include "JSFunction.h"
    2727#include "JSString.h"
     28#include "Operations.h"
    2829#include "PrototypeFunction.h"
     30#include "StringBuilder.h"
    2931#include "dtoa.h"
    30 #include "Operations.h"
    3132#include <wtf/Assertions.h>
    3233#include <wtf/MathExtras.h>
     
    7475    size_t length = strlen(result);
    7576
    76     UString str = sign ? "-" : "";
     77    StringBuilder builder;
     78    builder.append(sign ? "-" : "");
    7779    if (resultIsInfOrNan)
    78         str += result;
     80        builder.append((const char*)result);
    7981    else if (decimalPoint <= 0)
    80         str += "0";
     82        builder.append("0");
    8183    else {
    8284        Vector<char, 1024> buf(decimalPoint + 1);
     
    9092        buf[decimalPoint] = '\0';
    9193
    92         str.append(buf.data());
    93     }
    94 
    95     return str;
     94        builder.append((const char*)(buf.data()));
     95    }
     96
     97    return builder.release();
    9698}
    9799
     
    237239    UString s;
    238240    if (x < 0) {
    239         s.append('-');
     241        s = "-";
    240242        x = -x;
    241     } else if (x == -0.0)
    242         x = 0;
     243    } else {
     244        s = "";
     245        if (x == -0.0)
     246            x = 0;
     247    }
    243248
    244249    if (x >= pow(10.0, 21.0))
    245         return jsString(exec, s + UString::from(x));
     250        return jsString(exec, makeString(s, UString::from(x)));
    246251
    247252    const double tenToTheF = pow(10.0, f);
     
    254259    int k = m.size();
    255260    if (k <= f) {
    256         UString z;
     261        StringBuilder z;
    257262        for (int i = 0; i < f + 1 - k; i++)
    258263            z.append('0');
    259         m = z + m;
     264        z.append(m);
     265        m = z.release();
    260266        k = f + 1;
    261267        ASSERT(k == m.size());
    262268    }
    263269    int kMinusf = k - f;
     270
    264271    if (kMinusf < m.size())
    265         return jsString(exec, s + m.substr(0, kMinusf) + "." + m.substr(kMinusf));
    266     return jsString(exec, s + m.substr(0, kMinusf));
     272        return jsString(exec, makeString(s, m.substr(0, kMinusf), ".", m.substr(kMinusf)));
     273    return jsString(exec, makeString(s, m.substr(0, kMinusf)));
    267274}
    268275
     
    392399        s = "-";
    393400        x = -x;
    394     }
     401    } else
     402        s = "";
    395403
    396404    if (!(doublePrecision >= 1 && doublePrecision <= 21)) // true for NaN
     
    423431        if (e < -6 || e >= precision) {
    424432            if (m.size() > 1)
    425                 m = m.substr(0, 1) + "." + m.substr(1);
     433                m = makeString(m.substr(0, 1), ".", m.substr(1));
    426434            if (e >= 0)
    427                 return jsNontrivialString(exec, s + m + "e+" + UString::from(e));
    428             return jsNontrivialString(exec, s + m + "e-" + UString::from(-e));
     435                return jsNontrivialString(exec, makeString(s, m, "e+", UString::from(e)));
     436            return jsNontrivialString(exec, makeString(s, m, "e-", UString::from(-e)));
    429437        }
    430438    } else {
     
    434442
    435443    if (e == precision - 1)
    436         return jsString(exec, s + m);
     444        return jsString(exec, makeString(s, m));
    437445    if (e >= 0) {
    438446        if (e + 1 < m.size())
    439             return jsString(exec, s + m.substr(0, e + 1) + "." + m.substr(e + 1));
    440         return jsString(exec, s + m);
    441     }
    442     return jsNontrivialString(exec, s + "0." + charSequence('0', -(e + 1)) + m);
     447            return jsString(exec, makeString(s, m.substr(0, e + 1), ".", m.substr(e + 1)));
     448        return jsString(exec, makeString(s, m));
     449    }
     450    return jsNontrivialString(exec, makeString(s, "0.", charSequence('0', -(e + 1)), m));
    443451}
    444452
  • trunk/JavaScriptCore/runtime/Operations.h

    r52026 r52075  
    129129    }
    130130
     131    ALWAYS_INLINE JSValue jsString(ExecState* exec, JSValue thisValue, const ArgList& args)
     132    {
     133        unsigned ropeLength = 0;
     134        if (LIKELY(thisValue.isString()))
     135            ropeLength += asString(thisValue)->ropeLength();
     136        else
     137            ++ropeLength;
     138        for (unsigned i = 0; i < args.size(); ++i) {
     139            JSValue v = args.at(i);
     140            if (LIKELY(v.isString()))
     141                ropeLength += asString(v)->ropeLength();
     142            else
     143                ++ropeLength;
     144        }
     145
     146        RefPtr<JSString::Rope> rope = JSString::Rope::createOrNull(ropeLength);
     147        if (UNLIKELY(!rope))
     148            return throwOutOfMemoryError(exec);
     149
     150        unsigned index = 0;
     151        if (LIKELY(thisValue.isString()))
     152            rope->append(index, asString(thisValue));
     153        else
     154            rope->append(index, thisValue.toString(exec));
     155        for (unsigned i = 0; i < args.size(); ++i) {
     156            JSValue v = args.at(i);
     157            if (LIKELY(v.isString()))
     158                rope->append(index, asString(v));
     159            else
     160                rope->append(index, v.toString(exec));
     161        }
     162        ASSERT(index == ropeLength);
     163
     164        JSGlobalData* globalData = &exec->globalData();
     165        return new (globalData) JSString(globalData, rope.release());
     166    }
     167
    131168    // ECMA 11.9.3
    132169    inline bool JSValue::equal(ExecState* exec, JSValue v1, JSValue v2)
  • trunk/JavaScriptCore/runtime/StringPrototype.cpp

    r52028 r52075  
    3030#include "JSFunction.h"
    3131#include "ObjectPrototype.h"
     32#include "Operations.h"
    3233#include "PropertyNameArray.h"
    3334#include "RegExpConstructor.h"
     
    149150// ------------------------------ Functions --------------------------
    150151
    151 static inline UString substituteBackreferences(const UString& replacement, const UString& source, const int* ovector, RegExp* reg)
    152 {
    153     UString substitutedReplacement;
     152static NEVER_INLINE UString substituteBackreferencesSlow(const UString& replacement, const UString& source, const int* ovector, RegExp* reg, int i)
     153{
     154    Vector<UChar> substitutedReplacement;
    154155    int offset = 0;
    155     int i = -1;
    156     while ((i = replacement.find('$', i + 1)) != -1) {
     156    do {
    157157        if (i + 1 == replacement.size())
    158158            break;
     
    206206        offset = i + 1;
    207207        substitutedReplacement.append(source.data() + backrefStart, backrefLength);
    208     }
    209 
    210     if (!offset)
    211         return replacement;
     208    } while ((i = replacement.find('$', i + 1)) != -1);
    212209
    213210    if (replacement.size() - offset)
    214211        substitutedReplacement.append(replacement.data() + offset, replacement.size() - offset);
    215212
    216     return substitutedReplacement;
     213    substitutedReplacement.shrinkToFit();
     214    unsigned size = substitutedReplacement.size();
     215    return UString(substitutedReplacement.releaseBuffer(), size, false);
     216}
     217
     218static inline UString substituteBackreferences(const UString& replacement, const UString& source, const int* ovector, RegExp* reg)
     219{
     220    int i = replacement.find('$', 0);
     221    if (UNLIKELY(i != -1))
     222        return substituteBackreferencesSlow(replacement, source, ovector, reg, i);
     223    return replacement;
    217224}
    218225
     
    424431JSValue JSC_HOST_CALL stringProtoFuncConcat(ExecState* exec, JSObject*, JSValue thisValue, const ArgList& args)
    425432{
    426     UString s = thisValue.toThisString(exec);
    427 
    428     ArgList::const_iterator end = args.end();
    429     for (ArgList::const_iterator it = args.begin(); it != end; ++it)
    430         s += (*it).toString(exec);
    431     return jsString(exec, s);
     433    if (thisValue.isString() && (args.size() == 1)) {
     434        JSValue v = args.at(0);
     435        return v.isString()
     436            ? jsString(exec, asString(thisValue), asString(v))
     437            : jsString(exec, asString(thisValue), v.toString(exec));
     438    }
     439
     440    return jsString(exec, thisValue, args);
    432441}
    433442
  • trunk/JavaScriptCore/runtime/UString.h

    r52047 r52075  
    544544
    545545    template<>
    546     class StringTypeAdapter<char*>
    547     {
     546    class StringTypeAdapter<char*> {
    548547    public:
    549548        StringTypeAdapter<char*>(char* buffer)
     
    567566
    568567    template<>
    569     class StringTypeAdapter<const char*>
    570     {
     568    class StringTypeAdapter<const char*> {
    571569    public:
    572570        StringTypeAdapter<const char*>(const char* buffer)
     
    590588
    591589    template<>
    592     class StringTypeAdapter<UString>
    593     {
     590    class StringTypeAdapter<UString> {
    594591    public:
    595592        StringTypeAdapter<UString>(UString& string)
Note: See TracChangeset for help on using the changeset viewer.