Ignore:
Timestamp:
Dec 6, 2005, 1:21:15 AM (19 years ago)
Author:
mjs
Message:

JavaScriptCore:

Reviewed by Eric.

  • add PassRefPtr, a smart pointer class that works in conjunction with RefPtr but has transfer-of-ownership semantics
  • apply RefPtr and PassRefPtr to UString
  • cleaned up UString a little so that it doesn't need to have so many friend classes
  • JavaScriptCore.xcodeproj/project.pbxproj:
  • kjs/identifier.cpp: (KJS::Identifier::add):
  • kjs/identifier.h: (KJS::Identifier::Identifier): (KJS::Identifier::equal):
  • kjs/property_map.cpp: (KJS::PropertyMap::get): (KJS::PropertyMap::getLocation): (KJS::PropertyMap::put): (KJS::PropertyMap::remove):
  • kjs/ustring.cpp: (KJS::UCharReference::operator=): (KJS::UCharReference::ref): (KJS::UString::Rep::createCopying): (KJS::UString::Rep::create): (KJS::UString::usedCapacity): (KJS::UString::usedPreCapacity): (KJS::UString::expandCapacity): (KJS::UString::expandPreCapacity): (KJS::UString::UString): (KJS::UString::spliceSubstringsWithSeparators): (KJS::UString::append): (KJS::UString::operator=): (KJS::UString::toStrictUInt32): (KJS::UString::substr): (KJS::UString::copyForWriting): (KJS::operator==):
  • kjs/ustring.h: (KJS::UString::UString): (KJS::UString::~UString): (KJS::UString::data): (KJS::UString::isNull): (KJS::UString::isEmpty): (KJS::UString::size): (KJS::UString::rep):
  • kxmlcore/RefPtr.h: (KXMLCore::RefPtr::RefPtr): (KXMLCore::RefPtr::operator*): (KXMLCore::::operator): (KXMLCore::operator==): (KXMLCore::operator!=): (KXMLCore::static_pointer_cast): (KXMLCore::const_pointer_cast):

WebCore:

Reviewed by Eric.

  • add PassRefPtr, a smart pointer class that works in conjunction with RefPtr but has transfer-of-ownership semantics
  • apply RefPtr and PassRefPtr to UString
  • khtml/ecma/kjs_binding.cpp: (KJS::UString::UString):
File:
1 edited

Legend:

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

    r10757 r11472  
    159159UCharReference& UCharReference::operator=(UChar c)
    160160{
    161   str->detach();
    162   if (offset < str->rep->len)
    163     *(str->rep->data() + offset) = c;
     161  str->copyForWriting();
     162  if (offset < str->rep()->len)
     163    *(str->rep()->data() + offset) = c;
    164164  /* TODO: lengthen string ? */
    165165  return *this;
     
    168168UChar& UCharReference::ref() const
    169169{
    170   if (offset < str->rep->len)
    171     return *(str->rep->data() + offset);
     170  if (offset < str->rep()->len)
     171    return *(str->rep()->data() + offset);
    172172  else {
    173173    static UChar callerBetterNotModifyThis('\0');
     
    176176}
    177177
    178 UString::Rep *UString::Rep::createCopying(const UChar *d, int l)
     178PassRefPtr<UString::Rep> UString::Rep::createCopying(const UChar *d, int l)
    179179{
    180180  int sizeInBytes = l * sizeof(UChar);
     
    185185}
    186186
    187 UString::Rep *UString::Rep::create(UChar *d, int l)
     187PassRefPtr<UString::Rep> UString::Rep::create(UChar *d, int l)
    188188{
    189189  Rep *r = new Rep;
    190190  r->offset = 0;
    191191  r->len = l;
    192   r->rc = 1;
     192  r->rc = 0;
    193193  r->_hash = 0;
    194194  r->isIdentifier = 0;
     
    202202}
    203203
    204 UString::Rep *UString::Rep::create(Rep *base, int offset, int length)
     204PassRefPtr<UString::Rep> UString::Rep::create(PassRefPtr<Rep> base, int offset, int length)
    205205{
    206206  assert(base);
     
    221221  r->_hash = 0;
    222222  r->isIdentifier = 0;
    223   r->baseString = base;
    224   base->ref();
     223  r->baseString = base.release();
    225224  r->buf = 0;
    226225  r->usedCapacity = 0;
     
    346345inline int UString::usedCapacity() const
    347346{
    348   return rep->baseString ? rep->baseString->usedCapacity : rep->usedCapacity;
     347  return m_rep->baseString ? m_rep->baseString->usedCapacity : m_rep->usedCapacity;
    349348}
    350349
    351350inline int UString::usedPreCapacity() const
    352351{
    353   return rep->baseString ? rep->baseString->usedPreCapacity : rep->usedPreCapacity;
     352  return m_rep->baseString ? m_rep->baseString->usedPreCapacity : m_rep->usedPreCapacity;
    354353}
    355354
    356355void UString::expandCapacity(int requiredLength)
    357356{
    358   Rep *r = rep->baseString ? rep->baseString : rep;
     357  Rep *r = m_rep->baseString ? m_rep->baseString : rep();
    359358
    360359  if (requiredLength > r->capacity) {
     
    370369void UString::expandPreCapacity(int requiredPreCap)
    371370{
    372   Rep *r = rep->baseString ? rep->baseString : rep;
     371  Rep *r = m_rep->baseString ? m_rep->baseString : rep();
    373372
    374373  if (requiredPreCap > r->preCapacity) {
     
    393392    UChar *d = static_cast<UChar *>(fastMalloc(sizeof(UChar)));
    394393    d[0] = c;
    395     rep = Rep::create(d, 1);
     394    m_rep = Rep::create(d, 1);
    396395}
    397396
     
    399398{
    400399  if (!c) {
    401     attach(&Rep::null);
     400    m_rep = &Rep::null;
    402401    return;
    403402  }
    404403  int length = strlen(c);
    405404  if (length == 0) {
    406     attach(&Rep::empty);
     405    m_rep = &Rep::empty;
    407406    return;
    408407  }
     
    410409  for (int i = 0; i < length; i++)
    411410    d[i].uc = c[i];
    412   rep = Rep::create(d, length);
     411  m_rep = Rep::create(d, length);
    413412}
    414413
    415414UString::UString(const UChar *c, int length)
    416415{
    417   if (length == 0) {
    418     attach(&Rep::empty);
    419     return;
    420   }
    421   rep = Rep::createCopying(c, length);
     416  if (length == 0)
     417    m_rep = &Rep::empty;
     418  else
     419    m_rep = Rep::createCopying(c, length);
    422420}
    423421
    424422UString::UString(UChar *c, int length, bool copy)
    425423{
    426   if (length == 0) {
    427     attach(&Rep::empty);
    428     return;
    429   }
    430   if (copy) {
    431     rep = Rep::createCopying(c, length);
    432   } else {
    433     rep = Rep::create(c, length);
    434   }
     424  if (length == 0)
     425    m_rep = &Rep::empty;
     426  else if (copy)
     427    m_rep = Rep::createCopying(c, length);
     428  else
     429    m_rep = Rep::create(c, length);
    435430}
    436431
     
    438433{
    439434  int aSize = a.size();
    440   int aOffset = a.rep->offset;
     435  int aOffset = a.m_rep->offset;
    441436  int bSize = b.size();
    442   int bOffset = b.rep->offset;
     437  int bOffset = b.m_rep->offset;
    443438  int length = aSize + bSize;
    444439
     
    447442  if (aSize == 0) {
    448443    // a is empty
    449     attach(b.rep);
     444    m_rep = b.m_rep;
    450445  } else if (bSize == 0) {
    451446    // b is empty
    452     attach(a.rep);
     447    m_rep = a.m_rep;
    453448  } else if (aOffset + aSize == a.usedCapacity() && 4 * aSize >= bSize &&
    454449             (-bOffset != b.usedPreCapacity() || aSize >= bSize)) {
     
    460455    x.expandCapacity(aOffset + length);
    461456    memcpy(const_cast<UChar *>(a.data() + aSize), b.data(), bSize * sizeof(UChar));
    462     rep = Rep::create(a.rep, 0, length);
     457    m_rep = Rep::create(a.m_rep, 0, length);
    463458  } else if (-bOffset == b.usedPreCapacity() && 4 * bSize >= aSize) {
    464459    // - b reaches the beginning of its buffer so it qualifies for shared prepend
     
    468463    y.expandPreCapacity(-bOffset + aSize);
    469464    memcpy(const_cast<UChar *>(b.data() - aSize), a.data(), aSize * sizeof(UChar));
    470     rep = Rep::create(b.rep, -aSize, length);
     465    m_rep = Rep::create(b.m_rep, -aSize, length);
    471466  } else {
    472467    // a does not qualify for append, and b does not qualify for prepend, gotta make a whole new string
     
    475470    memcpy(d, a.data(), aSize * sizeof(UChar));
    476471    memcpy(d + aSize, b.data(), bSize * sizeof(UChar));
    477     rep = Rep::create(d, length);
    478     rep->capacity = newCapacity;
     472    m_rep = Rep::create(d, length);
     473    m_rep->capacity = newCapacity;
    479474  }
    480475}
     
    658653  }
    659654
    660   UString::Rep *rep = UString::Rep::create(buffer, totalLength);
    661   UString result = UString(rep);
    662   rep->deref();
    663 
    664   return result;
     655  return UString(UString::Rep::create(buffer, totalLength));
    665656}
    666657
     
    670661{
    671662  int thisSize = size();
    672   int thisOffset = rep->offset;
     663  int thisOffset = m_rep->offset;
    673664  int tSize = t.size();
    674665  int length = thisSize + tSize;
     
    680671  } else if (tSize == 0) {
    681672    // t is empty
    682   } else if (!rep->baseString && rep->rc == 1) {
     673  } else if (!m_rep->baseString && m_rep->rc == 1) {
    683674    // this is direct and has refcount of 1 (so we can just alter it directly)
    684675    expandCapacity(thisOffset + length);
    685676    memcpy(const_cast<UChar *>(data() + thisSize), t.data(), tSize * sizeof(UChar));
    686     rep->len = length;
    687     rep->_hash = 0;
     677    m_rep->len = length;
     678    m_rep->_hash = 0;
    688679  } else if (thisOffset + thisSize == usedCapacity()) {
    689680    // this reaches the end of the buffer - extend it
    690681    expandCapacity(thisOffset + length);
    691682    memcpy(const_cast<UChar *>(data() + thisSize), t.data(), tSize * sizeof(UChar));
    692     Rep *newRep = Rep::create(rep, 0, length);
    693     release();
    694     rep = newRep;
     683    m_rep = Rep::create(m_rep, 0, length);
    695684  } else {
    696685    // this is shared with someone using more capacity, gotta make a whole new string
     
    699688    memcpy(d, data(), thisSize * sizeof(UChar));
    700689    memcpy(const_cast<UChar *>(d + thisSize), t.data(), tSize * sizeof(UChar));
    701     release();
    702     rep = Rep::create(d, length);
    703     rep->capacity = newCapacity;
     690    m_rep = Rep::create(d, length);
     691    m_rep->capacity = newCapacity;
    704692  }
    705693
     
    710698{
    711699  int thisSize = size();
    712   int thisOffset = rep->offset;
     700  int thisOffset = m_rep->offset;
    713701  int tSize = strlen(t);
    714702  int length = thisSize + tSize;
     
    720708  } else if (tSize == 0) {
    721709    // t is empty, we'll just return *this below.
    722   } else if (!rep->baseString && rep->rc == 1) {
     710  } else if (!m_rep->baseString && m_rep->rc == 1) {
    723711    // this is direct and has refcount of 1 (so we can just alter it directly)
    724712    expandCapacity(thisOffset + length);
     
    726714    for (int i = 0; i < tSize; ++i)
    727715      d[thisSize+i] = t[i];
    728     rep->len = length;
    729     rep->_hash = 0;
     716    m_rep->len = length;
     717    m_rep->_hash = 0;
    730718  } else if (thisOffset + thisSize == usedCapacity()) {
    731719    // this string reaches the end of the buffer - extend it
     
    734722    for (int i = 0; i < tSize; ++i)
    735723      d[thisSize+i] = t[i];
    736     Rep *newRep = Rep::create(rep, 0, length);
    737     release();
    738     rep = newRep;
     724    m_rep = Rep::create(m_rep, 0, length);
    739725  } else {
    740726    // this is shared with someone using more capacity, gotta make a whole new string
     
    744730    for (int i = 0; i < tSize; ++i)
    745731      d[thisSize+i] = t[i];
    746     release();
    747     rep = Rep::create(d, length);
    748     rep->capacity = newCapacity;
     732    m_rep = Rep::create(d, length);
     733    m_rep->capacity = newCapacity;
    749734  }
    750735
     
    754739UString &UString::append(unsigned short c)
    755740{
    756   int thisOffset = rep->offset;
     741  int thisOffset = m_rep->offset;
    757742  int length = size();
    758743
    759744  // possible cases:
    760745  if (length == 0) {
    761     // this is empty - must make a new rep because we don't want to pollute the shared empty one
     746    // this is empty - must make a new m_rep because we don't want to pollute the shared empty one
    762747    int newCapacity = expandedSize(1, 0);
    763748    UChar *d = static_cast<UChar *>(fastMalloc(sizeof(UChar) * newCapacity));
    764749    d[0] = c;
    765     release();
    766     rep = Rep::create(d, 1);
    767     rep->capacity = newCapacity;
    768   } else if (!rep->baseString && rep->rc == 1) {
     750    m_rep = Rep::create(d, 1);
     751    m_rep->capacity = newCapacity;
     752  } else if (!m_rep->baseString && m_rep->rc == 1) {
    769753    // this is direct and has refcount of 1 (so we can just alter it directly)
    770754    expandCapacity(thisOffset + length + 1);
    771755    UChar *d = const_cast<UChar *>(data());
    772756    d[length] = c;
    773     rep->len = length + 1;
    774     rep->_hash = 0;
     757    m_rep->len = length + 1;
     758    m_rep->_hash = 0;
    775759  } else if (thisOffset + length == usedCapacity()) {
    776760    // this reaches the end of the string - extend it and share
     
    778762    UChar *d = const_cast<UChar *>(data());
    779763    d[length] = c;
    780     Rep *newRep = Rep::create(rep, 0, length + 1);
    781     release();
    782     rep = newRep;
     764    m_rep = Rep::create(m_rep, 0, length + 1);
    783765  } else {
    784766    // this is shared with someone using more capacity, gotta make a whole new string
     
    787769    memcpy(d, data(), length * sizeof(UChar));
    788770    d[length] = c;
    789     release();
    790     rep = Rep::create(d, length);
    791     rep->capacity = newCapacity;
     771    m_rep = Rep::create(d, length);
     772    m_rep->capacity = newCapacity;
    792773  }
    793774
     
    841822  int l = c ? strlen(c) : 0;
    842823  UChar *d;
    843   if (rep->rc == 1 && l <= rep->capacity && !rep->baseString && rep->offset == 0 && rep->preCapacity == 0) {
    844     d = rep->buf;
    845     rep->_hash = 0;
     824  if (m_rep->rc == 1 && l <= m_rep->capacity && !m_rep->baseString && m_rep->offset == 0 && m_rep->preCapacity == 0) {
     825    d = m_rep->buf;
     826    m_rep->_hash = 0;
    846827  } else {
    847     release();
    848828    d = static_cast<UChar *>(fastMalloc(sizeof(UChar) * l));
    849     rep = Rep::create(d, l);
     829    m_rep = Rep::create(d, l);
    850830  }
    851831  for (int i = 0; i < l; i++)
     
    857837UString &UString::operator=(const UString &str)
    858838{
    859   str.rep->ref();
    860   release();
    861   rep = str.rep;
    862 
     839  m_rep = str.m_rep;
    863840  return *this;
    864841}
     
    1001978
    1002979  // Empty string is not OK.
    1003   int len = rep->len;
     980  int len = m_rep->len;
    1004981  if (len == 0)
    1005982    return 0;
    1006   const UChar *p = rep->data();
     983  const UChar *p = m_rep->data();
    1007984  unsigned short c = p->unicode();
    1008985
     
    11411118    return *this;
    11421119
    1143   Rep *newRep = Rep::create(rep, pos, len);
    1144   UString result(newRep);
    1145   newRep->deref();
    1146 
    1147   return result;
    1148 }
    1149 
    1150 void UString::detach()
    1151 {
    1152   if (rep->rc > 1 || rep->baseString) {
     1120  return UString(Rep::create(m_rep, pos, len));
     1121}
     1122
     1123void UString::copyForWriting()
     1124{
     1125  if (m_rep->rc > 1 || m_rep->baseString) {
    11531126    int l = size();
    11541127    UChar *n = static_cast<UChar *>(fastMalloc(sizeof(UChar) * l));
    11551128    memcpy(n, data(), l * sizeof(UChar));
    1156     release();
    1157     rep = Rep::create(n, l);
     1129    m_rep = Rep::create(n, l);
    11581130  }
    11591131}
     
    11611133bool operator==(const UString& s1, const UString& s2)
    11621134{
    1163   if (s1.rep->len != s2.rep->len)
     1135  if (s1.m_rep->len != s2.m_rep->len)
    11641136    return false;
    11651137
    1166   return (memcmp(s1.rep->data(), s2.rep->data(),
    1167                  s1.rep->len * sizeof(UChar)) == 0);
     1138  return (memcmp(s1.m_rep->data(), s2.m_rep->data(),
     1139                 s1.m_rep->len * sizeof(UChar)) == 0);
    11681140}
    11691141
Note: See TracChangeset for help on using the changeset viewer.