JavaScriptCore/runtime/UString.h
changeset 0 4f2f89ce4247
equal deleted inserted replaced
-1:000000000000 0:4f2f89ce4247
       
     1 /*
       
     2  *  Copyright (C) 1999-2000 Harri Porten (porten@kde.org)
       
     3  *  Copyright (C) 2004, 2005, 2006, 2007, 2008, 2009 Apple Inc. All rights reserved.
       
     4  *  Copyright (C) 2009 Google Inc. All rights reserved.
       
     5  *
       
     6  *  This library is free software; you can redistribute it and/or
       
     7  *  modify it under the terms of the GNU Library General Public
       
     8  *  License as published by the Free Software Foundation; either
       
     9  *  version 2 of the License, or (at your option) any later version.
       
    10  *
       
    11  *  This library is distributed in the hope that it will be useful,
       
    12  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
       
    13  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
       
    14  *  Library General Public License for more details.
       
    15  *
       
    16  *  You should have received a copy of the GNU Library General Public License
       
    17  *  along with this library; see the file COPYING.LIB.  If not, write to
       
    18  *  the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
       
    19  *  Boston, MA 02110-1301, USA.
       
    20  *
       
    21  */
       
    22 
       
    23 #ifndef UString_h
       
    24 #define UString_h
       
    25 
       
    26 #include "Collector.h"
       
    27 #include "UStringImpl.h"
       
    28 #include <stdint.h>
       
    29 #include <string.h>
       
    30 #include <wtf/Assertions.h>
       
    31 #include <wtf/CrossThreadRefCounted.h>
       
    32 #include <wtf/OwnFastMallocPtr.h>
       
    33 #include <wtf/PassRefPtr.h>
       
    34 #include <wtf/RefPtr.h>
       
    35 #include <wtf/Vector.h>
       
    36 #include <wtf/text/CString.h>
       
    37 #include <wtf/unicode/Unicode.h>
       
    38 
       
    39 namespace JSC {
       
    40 
       
    41     using WTF::PlacementNewAdoptType;
       
    42     using WTF::PlacementNewAdopt;
       
    43 
       
    44     class UString {
       
    45         friend class JIT;
       
    46 
       
    47     public:
       
    48         typedef UStringImpl Rep;
       
    49     
       
    50     public:
       
    51         UString() {}
       
    52         UString(const char*); // Constructor for null-terminated string.
       
    53         UString(const char*, unsigned length);
       
    54         UString(const UChar*, unsigned length);
       
    55         UString(const Vector<UChar>& buffer);
       
    56 
       
    57         UString(const UString& s)
       
    58             : m_rep(s.m_rep)
       
    59         {
       
    60         }
       
    61 
       
    62         // Special constructor for cases where we overwrite an object in place.
       
    63         UString(PlacementNewAdoptType)
       
    64             : m_rep(PlacementNewAdopt)
       
    65         {
       
    66         }
       
    67 
       
    68         template<size_t inlineCapacity>
       
    69         static PassRefPtr<UStringImpl> adopt(Vector<UChar, inlineCapacity>& vector)
       
    70         {
       
    71             return Rep::adopt(vector);
       
    72         }
       
    73 
       
    74         static UString from(int);
       
    75         static UString from(long long);
       
    76         static UString from(unsigned);
       
    77         static UString from(long);
       
    78         static UString from(double);
       
    79 
       
    80         // NOTE: This method should only be used for *debugging* purposes as it
       
    81         // is neither Unicode safe nor free from side effects nor thread-safe.
       
    82         char* ascii() const;
       
    83 
       
    84         /**
       
    85          * Convert the string to UTF-8, assuming it is UTF-16 encoded.
       
    86          * In non-strict mode, this function is tolerant of badly formed UTF-16, it
       
    87          * can create UTF-8 strings that are invalid because they have characters in
       
    88          * the range U+D800-U+DDFF, U+FFFE, or U+FFFF, but the UTF-8 string is
       
    89          * guaranteed to be otherwise valid.
       
    90          * In strict mode, error is returned as null CString.
       
    91          */
       
    92         CString UTF8String(bool strict = false) const;
       
    93 
       
    94         const UChar* data() const
       
    95         {
       
    96             if (!m_rep)
       
    97                 return 0;
       
    98             return m_rep->characters();
       
    99         }
       
   100 
       
   101         unsigned size() const
       
   102         {
       
   103             if (!m_rep)
       
   104                 return 0;
       
   105             return m_rep->length();
       
   106         }
       
   107 
       
   108         bool isNull() const { return !m_rep; }
       
   109         bool isEmpty() const { return !m_rep || !m_rep->length(); }
       
   110 
       
   111         bool is8Bit() const;
       
   112 
       
   113         UChar operator[](unsigned pos) const;
       
   114 
       
   115         double toDouble(bool tolerateTrailingJunk, bool tolerateEmptyString) const;
       
   116         double toDouble(bool tolerateTrailingJunk) const;
       
   117         double toDouble() const;
       
   118 
       
   119         uint32_t toUInt32(bool* ok = 0) const;
       
   120         uint32_t toUInt32(bool* ok, bool tolerateEmptyString) const;
       
   121         uint32_t toStrictUInt32(bool* ok = 0) const;
       
   122 
       
   123         unsigned toArrayIndex(bool* ok = 0) const;
       
   124 
       
   125         static const unsigned NotFound = 0xFFFFFFFFu;
       
   126         unsigned find(const UString& f, unsigned pos = 0) const;
       
   127         unsigned find(UChar, unsigned pos = 0) const;
       
   128         unsigned rfind(const UString& f, unsigned pos) const;
       
   129         unsigned rfind(UChar, unsigned pos) const;
       
   130 
       
   131         UString substr(unsigned pos = 0, unsigned len = 0xFFFFFFFF) const;
       
   132 
       
   133         static const UString& null() { return *s_nullUString; }
       
   134 
       
   135         Rep* rep() const { return m_rep.get(); }
       
   136 
       
   137         UString(PassRefPtr<Rep> r)
       
   138             : m_rep(r)
       
   139         {
       
   140         }
       
   141 
       
   142         size_t cost() const
       
   143         {
       
   144             if (!m_rep)
       
   145                 return 0;
       
   146             return m_rep->cost();
       
   147         }
       
   148 
       
   149         ALWAYS_INLINE ~UString() { }
       
   150     private:
       
   151         RefPtr<Rep> m_rep;
       
   152 
       
   153         static UString* s_nullUString;
       
   154 
       
   155         friend void initializeUString();
       
   156         friend bool operator==(const UString&, const UString&);
       
   157     };
       
   158 
       
   159     ALWAYS_INLINE bool operator==(const UString& s1, const UString& s2)
       
   160     {
       
   161         UString::Rep* rep1 = s1.rep();
       
   162         UString::Rep* rep2 = s2.rep();
       
   163         unsigned size1 = 0;
       
   164         unsigned size2 = 0;
       
   165 
       
   166         if (rep1 == rep2) // If they're the same rep, they're equal.
       
   167             return true;
       
   168         
       
   169         if (rep1)
       
   170             size1 = rep1->length();
       
   171             
       
   172         if (rep2)
       
   173             size2 = rep2->length();
       
   174             
       
   175         if (size1 != size2) // If the lengths are not the same, we're done.
       
   176             return false;
       
   177         
       
   178         if (!size1)
       
   179             return true;
       
   180         
       
   181         // At this point we know 
       
   182         //   (a) that the strings are the same length and
       
   183         //   (b) that they are greater than zero length.
       
   184         const UChar* d1 = rep1->characters();
       
   185         const UChar* d2 = rep2->characters();
       
   186         
       
   187         if (d1 == d2) // Check to see if the data pointers are the same.
       
   188             return true;
       
   189         
       
   190         // Do quick checks for sizes 1 and 2.
       
   191         switch (size1) {
       
   192         case 1:
       
   193             return d1[0] == d2[0];
       
   194         case 2:
       
   195             return (d1[0] == d2[0]) & (d1[1] == d2[1]);
       
   196         default:
       
   197             return memcmp(d1, d2, size1 * sizeof(UChar)) == 0;
       
   198         }
       
   199     }
       
   200 
       
   201 
       
   202     inline bool operator!=(const UString& s1, const UString& s2)
       
   203     {
       
   204         return !JSC::operator==(s1, s2);
       
   205     }
       
   206 
       
   207     bool operator<(const UString& s1, const UString& s2);
       
   208     bool operator>(const UString& s1, const UString& s2);
       
   209 
       
   210     bool operator==(const UString& s1, const char* s2);
       
   211 
       
   212     inline bool operator!=(const UString& s1, const char* s2)
       
   213     {
       
   214         return !JSC::operator==(s1, s2);
       
   215     }
       
   216 
       
   217     inline bool operator==(const char *s1, const UString& s2)
       
   218     {
       
   219         return operator==(s2, s1);
       
   220     }
       
   221 
       
   222     inline bool operator!=(const char *s1, const UString& s2)
       
   223     {
       
   224         return !JSC::operator==(s1, s2);
       
   225     }
       
   226 
       
   227     inline int codePointCompare(const UString& s1, const UString& s2)
       
   228     {
       
   229         return codePointCompare(s1.rep(), s2.rep());
       
   230     }
       
   231 
       
   232     // Rule from ECMA 15.2 about what an array index is.
       
   233     // Must exactly match string form of an unsigned integer, and be less than 2^32 - 1.
       
   234     inline unsigned UString::toArrayIndex(bool* ok) const
       
   235     {
       
   236         unsigned i = toStrictUInt32(ok);
       
   237         if (ok && i >= 0xFFFFFFFFU)
       
   238             *ok = false;
       
   239         return i;
       
   240     }
       
   241 
       
   242     // We'd rather not do shared substring append for small strings, since
       
   243     // this runs too much risk of a tiny initial string holding down a
       
   244     // huge buffer.
       
   245     static const unsigned minShareSize = Heap::minExtraCost / sizeof(UChar);
       
   246 
       
   247     struct IdentifierRepHash : PtrHash<RefPtr<JSC::UString::Rep> > {
       
   248         static unsigned hash(const RefPtr<JSC::UString::Rep>& key) { return key->existingHash(); }
       
   249         static unsigned hash(JSC::UString::Rep* key) { return key->existingHash(); }
       
   250     };
       
   251 
       
   252     void initializeUString();
       
   253 
       
   254     template<typename StringType>
       
   255     class StringTypeAdapter {
       
   256     };
       
   257 
       
   258     template<>
       
   259     class StringTypeAdapter<char*> {
       
   260     public:
       
   261         StringTypeAdapter<char*>(char* buffer)
       
   262             : m_buffer((unsigned char*)buffer)
       
   263             , m_length(strlen(buffer))
       
   264         {
       
   265         }
       
   266 
       
   267         unsigned length() { return m_length; }
       
   268 
       
   269         void writeTo(UChar* destination)
       
   270         {
       
   271             for (unsigned i = 0; i < m_length; ++i)
       
   272                 destination[i] = m_buffer[i];
       
   273         }
       
   274 
       
   275     private:
       
   276         const unsigned char* m_buffer;
       
   277         unsigned m_length;
       
   278     };
       
   279 
       
   280     template<>
       
   281     class StringTypeAdapter<const char*> {
       
   282     public:
       
   283         StringTypeAdapter<const char*>(const char* buffer)
       
   284             : m_buffer((unsigned char*)buffer)
       
   285             , m_length(strlen(buffer))
       
   286         {
       
   287         }
       
   288 
       
   289         unsigned length() { return m_length; }
       
   290 
       
   291         void writeTo(UChar* destination)
       
   292         {
       
   293             for (unsigned i = 0; i < m_length; ++i)
       
   294                 destination[i] = m_buffer[i];
       
   295         }
       
   296 
       
   297     private:
       
   298         const unsigned char* m_buffer;
       
   299         unsigned m_length;
       
   300     };
       
   301 
       
   302     template<>
       
   303     class StringTypeAdapter<UString> {
       
   304     public:
       
   305         StringTypeAdapter<UString>(UString& string)
       
   306             : m_data(string.data())
       
   307             , m_length(string.size())
       
   308         {
       
   309         }
       
   310 
       
   311         unsigned length() { return m_length; }
       
   312 
       
   313         void writeTo(UChar* destination)
       
   314         {
       
   315             for (unsigned i = 0; i < m_length; ++i)
       
   316                 destination[i] = m_data[i];
       
   317         }
       
   318 
       
   319     private:
       
   320         const UChar* m_data;
       
   321         unsigned m_length;
       
   322     };
       
   323 
       
   324     inline void sumWithOverflow(unsigned& total, unsigned addend, bool& overflow)
       
   325     {
       
   326         unsigned oldTotal = total;
       
   327         total = oldTotal + addend;
       
   328         if (total < oldTotal)
       
   329             overflow = true;
       
   330     }
       
   331 
       
   332     template<typename StringType1, typename StringType2>
       
   333     PassRefPtr<UStringImpl> tryMakeString(StringType1 string1, StringType2 string2)
       
   334     {
       
   335         StringTypeAdapter<StringType1> adapter1(string1);
       
   336         StringTypeAdapter<StringType2> adapter2(string2);
       
   337 
       
   338         UChar* buffer;
       
   339         bool overflow = false;
       
   340         unsigned length = adapter1.length();
       
   341         sumWithOverflow(length, adapter2.length(), overflow);
       
   342         if (overflow)
       
   343             return 0;
       
   344         PassRefPtr<UStringImpl> resultImpl = UStringImpl::tryCreateUninitialized(length, buffer);
       
   345         if (!resultImpl)
       
   346             return 0;
       
   347 
       
   348         UChar* result = buffer;
       
   349         adapter1.writeTo(result);
       
   350         result += adapter1.length();
       
   351         adapter2.writeTo(result);
       
   352 
       
   353         return resultImpl;
       
   354     }
       
   355 
       
   356     template<typename StringType1, typename StringType2, typename StringType3>
       
   357     PassRefPtr<UStringImpl> tryMakeString(StringType1 string1, StringType2 string2, StringType3 string3)
       
   358     {
       
   359         StringTypeAdapter<StringType1> adapter1(string1);
       
   360         StringTypeAdapter<StringType2> adapter2(string2);
       
   361         StringTypeAdapter<StringType3> adapter3(string3);
       
   362 
       
   363         UChar* buffer = 0;
       
   364         bool overflow = false;
       
   365         unsigned length = adapter1.length();
       
   366         sumWithOverflow(length, adapter2.length(), overflow);
       
   367         sumWithOverflow(length, adapter3.length(), overflow);
       
   368         if (overflow)
       
   369             return 0;
       
   370         PassRefPtr<UStringImpl> resultImpl = UStringImpl::tryCreateUninitialized(length, buffer);
       
   371         if (!resultImpl)
       
   372             return 0;
       
   373 
       
   374         UChar* result = buffer;
       
   375         adapter1.writeTo(result);
       
   376         result += adapter1.length();
       
   377         adapter2.writeTo(result);
       
   378         result += adapter2.length();
       
   379         adapter3.writeTo(result);
       
   380 
       
   381         return resultImpl;
       
   382     }
       
   383 
       
   384     template<typename StringType1, typename StringType2, typename StringType3, typename StringType4>
       
   385     PassRefPtr<UStringImpl> tryMakeString(StringType1 string1, StringType2 string2, StringType3 string3, StringType4 string4)
       
   386     {
       
   387         StringTypeAdapter<StringType1> adapter1(string1);
       
   388         StringTypeAdapter<StringType2> adapter2(string2);
       
   389         StringTypeAdapter<StringType3> adapter3(string3);
       
   390         StringTypeAdapter<StringType4> adapter4(string4);
       
   391 
       
   392         UChar* buffer;
       
   393         bool overflow = false;
       
   394         unsigned length = adapter1.length();
       
   395         sumWithOverflow(length, adapter2.length(), overflow);
       
   396         sumWithOverflow(length, adapter3.length(), overflow);
       
   397         sumWithOverflow(length, adapter4.length(), overflow);
       
   398         if (overflow)
       
   399             return 0;
       
   400         PassRefPtr<UStringImpl> resultImpl = UStringImpl::tryCreateUninitialized(length, buffer);
       
   401         if (!resultImpl)
       
   402             return 0;
       
   403 
       
   404         UChar* result = buffer;
       
   405         adapter1.writeTo(result);
       
   406         result += adapter1.length();
       
   407         adapter2.writeTo(result);
       
   408         result += adapter2.length();
       
   409         adapter3.writeTo(result);
       
   410         result += adapter3.length();
       
   411         adapter4.writeTo(result);
       
   412 
       
   413         return resultImpl;
       
   414     }
       
   415 
       
   416     template<typename StringType1, typename StringType2, typename StringType3, typename StringType4, typename StringType5>
       
   417     PassRefPtr<UStringImpl> tryMakeString(StringType1 string1, StringType2 string2, StringType3 string3, StringType4 string4, StringType5 string5)
       
   418     {
       
   419         StringTypeAdapter<StringType1> adapter1(string1);
       
   420         StringTypeAdapter<StringType2> adapter2(string2);
       
   421         StringTypeAdapter<StringType3> adapter3(string3);
       
   422         StringTypeAdapter<StringType4> adapter4(string4);
       
   423         StringTypeAdapter<StringType5> adapter5(string5);
       
   424 
       
   425         UChar* buffer;
       
   426         bool overflow = false;
       
   427         unsigned length = adapter1.length();
       
   428         sumWithOverflow(length, adapter2.length(), overflow);
       
   429         sumWithOverflow(length, adapter3.length(), overflow);
       
   430         sumWithOverflow(length, adapter4.length(), overflow);
       
   431         sumWithOverflow(length, adapter5.length(), overflow);
       
   432         if (overflow)
       
   433             return 0;
       
   434         PassRefPtr<UStringImpl> resultImpl = UStringImpl::tryCreateUninitialized(length, buffer);
       
   435         if (!resultImpl)
       
   436             return 0;
       
   437 
       
   438         UChar* result = buffer;
       
   439         adapter1.writeTo(result);
       
   440         result += adapter1.length();
       
   441         adapter2.writeTo(result);
       
   442         result += adapter2.length();
       
   443         adapter3.writeTo(result);
       
   444         result += adapter3.length();
       
   445         adapter4.writeTo(result);
       
   446         result += adapter4.length();
       
   447         adapter5.writeTo(result);
       
   448 
       
   449         return resultImpl;
       
   450     }
       
   451 
       
   452     template<typename StringType1, typename StringType2, typename StringType3, typename StringType4, typename StringType5, typename StringType6>
       
   453     PassRefPtr<UStringImpl> tryMakeString(StringType1 string1, StringType2 string2, StringType3 string3, StringType4 string4, StringType5 string5, StringType6 string6)
       
   454     {
       
   455         StringTypeAdapter<StringType1> adapter1(string1);
       
   456         StringTypeAdapter<StringType2> adapter2(string2);
       
   457         StringTypeAdapter<StringType3> adapter3(string3);
       
   458         StringTypeAdapter<StringType4> adapter4(string4);
       
   459         StringTypeAdapter<StringType5> adapter5(string5);
       
   460         StringTypeAdapter<StringType6> adapter6(string6);
       
   461 
       
   462         UChar* buffer;
       
   463         bool overflow = false;
       
   464         unsigned length = adapter1.length();
       
   465         sumWithOverflow(length, adapter2.length(), overflow);
       
   466         sumWithOverflow(length, adapter3.length(), overflow);
       
   467         sumWithOverflow(length, adapter4.length(), overflow);
       
   468         sumWithOverflow(length, adapter5.length(), overflow);
       
   469         sumWithOverflow(length, adapter6.length(), overflow);
       
   470         if (overflow)
       
   471             return 0;
       
   472         PassRefPtr<UStringImpl> resultImpl = UStringImpl::tryCreateUninitialized(length, buffer);
       
   473         if (!resultImpl)
       
   474             return 0;
       
   475 
       
   476         UChar* result = buffer;
       
   477         adapter1.writeTo(result);
       
   478         result += adapter1.length();
       
   479         adapter2.writeTo(result);
       
   480         result += adapter2.length();
       
   481         adapter3.writeTo(result);
       
   482         result += adapter3.length();
       
   483         adapter4.writeTo(result);
       
   484         result += adapter4.length();
       
   485         adapter5.writeTo(result);
       
   486         result += adapter5.length();
       
   487         adapter6.writeTo(result);
       
   488 
       
   489         return resultImpl;
       
   490     }
       
   491 
       
   492     template<typename StringType1, typename StringType2, typename StringType3, typename StringType4, typename StringType5, typename StringType6, typename StringType7>
       
   493     PassRefPtr<UStringImpl> tryMakeString(StringType1 string1, StringType2 string2, StringType3 string3, StringType4 string4, StringType5 string5, StringType6 string6, StringType7 string7)
       
   494     {
       
   495         StringTypeAdapter<StringType1> adapter1(string1);
       
   496         StringTypeAdapter<StringType2> adapter2(string2);
       
   497         StringTypeAdapter<StringType3> adapter3(string3);
       
   498         StringTypeAdapter<StringType4> adapter4(string4);
       
   499         StringTypeAdapter<StringType5> adapter5(string5);
       
   500         StringTypeAdapter<StringType6> adapter6(string6);
       
   501         StringTypeAdapter<StringType7> adapter7(string7);
       
   502 
       
   503         UChar* buffer;
       
   504         bool overflow = false;
       
   505         unsigned length = adapter1.length();
       
   506         sumWithOverflow(length, adapter2.length(), overflow);
       
   507         sumWithOverflow(length, adapter3.length(), overflow);
       
   508         sumWithOverflow(length, adapter4.length(), overflow);
       
   509         sumWithOverflow(length, adapter5.length(), overflow);
       
   510         sumWithOverflow(length, adapter6.length(), overflow);
       
   511         sumWithOverflow(length, adapter7.length(), overflow);
       
   512         if (overflow)
       
   513             return 0;
       
   514         PassRefPtr<UStringImpl> resultImpl = UStringImpl::tryCreateUninitialized(length, buffer);
       
   515         if (!resultImpl)
       
   516             return 0;
       
   517 
       
   518         UChar* result = buffer;
       
   519         adapter1.writeTo(result);
       
   520         result += adapter1.length();
       
   521         adapter2.writeTo(result);
       
   522         result += adapter2.length();
       
   523         adapter3.writeTo(result);
       
   524         result += adapter3.length();
       
   525         adapter4.writeTo(result);
       
   526         result += adapter4.length();
       
   527         adapter5.writeTo(result);
       
   528         result += adapter5.length();
       
   529         adapter6.writeTo(result);
       
   530         result += adapter6.length();
       
   531         adapter7.writeTo(result);
       
   532 
       
   533         return resultImpl;
       
   534     }
       
   535 
       
   536     template<typename StringType1, typename StringType2, typename StringType3, typename StringType4, typename StringType5, typename StringType6, typename StringType7, typename StringType8>
       
   537     PassRefPtr<UStringImpl> tryMakeString(StringType1 string1, StringType2 string2, StringType3 string3, StringType4 string4, StringType5 string5, StringType6 string6, StringType7 string7, StringType8 string8)
       
   538     {
       
   539         StringTypeAdapter<StringType1> adapter1(string1);
       
   540         StringTypeAdapter<StringType2> adapter2(string2);
       
   541         StringTypeAdapter<StringType3> adapter3(string3);
       
   542         StringTypeAdapter<StringType4> adapter4(string4);
       
   543         StringTypeAdapter<StringType5> adapter5(string5);
       
   544         StringTypeAdapter<StringType6> adapter6(string6);
       
   545         StringTypeAdapter<StringType7> adapter7(string7);
       
   546         StringTypeAdapter<StringType8> adapter8(string8);
       
   547 
       
   548         UChar* buffer;
       
   549         bool overflow = false;
       
   550         unsigned length = adapter1.length();
       
   551         sumWithOverflow(length, adapter2.length(), overflow);
       
   552         sumWithOverflow(length, adapter3.length(), overflow);
       
   553         sumWithOverflow(length, adapter4.length(), overflow);
       
   554         sumWithOverflow(length, adapter5.length(), overflow);
       
   555         sumWithOverflow(length, adapter6.length(), overflow);
       
   556         sumWithOverflow(length, adapter7.length(), overflow);
       
   557         sumWithOverflow(length, adapter8.length(), overflow);
       
   558         if (overflow)
       
   559             return 0;
       
   560         PassRefPtr<UStringImpl> resultImpl = UStringImpl::tryCreateUninitialized(length, buffer);
       
   561         if (!resultImpl)
       
   562             return 0;
       
   563 
       
   564         UChar* result = buffer;
       
   565         adapter1.writeTo(result);
       
   566         result += adapter1.length();
       
   567         adapter2.writeTo(result);
       
   568         result += adapter2.length();
       
   569         adapter3.writeTo(result);
       
   570         result += adapter3.length();
       
   571         adapter4.writeTo(result);
       
   572         result += adapter4.length();
       
   573         adapter5.writeTo(result);
       
   574         result += adapter5.length();
       
   575         adapter6.writeTo(result);
       
   576         result += adapter6.length();
       
   577         adapter7.writeTo(result);
       
   578         result += adapter7.length();
       
   579         adapter8.writeTo(result);
       
   580 
       
   581         return resultImpl;
       
   582     }
       
   583 
       
   584     template<typename StringType1, typename StringType2>
       
   585     UString makeString(StringType1 string1, StringType2 string2)
       
   586     {
       
   587         PassRefPtr<UStringImpl> resultImpl = tryMakeString(string1, string2);
       
   588         if (!resultImpl)
       
   589             CRASH();
       
   590         return resultImpl;
       
   591     }
       
   592 
       
   593     template<typename StringType1, typename StringType2, typename StringType3>
       
   594     UString makeString(StringType1 string1, StringType2 string2, StringType3 string3)
       
   595     {
       
   596         PassRefPtr<UStringImpl> resultImpl = tryMakeString(string1, string2, string3);
       
   597         if (!resultImpl)
       
   598             CRASH();
       
   599         return resultImpl;
       
   600     }
       
   601 
       
   602     template<typename StringType1, typename StringType2, typename StringType3, typename StringType4>
       
   603     UString makeString(StringType1 string1, StringType2 string2, StringType3 string3, StringType4 string4)
       
   604     {
       
   605         PassRefPtr<UStringImpl> resultImpl = tryMakeString(string1, string2, string3, string4);
       
   606         if (!resultImpl)
       
   607             CRASH();
       
   608         return resultImpl;
       
   609     }
       
   610 
       
   611     template<typename StringType1, typename StringType2, typename StringType3, typename StringType4, typename StringType5>
       
   612     UString makeString(StringType1 string1, StringType2 string2, StringType3 string3, StringType4 string4, StringType5 string5)
       
   613     {
       
   614         PassRefPtr<UStringImpl> resultImpl = tryMakeString(string1, string2, string3, string4, string5);
       
   615         if (!resultImpl)
       
   616             CRASH();
       
   617         return resultImpl;
       
   618     }
       
   619 
       
   620     template<typename StringType1, typename StringType2, typename StringType3, typename StringType4, typename StringType5, typename StringType6>
       
   621     UString makeString(StringType1 string1, StringType2 string2, StringType3 string3, StringType4 string4, StringType5 string5, StringType6 string6)
       
   622     {
       
   623         PassRefPtr<UStringImpl> resultImpl = tryMakeString(string1, string2, string3, string4, string5, string6);
       
   624         if (!resultImpl)
       
   625             CRASH();
       
   626         return resultImpl;
       
   627     }
       
   628 
       
   629     template<typename StringType1, typename StringType2, typename StringType3, typename StringType4, typename StringType5, typename StringType6, typename StringType7>
       
   630     UString makeString(StringType1 string1, StringType2 string2, StringType3 string3, StringType4 string4, StringType5 string5, StringType6 string6, StringType7 string7)
       
   631     {
       
   632         PassRefPtr<UStringImpl> resultImpl = tryMakeString(string1, string2, string3, string4, string5, string6, string7);
       
   633         if (!resultImpl)
       
   634             CRASH();
       
   635         return resultImpl;
       
   636     }
       
   637 
       
   638     template<typename StringType1, typename StringType2, typename StringType3, typename StringType4, typename StringType5, typename StringType6, typename StringType7, typename StringType8>
       
   639     UString makeString(StringType1 string1, StringType2 string2, StringType3 string3, StringType4 string4, StringType5 string5, StringType6 string6, StringType7 string7, StringType8 string8)
       
   640     {
       
   641         PassRefPtr<UStringImpl> resultImpl = tryMakeString(string1, string2, string3, string4, string5, string6, string7, string8);
       
   642         if (!resultImpl)
       
   643             CRASH();
       
   644         return resultImpl;
       
   645     }
       
   646 
       
   647 } // namespace JSC
       
   648 
       
   649 namespace WTF {
       
   650 
       
   651     template<typename T> struct DefaultHash;
       
   652     template<typename T> struct StrHash;
       
   653 
       
   654     template<> struct StrHash<JSC::UString::Rep*> {
       
   655         static unsigned hash(const JSC::UString::Rep* key) { return key->hash(); }
       
   656         static bool equal(const JSC::UString::Rep* a, const JSC::UString::Rep* b) { return ::equal(a, b); }
       
   657         static const bool safeToCompareToEmptyOrDeleted = false;
       
   658     };
       
   659 
       
   660     template<> struct StrHash<RefPtr<JSC::UString::Rep> > : public StrHash<JSC::UString::Rep*> {
       
   661         using StrHash<JSC::UString::Rep*>::hash;
       
   662         static unsigned hash(const RefPtr<JSC::UString::Rep>& key) { return key->hash(); }
       
   663         using StrHash<JSC::UString::Rep*>::equal;
       
   664         static bool equal(const RefPtr<JSC::UString::Rep>& a, const RefPtr<JSC::UString::Rep>& b) { return ::equal(a.get(), b.get()); }
       
   665         static bool equal(const JSC::UString::Rep* a, const RefPtr<JSC::UString::Rep>& b) { return ::equal(a, b.get()); }
       
   666         static bool equal(const RefPtr<JSC::UString::Rep>& a, const JSC::UString::Rep* b) { return ::equal(a.get(), b); }
       
   667 
       
   668         static const bool safeToCompareToEmptyOrDeleted = false;
       
   669     };
       
   670 
       
   671     template <> struct VectorTraits<JSC::UString> : SimpleClassVectorTraits
       
   672     {
       
   673         static const bool canInitializeWithMemset = true;
       
   674     };
       
   675     
       
   676 } // namespace WTF
       
   677 
       
   678 #endif