Ignore:
Timestamp:
Feb 6, 2010, 12:55:31 AM (15 years ago)
Author:
[email protected]
Message:

Change UStringImpl::create to CRASH if the string cannot be allocated,
rather than returning a null string (which will behave like a zero-length
string if used).

Reviewed by Geoff Garen.

Also move createRep function from UString to become new overloaded
UStringImpl::create methods. In doing so, bring their behaviour closer to
being in line with WebCore::StringImpl, in removing the behaviour that they
can be used to produce null UStrings (ASSERT the char* provided is non-null).
This behaviour of converting null C-strings to null UStrings is inefficient
(cmompared to just using UString::null()), incompatible with WebCore::StringImpl's
behaviour, and may generate unexpected behaviour, since in many cases a null
UString can be used like an empty string.

With these changes UStringImpl need not have a concept of null impls, we can
start transitioning this to become an implementation detail of UString, that
internally it chooses to use a null-object rather than an actually zero impl
pointer.

(JSC::Debugger::recompileAllJSFunctions):

  • debugger/DebuggerCallFrame.cpp:

(JSC::DebuggerCallFrame::calculatedFunctionName):

  • parser/Parser.cpp:

(JSC::Parser::parse):

  • profiler/Profile.cpp:

(JSC::Profile::Profile):

  • profiler/ProfileGenerator.cpp:

(JSC::ProfileGenerator::stopProfiling):

  • runtime/Error.cpp:

(JSC::Error::create):
(JSC::throwError):

  • runtime/ExceptionHelpers.cpp:

(JSC::createError):

  • runtime/Identifier.cpp:

(JSC::Identifier::add):

  • runtime/PropertyNameArray.cpp:

(JSC::PropertyNameArray::add):

  • runtime/UString.cpp:

(JSC::initializeUString):
(JSC::UString::UString):
(JSC::UString::operator=):

  • runtime/UString.h:

(JSC::UString::isNull):
(JSC::UString::null):
(JSC::UString::rep):
(JSC::UString::UString):

  • runtime/UStringImpl.cpp:

(JSC::UStringImpl::create):

  • runtime/UStringImpl.h:
File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/JavaScriptCore/runtime/UString.cpp

    r53456 r54464  
    150150// reduce the possibility of it becoming zero due to ref/deref not being thread-safe.
    151151static UChar sharedEmptyChar;
    152 UStringImpl* UStringImpl::s_null;
    153152UStringImpl* UStringImpl::s_empty;
    154 UString* UString::nullUString;
     153
     154UString::Rep* UString::s_nullRep;
     155UString* UString::s_nullUString;
    155156
    156157void initializeUString()
    157158{
    158     UStringImpl::s_null = new UStringImpl(0, 0, UStringImpl::ConstructStaticString);
    159159    UStringImpl::s_empty = new UStringImpl(&sharedEmptyChar, 0, UStringImpl::ConstructStaticString);
    160     UString::nullUString = new UString;
    161 }
    162 
    163 static PassRefPtr<UString::Rep> createRep(const char* c)
    164 {
    165     if (!c)
    166         return &UString::Rep::null();
    167 
    168     if (!c[0])
    169         return &UString::Rep::empty();
    170 
    171     size_t length = strlen(c);
    172     UChar* d;
    173     PassRefPtr<UStringImpl> result = UStringImpl::tryCreateUninitialized(length, d);
    174     if (!result)
    175         return &UString::Rep::null();
    176 
    177     for (size_t i = 0; i < length; i++)
    178         d[i] = static_cast<unsigned char>(c[i]); // use unsigned char to zero-extend instead of sign-extend
    179     return result;
    180 }
    181 
    182 static inline PassRefPtr<UString::Rep> createRep(const char* c, int length)
    183 {
    184     if (!c)
    185         return &UString::Rep::null();
    186 
    187     if (!length)
    188         return &UString::Rep::empty();
    189 
    190     UChar* d;
    191     PassRefPtr<UStringImpl> result = UStringImpl::tryCreateUninitialized(length, d);
    192     if (!result)
    193         return &UString::Rep::null();
    194 
    195     for (int i = 0; i < length; i++)
    196         d[i] = static_cast<unsigned char>(c[i]); // use unsigned char to zero-extend instead of sign-extend
    197     return result;
     160
     161    UString::s_nullRep = new UStringImpl(0, 0, UStringImpl::ConstructStaticString);
     162    UString::s_nullUString = new UString;
    198163}
    199164
    200165UString::UString(const char* c)
    201     : m_rep(createRep(c))
     166    : m_rep(Rep::create(c))
    202167{
    203168}
    204169
    205170UString::UString(const char* c, int length)
    206     : m_rep(createRep(c, length))
     171    : m_rep(Rep::create(c, length))
    207172{
    208173}
     
    460425{
    461426    if (!c) {
    462         m_rep = &Rep::null();
     427        m_rep = s_nullRep;
    463428        return *this;
    464429    }
     
    476441            d[i] = static_cast<unsigned char>(c[i]); // use unsigned char to zero-extend instead of sign-extend
    477442    } else
    478         makeNull();
     443        m_rep = s_nullRep;;
    479444
    480445    return *this;
     
    889854}
    890855
    891 // For use in error handling code paths -- having this not be inlined helps avoid PIC branches to fetch the global on Mac OS X.
    892 NEVER_INLINE void UString::makeNull()
    893 {
    894     m_rep = &Rep::null();
    895 }
    896 
    897 // For use in error handling code paths -- having this not be inlined helps avoid PIC branches to fetch the global on Mac OS X.
    898 NEVER_INLINE UString::Rep* UString::nullRep()
    899 {
    900     return &Rep::null();
    901 }
    902 
    903856} // namespace JSC
Note: See TracChangeset for help on using the changeset viewer.