Ignore:
Timestamp:
Jun 26, 2008, 7:53:42 PM (17 years ago)
Author:
Darin Adler
Message:

2008-06-26 Darin Adler <Darin Adler>

Reviewed by Geoff.

  • optimize UString append and the replace function a bit

SunSpider says 1.8% faster.

  • VM/JSPropertyNameIterator.cpp: Added include of JSString.h, now needed because jsString returns a JSString*.
  • VM/Machine.cpp: (KJS::Machine::privateExecute): Removed the toObject call from native function calls. Also removed code to put the this value into a register.
  • kjs/BooleanObject.cpp: (KJS::booleanProtoFuncToString): Rewrite to handle false and true separately.
  • kjs/FunctionPrototype.cpp: (KJS::constructFunction): Use single-character append rather than building a string for each character.
  • kjs/JSFunction.cpp: (KJS::globalFuncUnescape): Ditto.
  • kjs/JSImmediate.cpp: (KJS::JSImmediate::prototype): Added. Gets the appropriate prototype for use with an immediate value. To be used instead of toObject when doing a get on an immediate value.
  • kjs/JSImmediate.h: Added prototype.
  • kjs/JSObject.cpp: (KJS::JSObject::toString): Tweaked formatting.
  • kjs/JSObject.h: (KJS::JSValue::get): Use prototype instead of toObject to avoid creating an object wrapper just to search for properties. This also saves an unnecessary hash table lookup since the object wrappers themselves don't have any properties.
  • kjs/JSString.h: Added toThisString and toThisJSString.
  • kjs/JSValue.cpp: (KJS::JSCell::toThisString): Added. (KJS::JSCell::toThisJSString): Added. (KJS::JSCell::getJSNumber): Added. (KJS::jsString): Changed return type to JSString*. (KJS::jsOwnedString): Ditto.
  • kjs/JSValue.h: (KJS::JSValue::toThisString): Added. (KJS::JSValue::toThisJSString): Added. (KJS::JSValue::getJSNumber): Added.
  • kjs/NumberObject.cpp: (KJS::NumberObject::getJSNumber): Added. (KJS::integer_part_noexp): Append C string directly rather than first turning it into a UString. (KJS::numberProtoFuncToString): Use getJSNumber to check if the value is a number rather than isObject(&NumberObject::info). This works for immediate numbers, number cells, and NumberObject instances. (KJS::numberProtoFuncToLocaleString): Ditto. (KJS::numberProtoFuncValueOf): Ditto. (KJS::numberProtoFuncToFixed): Ditto. (KJS::numberProtoFuncToExponential): Ditto. (KJS::numberProtoFuncToPrecision): Ditto.
  • kjs/NumberObject.h: Added getJSNumber.
  • kjs/PropertySlot.cpp: Tweaked comment.
  • kjs/internal.cpp: (KJS::JSString::toThisString): Added. (KJS::JSString::toThisJSString): Added. (KJS::JSString::getOwnPropertySlot): Changed code that searches the prototype chain to start with the string prototype and not create a string object. (KJS::JSNumberCell::toThisString): Added. (KJS::JSNumberCell::getJSNumber): Added.
  • kjs/lookup.cpp: (KJS::staticFunctionGetter): Moved here, because there's no point in having a function that's only used for a function pointer be inline. (KJS::setUpStaticFunctionSlot): New function for getStaticFunctionSlot.
  • kjs/lookup.h: (KJS::staticValueGetter): Don't mark this inline. It doesn't make sense to have a function that's only used for a function pointer be inline. (KJS::getStaticFunctionSlot): Changed to get properties from the parent first before doing any handling of functions. This is the fastest way to return the function once the initial setup is done.
  • kjs/string_object.cpp: (KJS::StringObject::getPropertyNames): Call value() instead of getString(), avoiding an unnecessary virtual function call (the call to the type() function in the implementation of the isString() function). (KJS::StringObject::toString): Added. (KJS::StringObject::toThisString): Added. (KJS::StringObject::toThisJSString): Added. (KJS::substituteBackreferences): Rewrote to use a appending algorithm instead of a the old one that tried to replace in place. (KJS::stringProtoFuncReplace): Merged this function and the replace function. Replaced the hand-rolled dynamic arrays for source ranges and replacements with Vector. (KJS::stringProtoFuncToString): Handle JSString as well as StringObject. Removed the separate valueOf implementation, since it can just share this. (KJS::stringProtoFuncCharAt): Use toThisString, which handles JSString as well as StringObject, and is slightly more efficient than the old code too. (KJS::stringProtoFuncCharCodeAt): Ditto. (KJS::stringProtoFuncConcat): Ditto. (KJS::stringProtoFuncIndexOf): Ditto. (KJS::stringProtoFuncLastIndexOf): Ditto. (KJS::stringProtoFuncMatch): Ditto. (KJS::stringProtoFuncSearch): Ditto. (KJS::stringProtoFuncSlice): Ditto. (KJS::stringProtoFuncSplit): Ditto. (KJS::stringProtoFuncSubstr): Ditto. (KJS::stringProtoFuncSubstring): Ditto. (KJS::stringProtoFuncToLowerCase): Use toThisJSString. (KJS::stringProtoFuncToUpperCase): Ditto. (KJS::stringProtoFuncToLocaleLowerCase): Ditto. (KJS::stringProtoFuncToLocaleUpperCase): Ditto. (KJS::stringProtoFuncLocaleCompare): Ditto. (KJS::stringProtoFuncBig): Use toThisString. (KJS::stringProtoFuncSmall): Ditto. (KJS::stringProtoFuncBlink): Ditto. (KJS::stringProtoFuncBold): Ditto. (KJS::stringProtoFuncFixed): Ditto. (KJS::stringProtoFuncItalics): Ditto. (KJS::stringProtoFuncStrike): Ditto. (KJS::stringProtoFuncSub): Ditto. (KJS::stringProtoFuncSup): Ditto. (KJS::stringProtoFuncFontcolor): Ditto. (KJS::stringProtoFuncFontsize): Ditto. (KJS::stringProtoFuncAnchor): Ditto. (KJS::stringProtoFuncLink): Ditto.
  • kjs/string_object.h: Added toString, toThisString, and toThisJSString.
  • kjs/ustring.cpp: (KJS::UString::append): Added a version that takes a character pointer and size, so we don't have to create a UString just to append to another UString.
  • kjs/ustring.h:
File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/JavaScriptCore/kjs/string_object.cpp

    r34754 r34821  
    3737
    3838static JSValue* stringProtoFuncToString(ExecState*, JSObject*, JSValue*, const ArgList&);
    39 static JSValue* stringProtoFuncValueOf(ExecState*, JSObject*, JSValue*, const ArgList&);
    4039static JSValue* stringProtoFuncCharAt(ExecState*, JSObject*, JSValue*, const ArgList&);
    4140static JSValue* stringProtoFuncCharCodeAt(ExecState*, JSObject*, JSValue*, const ArgList&);
     
    128127void StringObject::getPropertyNames(ExecState* exec, PropertyNameArray& propertyNames)
    129128{
    130   int size = internalValue()->getString().size();
     129  int size = internalValue()->value().size();
    131130  for (int i = 0; i < size; i++)
    132131    propertyNames.add(Identifier(exec, UString::from(i)));
    133132  return JSObject::getPropertyNames(exec, propertyNames);
     133}
     134
     135UString StringObject::toString(ExecState*) const
     136{
     137    return internalValue()->value();
     138}
     139
     140UString StringObject::toThisString(ExecState*) const
     141{
     142    return internalValue()->value();
     143}
     144
     145JSString* StringObject::toThisJSString(ExecState*)
     146{
     147    return internalValue();
    134148}
    135149
     
    139153@begin stringTable 26
    140154  toString              stringProtoFuncToString          DontEnum|Function       0
    141   valueOf               stringProtoFuncValueOf           DontEnum|Function       0
     155  valueOf               stringProtoFuncToString          DontEnum|Function       0
    142156  charAt                stringProtoFuncCharAt            DontEnum|Function       1
    143157  charCodeAt            stringProtoFuncCharCodeAt        DontEnum|Function       1
     
    188202// ------------------------------ Functions --------------------------
    189203
    190 static inline void expandSourceRanges(UString::Range * & array, int& count, int& capacity)
    191 {
    192   int newCapacity;
    193   if (capacity == 0) {
    194     newCapacity = 16;
    195   } else {
    196     newCapacity = capacity * 2;
    197   }
    198 
    199   UString::Range *newArray = new UString::Range[newCapacity];
    200   for (int i = 0; i < count; i++) {
    201     newArray[i] = array[i];
    202   }
    203 
    204   delete [] array;
    205 
    206   capacity = newCapacity;
    207   array = newArray;
    208 }
    209 
    210 static void pushSourceRange(UString::Range * & array, int& count, int& capacity, UString::Range range)
    211 {
    212   if (count + 1 > capacity)
    213     expandSourceRanges(array, count, capacity);
    214 
    215   array[count] = range;
    216   count++;
    217 }
    218 
    219 static inline void expandReplacements(UString * & array, int& count, int& capacity)
    220 {
    221   int newCapacity;
    222   if (capacity == 0) {
    223     newCapacity = 16;
    224   } else {
    225     newCapacity = capacity * 2;
    226   }
    227 
    228   UString *newArray = new UString[newCapacity];
    229   for (int i = 0; i < count; i++) {
    230     newArray[i] = array[i];
    231   }
    232  
    233   delete [] array;
    234 
    235   capacity = newCapacity;
    236   array = newArray;
    237 }
    238 
    239 static void pushReplacement(UString * & array, int& count, int& capacity, UString replacement)
    240 {
    241   if (count + 1 > capacity)
    242     expandReplacements(array, count, capacity);
    243 
    244   array[count] = replacement;
    245   count++;
    246 }
    247 
    248 static inline UString substituteBackreferences(const UString &replacement, const UString &source, int *ovector, RegExp *reg)
    249 {
    250   UString substitutedReplacement = replacement;
    251 
     204static inline UString substituteBackreferences(const UString& replacement, const UString& source, const int* ovector, RegExp* reg)
     205{
     206  UString substitutedReplacement;
     207  int offset = 0;
    252208  int i = -1;
    253   while ((i = substitutedReplacement.find(UString("$"), i + 1)) != -1) {
    254     if (i+1 == substitutedReplacement.size())
     209  while ((i = replacement.find('$', i + 1)) != -1) {
     210    if (i + 1 == replacement.size())
    255211        break;
    256212
    257     unsigned short ref = substitutedReplacement[i+1];
    258     int backrefStart = 0;
    259     int backrefLength = 0;
     213    unsigned short ref = replacement[i + 1];
     214    if (ref == '$') {
     215        // "$$" -> "$"
     216        ++i;
     217        substitutedReplacement.append(replacement.data() + offset, i - offset);
     218        offset = i + 1;
     219        substitutedReplacement.append('$');
     220        continue;
     221    }
     222
     223    int backrefStart;
     224    int backrefLength;
    260225    int advance = 0;
    261 
    262     if (ref == '$') {  // "$$" -> "$"
    263         substitutedReplacement = substitutedReplacement.substr(0, i + 1) + substitutedReplacement.substr(i + 2);
    264         continue;
    265     } else if (ref == '&') {
     226    if (ref == '&') {
    266227        backrefStart = ovector[0];
    267228        backrefLength = ovector[1] - backrefStart;
     
    277238        if (backrefIndex > reg->numSubpatterns())
    278239            continue;
    279         if (substitutedReplacement.size() > i + 2) {
    280             ref = substitutedReplacement[i+2];
     240        if (replacement.size() > i + 2) {
     241            ref = replacement[i + 2];
    281242            if (ref >= '0' && ref <= '9') {
    282243                backrefIndex = 10 * backrefIndex + ref - '0';
     
    292253        continue;
    293254
    294     substitutedReplacement = substitutedReplacement.substr(0, i) + source.substr(backrefStart, backrefLength) + substitutedReplacement.substr(i + 2 + advance);
    295     i += backrefLength - 1; // - 1 offsets 'i + 1'
     255    if (i - offset)
     256        substitutedReplacement.append(replacement.data() + offset, i - offset);
     257    i += 1 + advance;
     258    offset = i + 1;
     259    substitutedReplacement.append(source.data() + backrefStart, backrefLength);
    296260  }
    297261
     262  if (!offset)
     263    return replacement;
     264
     265  if (replacement.size() - offset)
     266    substitutedReplacement.append(replacement.data() + offset, replacement.size() - offset);
     267
    298268  return substitutedReplacement;
    299269}
     
    304274}
    305275
    306 static JSValue *replace(ExecState *exec, JSString* sourceVal, JSValue *pattern, JSValue *replacement)
    307 {
    308   UString source = sourceVal->value();
     276JSValue* stringProtoFuncReplace(ExecState* exec, JSObject*, JSValue* thisValue, const ArgList& args)
     277{
     278  JSString* sourceVal = thisValue->toThisJSString(exec);
     279  const UString& source = sourceVal->value();
     280
     281  JSValue* pattern = args[0];
     282
     283  JSValue* replacement = args[1];
     284  UString replacementString;
    309285  CallData callData;
    310   UString replacementString;
    311 
    312286  CallType callType = replacement->getCallData(callData);
    313287  if (callType == CallTypeNone)
    314288    replacementString = replacement->toString(exec);
    315289
    316   if (pattern->isObject() && static_cast<JSObject *>(pattern)->inherits(&RegExpObject::info)) {
    317     RegExp *reg = static_cast<RegExpObject *>(pattern)->regExp();
     290  if (pattern->isObject(&RegExpObject::info)) {
     291    RegExp* reg = static_cast<RegExpObject*>(pattern)->regExp();
    318292    bool global = reg->global();
    319293
    320     RegExpConstructor* regExpObj = static_cast<RegExpConstructor*>(exec->lexicalGlobalObject()->regExpConstructor());
     294    RegExpConstructor* regExpObj = exec->lexicalGlobalObject()->regExpConstructor();
    321295
    322296    int lastIndex = 0;
    323297    int startPosition = 0;
    324298
    325     UString::Range *sourceRanges = 0;
    326     int sourceRangeCount = 0;
    327     int sourceRangeCapacity = 0;
    328     UString *replacements = 0;
    329     int replacementCount = 0;
    330     int replacementCapacity = 0;
     299    Vector<UString::Range, 16> sourceRanges;
     300    Vector<UString, 16> replacements;
    331301
    332302    // This is either a loop (if global is set) or a one-way (if not).
     
    339309        break;
    340310
    341       pushSourceRange(sourceRanges, sourceRangeCount, sourceRangeCapacity, UString::Range(lastIndex, matchIndex - lastIndex));
    342 
    343       UString substitutedReplacement;
     311      sourceRanges.append(UString::Range(lastIndex, matchIndex - lastIndex));
     312
    344313      if (callType != CallTypeNone) {
    345314          int completeMatchStart = ovector[0];
     
    359328          args.append(sourceVal);
    360329
    361           substitutedReplacement = call(exec, replacement, callType, callData, exec->globalThisValue(), args)->toString(exec);
     330          replacements.append(call(exec, replacement, callType, callData, exec->globalThisValue(), args)->toString(exec));
    362331      } else
    363           substitutedReplacement = substituteBackreferences(replacementString, source, ovector, reg);
    364 
    365       pushReplacement(replacements, replacementCount, replacementCapacity, substitutedReplacement);
     332          replacements.append(substituteBackreferences(replacementString, source, ovector, reg));
    366333
    367334      lastIndex = matchIndex + matchLen;
     
    377344
    378345    if (lastIndex < source.size())
    379       pushSourceRange(sourceRanges, sourceRangeCount, sourceRangeCapacity, UString::Range(lastIndex, source.size() - lastIndex));
    380 
    381     UString result;
    382 
    383     if (sourceRanges)
    384         result = source.spliceSubstringsWithSeparators(sourceRanges, sourceRangeCount, replacements, replacementCount);
    385 
    386     delete [] sourceRanges;
    387     delete [] replacements;
     346      sourceRanges.append(UString::Range(lastIndex, source.size() - lastIndex));
     347
     348    UString result = source.spliceSubstringsWithSeparators(sourceRanges.data(), sourceRanges.size(), replacements.data(), replacements.size());
    388349
    389350    if (result == source)
     
    416377JSValue* stringProtoFuncToString(ExecState* exec, JSObject*, JSValue* thisValue, const ArgList&)
    417378{
    418     if (!thisValue->isObject(&StringObject::info))
    419         return throwError(exec, TypeError);
    420 
    421     return static_cast<StringObject*>(thisValue)->internalValue();
    422 }
    423 
    424 JSValue* stringProtoFuncValueOf(ExecState* exec, JSObject*, JSValue* thisValue, const ArgList&)
    425 {
    426     if (!thisValue->isObject(&StringObject::info))
    427         return throwError(exec, TypeError);
    428 
    429     return static_cast<StringObject*>(thisValue)->internalValue();
     379    // Also used for valueOf.
     380
     381    if (thisValue->isString())
     382        return thisValue;
     383
     384    if (thisValue->isObject(&StringObject::info))
     385        return static_cast<StringObject*>(thisValue)->internalValue();
     386
     387    return throwError(exec, TypeError);
    430388}
    431389
    432390JSValue* stringProtoFuncCharAt(ExecState* exec, JSObject*, JSValue* thisValue, const ArgList& args)
    433391{
    434     // This optimizes the common case that thisObj is a StringObject
    435     UString s = thisValue->isObject(&StringObject::info) ? static_cast<StringObject*>(thisValue)->internalValue()->value() : thisValue->toThisObject(exec)->toString(exec);
     392    UString s = thisValue->toThisString(exec);
    436393    int len = s.size();
    437394
     
    448405JSValue* stringProtoFuncCharCodeAt(ExecState* exec, JSObject*, JSValue* thisValue, const ArgList& args)
    449406{
    450     // This optimizes the common case that thisObj is a StringObject
    451     UString s = thisValue->isObject(&StringObject::info) ? static_cast<StringObject*>(thisValue)->internalValue()->value() : thisValue->toThisObject(exec)->toString(exec);
     407    UString s = thisValue->toThisString(exec);
    452408    int len = s.size();
    453409
     
    465421JSValue* stringProtoFuncConcat(ExecState* exec, JSObject*, JSValue* thisValue, const ArgList& args)
    466422{
    467     // This optimizes the common case that thisObj is a StringObject
    468     UString s = thisValue->isObject(&StringObject::info) ? static_cast<StringObject*>(thisValue)->internalValue()->value() : thisValue->toThisObject(exec)->toString(exec);
     423    UString s = thisValue->toThisString(exec);
    469424
    470425    ArgList::const_iterator end = args.end();
     
    477432JSValue* stringProtoFuncIndexOf(ExecState* exec, JSObject*, JSValue* thisValue, const ArgList& args)
    478433{
    479     // This optimizes the common case that thisObj is a StringObject
    480     UString s = thisValue->isObject(&StringObject::info) ? static_cast<StringObject*>(thisValue)->internalValue()->value() : thisValue->toThisObject(exec)->toString(exec);
     434    UString s = thisValue->toThisString(exec);
    481435    int len = s.size();
    482436
     
    494448JSValue* stringProtoFuncLastIndexOf(ExecState* exec, JSObject*, JSValue* thisValue, const ArgList& args)
    495449{
    496     // This optimizes the common case that thisObj is a StringObject
    497     UString s = thisValue->isObject(&StringObject::info) ? static_cast<StringObject*>(thisValue)->internalValue()->value() : thisValue->toThisObject(exec)->toString(exec);
     450    UString s = thisValue->toThisString(exec);
    498451    int len = s.size();
    499452
     
    512465JSValue* stringProtoFuncMatch(ExecState* exec, JSObject*, JSValue* thisValue, const ArgList& args)
    513466{
    514     // This optimizes the common case that thisObj is a StringObject
    515     UString s = thisValue->isObject(&StringObject::info) ? static_cast<StringObject*>(thisValue)->internalValue()->value() : thisValue->toThisObject(exec)->toString(exec);
     467    UString s = thisValue->toThisString(exec);
    516468
    517469    JSValue* a0 = args[0];
     
    530482      reg = RegExp::create(a0->toString(exec));
    531483    }
    532     RegExpConstructor* regExpObj = static_cast<RegExpConstructor*>(exec->lexicalGlobalObject()->regExpConstructor());
     484    RegExpConstructor* regExpObj = exec->lexicalGlobalObject()->regExpConstructor();
    533485    int pos;
    534486    int matchLength;
     
    567519JSValue* stringProtoFuncSearch(ExecState* exec, JSObject*, JSValue* thisValue, const ArgList& args)
    568520{
    569     // This optimizes the common case that thisObj is a StringObject
    570     UString s = thisValue->isObject(&StringObject::info) ? static_cast<StringObject*>(thisValue)->internalValue()->value() : thisValue->toThisObject(exec)->toString(exec);
     521    UString s = thisValue->toThisString(exec);
    571522
    572523    JSValue* a0 = args[0];
     
    584535      reg = RegExp::create(a0->toString(exec));
    585536    }
    586     RegExpConstructor* regExpObj = static_cast<RegExpConstructor*>(exec->lexicalGlobalObject()->regExpConstructor());
     537    RegExpConstructor* regExpObj = exec->lexicalGlobalObject()->regExpConstructor();
    587538    int pos;
    588539    int matchLength;
     
    591542}
    592543
    593 JSValue* stringProtoFuncReplace(ExecState* exec, JSObject*, JSValue* thisValue, const ArgList& args)
    594 {
    595     // This optimizes the common case that thisObj is a StringObject
    596     UString s = thisValue->isObject(&StringObject::info) ? static_cast<StringObject*>(thisValue)->internalValue()->value() : thisValue->toThisObject(exec)->toString(exec);
    597 
    598     JSString* sVal = thisValue->isObject(&StringObject::info) ?
    599       static_cast<StringObject*>(thisValue)->internalValue() :
    600       static_cast<JSString*>(jsString(exec, s));
    601 
    602     JSValue* a0 = args[0];
    603     JSValue* a1 = args[1];
    604 
    605     return replace(exec, sVal, a0, a1);
    606 }
    607 
    608544JSValue* stringProtoFuncSlice(ExecState* exec, JSObject*, JSValue* thisValue, const ArgList& args)
    609545{
    610     // This optimizes the common case that thisObj is a StringObject
    611     UString s = thisValue->isObject(&StringObject::info) ? static_cast<StringObject*>(thisValue)->internalValue()->value() : thisValue->toThisObject(exec)->toString(exec);
     546    UString s = thisValue->toThisString(exec);
    612547    int len = s.size();
    613548
     
    633568JSValue* stringProtoFuncSplit(ExecState* exec, JSObject*, JSValue* thisValue, const ArgList& args)
    634569{
    635     // This optimizes the common case that thisObj is a StringObject
    636     UString s = thisValue->isObject(&StringObject::info) ? static_cast<StringObject*>(thisValue)->internalValue()->value() : thisValue->toThisObject(exec)->toString(exec);
     570    UString s = thisValue->toThisString(exec);
    637571
    638572    JSValue* a0 = args[0];
     
    702636JSValue* stringProtoFuncSubstr(ExecState* exec, JSObject*, JSValue* thisValue, const ArgList& args)
    703637{
    704     // This optimizes the common case that thisObj is a StringObject
    705     UString s = thisValue->isObject(&StringObject::info) ? static_cast<StringObject*>(thisValue)->internalValue()->value() : thisValue->toThisObject(exec)->toString(exec);
     638    UString s = thisValue->toThisString(exec);
    706639    int len = s.size();
    707640
     
    727660JSValue* stringProtoFuncSubstring(ExecState* exec, JSObject*, JSValue* thisValue, const ArgList& args)
    728661{
    729     // This optimizes the common case that thisObj is a StringObject
    730     UString s = thisValue->isObject(&StringObject::info) ? static_cast<StringObject*>(thisValue)->internalValue()->value() : thisValue->toThisObject(exec)->toString(exec);
     662    UString s = thisValue->toThisString(exec);
    731663    int len = s.size();
    732664
     
    760692JSValue* stringProtoFuncToLowerCase(ExecState* exec, JSObject*, JSValue* thisValue, const ArgList&)
    761693{
    762     // This optimizes the common case that thisObj is a StringObject
    763     UString s = thisValue->isObject(&StringObject::info) ? static_cast<StringObject*>(thisValue)->internalValue()->value() : thisValue->toThisObject(exec)->toString(exec);
     694    JSString* sVal = thisValue->toThisJSString(exec);
     695    const UString& s = sVal->value();
    764696   
    765     JSString* sVal = thisValue->isObject(&StringObject::info)
    766         ? static_cast<StringObject*>(thisValue)->internalValue()
    767         : static_cast<JSString*>(jsString(exec, s));
    768697    int ssize = s.size();
    769698    if (!ssize)
     
    785714JSValue* stringProtoFuncToUpperCase(ExecState* exec, JSObject*, JSValue* thisValue, const ArgList&)
    786715{
    787     // This optimizes the common case that thisObj is a StringObject
    788     UString s = thisValue->isObject(&StringObject::info) ? static_cast<StringObject*>(thisValue)->internalValue()->value() : thisValue->toThisObject(exec)->toString(exec);
    789 
    790     JSString* sVal = thisValue->isObject(&StringObject::info)
    791         ? static_cast<StringObject*>(thisValue)->internalValue()
    792         : static_cast<JSString*>(jsString(exec, s));
     716    JSString* sVal = thisValue->toThisJSString(exec);
     717    const UString& s = sVal->value();
     718   
    793719    int ssize = s.size();
    794720    if (!ssize)
     
    810736JSValue* stringProtoFuncToLocaleLowerCase(ExecState* exec, JSObject*, JSValue* thisValue, const ArgList&)
    811737{
    812     // This optimizes the common case that thisObj is a StringObject
    813     UString s = thisValue->isObject(&StringObject::info) ? static_cast<StringObject*>(thisValue)->internalValue()->value() : thisValue->toThisObject(exec)->toString(exec);
     738    // FIXME: See http://www.unicode.org/Public/UNIDATA/SpecialCasing.txt for locale-sensitive mappings that aren't implemented.
     739
     740    JSString* sVal = thisValue->toThisJSString(exec);
     741    const UString& s = sVal->value();
    814742   
    815     // FIXME: See http://www.unicode.org/Public/UNIDATA/SpecialCasing.txt for locale-sensitive mappings that aren't implemented.
    816     JSString* sVal = thisValue->isObject(&StringObject::info)
    817         ? static_cast<StringObject*>(thisValue)->internalValue()
    818         : static_cast<JSString*>(jsString(exec, s));
    819743    int ssize = s.size();
    820744    if (!ssize)
     
    836760JSValue* stringProtoFuncToLocaleUpperCase(ExecState* exec, JSObject*, JSValue* thisValue, const ArgList&)
    837761{
    838     // This optimizes the common case that thisObj is a StringObject
    839     UString s = thisValue->isObject(&StringObject::info) ? static_cast<StringObject*>(thisValue)->internalValue()->value() : thisValue->toThisObject(exec)->toString(exec);
    840 
    841     JSString* sVal = thisValue->isObject(&StringObject::info)
    842         ? static_cast<StringObject*>(thisValue)->internalValue()
    843         : static_cast<JSString*>(jsString(exec, s));
     762    JSString* sVal = thisValue->toThisJSString(exec);
     763    const UString& s = sVal->value();
     764   
    844765    int ssize = s.size();
    845766    if (!ssize)
     
    864785      return jsNumber(exec, 0);
    865786
    866     // This optimizes the common case that thisObj is a StringObject
    867     UString s = thisValue->isObject(&StringObject::info) ? static_cast<StringObject*>(thisValue)->internalValue()->value() : thisValue->toThisObject(exec)->toString(exec);
     787    UString s = thisValue->toThisString(exec);
    868788    JSValue* a0 = args[0];
    869789    return jsNumber(exec, localeCompare(s, a0->toString(exec)));
     
    872792JSValue* stringProtoFuncBig(ExecState* exec, JSObject*, JSValue* thisValue, const ArgList&)
    873793{
    874     // This optimizes the common case that thisObj is a StringObject
    875     UString s = thisValue->isObject(&StringObject::info) ? static_cast<StringObject*>(thisValue)->internalValue()->value() : thisValue->toThisObject(exec)->toString(exec);
     794    UString s = thisValue->toThisString(exec);
    876795    return jsString(exec, "<big>" + s + "</big>");
    877796}
     
    879798JSValue* stringProtoFuncSmall(ExecState* exec, JSObject*, JSValue* thisValue, const ArgList&)
    880799{
    881     // This optimizes the common case that thisObj is a StringObject
    882     UString s = thisValue->isObject(&StringObject::info) ? static_cast<StringObject*>(thisValue)->internalValue()->value() : thisValue->toThisObject(exec)->toString(exec);
     800    UString s = thisValue->toThisString(exec);
    883801    return jsString(exec, "<small>" + s + "</small>");
    884802}
     
    886804JSValue* stringProtoFuncBlink(ExecState* exec, JSObject*, JSValue* thisValue, const ArgList&)
    887805{
    888     // This optimizes the common case that thisObj is a StringObject
    889     UString s = thisValue->isObject(&StringObject::info) ? static_cast<StringObject*>(thisValue)->internalValue()->value() : thisValue->toThisObject(exec)->toString(exec);
     806    UString s = thisValue->toThisString(exec);
    890807    return jsString(exec, "<blink>" + s + "</blink>");
    891808}
     
    893810JSValue* stringProtoFuncBold(ExecState* exec, JSObject*, JSValue* thisValue, const ArgList&)
    894811{
    895     // This optimizes the common case that thisObj is a StringObject
    896     UString s = thisValue->isObject(&StringObject::info) ? static_cast<StringObject*>(thisValue)->internalValue()->value() : thisValue->toThisObject(exec)->toString(exec);
     812    UString s = thisValue->toThisString(exec);
    897813    return jsString(exec, "<b>" + s + "</b>");
    898814}
     
    900816JSValue* stringProtoFuncFixed(ExecState* exec, JSObject*, JSValue* thisValue, const ArgList&)
    901817{
    902     // This optimizes the common case that thisObj is a StringObject
    903     UString s = thisValue->isObject(&StringObject::info) ? static_cast<StringObject*>(thisValue)->internalValue()->value() : thisValue->toThisObject(exec)->toString(exec);
     818    UString s = thisValue->toThisString(exec);
    904819    return jsString(exec, "<tt>" + s + "</tt>");
    905820}
     
    907822JSValue* stringProtoFuncItalics(ExecState* exec, JSObject*, JSValue* thisValue, const ArgList&)
    908823{
    909     // This optimizes the common case that thisObj is a StringObject
    910     UString s = thisValue->isObject(&StringObject::info) ? static_cast<StringObject*>(thisValue)->internalValue()->value() : thisValue->toThisObject(exec)->toString(exec);
     824    UString s = thisValue->toThisString(exec);
    911825    return jsString(exec, "<i>" + s + "</i>");
    912826}
     
    914828JSValue* stringProtoFuncStrike(ExecState* exec, JSObject*, JSValue* thisValue, const ArgList&)
    915829{
    916     // This optimizes the common case that thisObj is a StringObject
    917     UString s = thisValue->isObject(&StringObject::info) ? static_cast<StringObject*>(thisValue)->internalValue()->value() : thisValue->toThisObject(exec)->toString(exec);
     830    UString s = thisValue->toThisString(exec);
    918831    return jsString(exec, "<strike>" + s + "</strike>");
    919832}
     
    921834JSValue* stringProtoFuncSub(ExecState* exec, JSObject*, JSValue* thisValue, const ArgList&)
    922835{
    923     // This optimizes the common case that thisObj is a StringObject
    924     UString s = thisValue->isObject(&StringObject::info) ? static_cast<StringObject*>(thisValue)->internalValue()->value() : thisValue->toThisObject(exec)->toString(exec);
     836    UString s = thisValue->toThisString(exec);
    925837    return jsString(exec, "<sub>" + s + "</sub>");
    926838}
     
    928840JSValue* stringProtoFuncSup(ExecState* exec, JSObject*, JSValue* thisValue, const ArgList&)
    929841{
    930     // This optimizes the common case that thisObj is a StringObject
    931     UString s = thisValue->isObject(&StringObject::info) ? static_cast<StringObject*>(thisValue)->internalValue()->value() : thisValue->toThisObject(exec)->toString(exec);
     842    UString s = thisValue->toThisString(exec);
    932843    return jsString(exec, "<sup>" + s + "</sup>");
    933844}
     
    935846JSValue* stringProtoFuncFontcolor(ExecState* exec, JSObject*, JSValue* thisValue, const ArgList& args)
    936847{
    937     // This optimizes the common case that thisObj is a StringObject
    938     UString s = thisValue->isObject(&StringObject::info) ? static_cast<StringObject*>(thisValue)->internalValue()->value() : thisValue->toThisObject(exec)->toString(exec);
     848    UString s = thisValue->toThisString(exec);
    939849    JSValue* a0 = args[0];
    940850    return jsString(exec, "<font color=\"" + a0->toString(exec) + "\">" + s + "</font>");
     
    943853JSValue* stringProtoFuncFontsize(ExecState* exec, JSObject*, JSValue* thisValue, const ArgList& args)
    944854{
    945     // This optimizes the common case that thisObj is a StringObject
    946     UString s = thisValue->isObject(&StringObject::info) ? static_cast<StringObject*>(thisValue)->internalValue()->value() : thisValue->toThisObject(exec)->toString(exec);
     855    UString s = thisValue->toThisString(exec);
    947856    JSValue* a0 = args[0];
    948857    return jsString(exec, "<font size=\"" + a0->toString(exec) + "\">" + s + "</font>");
     
    951860JSValue* stringProtoFuncAnchor(ExecState* exec, JSObject*, JSValue* thisValue, const ArgList& args)
    952861{
    953     // This optimizes the common case that thisObj is a StringObject
    954     UString s = thisValue->isObject(&StringObject::info) ? static_cast<StringObject*>(thisValue)->internalValue()->value() : thisValue->toThisObject(exec)->toString(exec);
     862    UString s = thisValue->toThisString(exec);
    955863    JSValue* a0 = args[0];
    956864    return jsString(exec, "<a name=\"" + a0->toString(exec) + "\">" + s + "</a>");
     
    959867JSValue* stringProtoFuncLink(ExecState* exec, JSObject*, JSValue* thisValue, const ArgList& args)
    960868{
    961     // This optimizes the common case that thisObj is a StringObject
    962     UString s = thisValue->isObject(&StringObject::info) ? static_cast<StringObject*>(thisValue)->internalValue()->value() : thisValue->toThisObject(exec)->toString(exec);
     869    UString s = thisValue->toThisString(exec);
    963870    JSValue* a0 = args[0];
    964871    return jsString(exec, "<a href=\"" + a0->toString(exec) + "\">" + s + "</a>");
Note: See TracChangeset for help on using the changeset viewer.