[webkit-changes] cvs commit: WebCore/khtml/ecma kjs_binding.cpp
Maciej
mjs at opensource.apple.com
Tue Dec 6 01:21:16 PST 2005
mjs 05/12/06 01:21:15
Modified: . ChangeLog
JavaScriptCore.xcodeproj project.pbxproj
kjs identifier.cpp identifier.h property_map.cpp
ustring.cpp ustring.h
kxmlcore RefPtr.h
. ChangeLog
khtml/ecma kjs_binding.cpp
Added: kxmlcore PassRefPtr.h
ForwardingHeaders/kxmlcore PassRefPtr.h
Log:
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):
Revision Changes Path
1.893 +54 -0 JavaScriptCore/ChangeLog
Index: ChangeLog
===================================================================
RCS file: /cvs/root/JavaScriptCore/ChangeLog,v
retrieving revision 1.892
retrieving revision 1.893
diff -u -r1.892 -r1.893
--- ChangeLog 4 Dec 2005 23:45:46 -0000 1.892
+++ ChangeLog 6 Dec 2005 09:20:58 -0000 1.893
@@ -1,3 +1,57 @@
+2005-12-05 Maciej Stachowiak <mjs at apple.com>
+
+ 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):
+
2005-12-04 Geoffrey Garen <ggaren at apple.com>
Update test results to match Anders's last checkin.
1.27 +4 -0 JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj
Index: project.pbxproj
===================================================================
RCS file: /cvs/root/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj,v
retrieving revision 1.26
retrieving revision 1.27
diff -u -r1.26 -r1.27
--- project.pbxproj 1 Dec 2005 10:31:58 -0000 1.26
+++ project.pbxproj 6 Dec 2005 09:21:02 -0000 1.27
@@ -33,6 +33,7 @@
6557E8F808EA5D4D0049CDFC /* HashMapPtrSpec.h in Headers */ = {isa = PBXBuildFile; fileRef = 6557E8F708EA5D4D0049CDFC /* HashMapPtrSpec.h */; settings = {ATTRIBUTES = (Private, ); }; };
65621E6D089E859700760F35 /* property_slot.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 65621E6B089E859700760F35 /* property_slot.cpp */; };
65621E6E089E859700760F35 /* property_slot.h in Headers */ = {isa = PBXBuildFile; fileRef = 65621E6C089E859700760F35 /* property_slot.h */; settings = {ATTRIBUTES = (Private, ); }; };
+ 6580F796094070560082C219 /* PassRefPtr.h in Headers */ = {isa = PBXBuildFile; fileRef = 6580F795094070560082C219 /* PassRefPtr.h */; settings = {ATTRIBUTES = (Private, ); }; };
65C647B4093EF8D60022C380 /* RefPtr.h in Headers */ = {isa = PBXBuildFile; fileRef = 65C647B3093EF8D60022C380 /* RefPtr.h */; settings = {ATTRIBUTES = (Private, ); }; };
65D7D19C08F10B5B0015ABD8 /* FastMallocInternal.h in Headers */ = {isa = PBXBuildFile; fileRef = 65D7D19B08F10B5B0015ABD8 /* FastMallocInternal.h */; };
65DFC93008EA173A00F7300B /* HashFunctions.h in Headers */ = {isa = PBXBuildFile; fileRef = 65DFC92A08EA173A00F7300B /* HashFunctions.h */; settings = {ATTRIBUTES = (Private, ); }; };
@@ -337,6 +338,7 @@
6560A63D04B3B69F008AE952 /* CoreServices.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreServices.framework; path = /System/Library/Frameworks/CoreServices.framework; sourceTree = "<absolute>"; };
65621E6B089E859700760F35 /* property_slot.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = property_slot.cpp; sourceTree = "<group>"; };
65621E6C089E859700760F35 /* property_slot.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = property_slot.h; sourceTree = "<group>"; };
+ 6580F795094070560082C219 /* PassRefPtr.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = PassRefPtr.h; sourceTree = "<group>"; };
65C02FBB0637462A003E7EE6 /* protect.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = protect.h; sourceTree = "<group>"; };
65C647B3093EF8D60022C380 /* RefPtr.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = RefPtr.h; sourceTree = "<group>"; };
65D7D19B08F10B5B0015ABD8 /* FastMallocInternal.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = FastMallocInternal.h; sourceTree = "<group>"; };
@@ -663,6 +665,7 @@
isa = PBXGroup;
children = (
65C647B3093EF8D60022C380 /* RefPtr.h */,
+ 6580F795094070560082C219 /* PassRefPtr.h */,
65D7D19B08F10B5B0015ABD8 /* FastMallocInternal.h */,
6557E8F708EA5D4D0049CDFC /* HashMapPtrSpec.h */,
65DFC92A08EA173A00F7300B /* HashFunctions.h */,
@@ -847,6 +850,7 @@
65D7D19C08F10B5B0015ABD8 /* FastMallocInternal.h in Headers */,
65EA4C9C092AF9E20093D800 /* JSLock.h in Headers */,
65C647B4093EF8D60022C380 /* RefPtr.h in Headers */,
+ 6580F796094070560082C219 /* PassRefPtr.h in Headers */,
);
runOnlyForDeploymentPostprocessing = 0;
};
1.23 +2 -2 JavaScriptCore/kjs/identifier.cpp
Index: identifier.cpp
===================================================================
RCS file: /cvs/root/JavaScriptCore/kjs/identifier.cpp,v
retrieving revision 1.22
retrieving revision 1.23
diff -u -r1.22 -r1.23
--- identifier.cpp 4 Oct 2005 01:43:58 -0000 1.22
+++ identifier.cpp 6 Dec 2005 09:21:04 -0000 1.23
@@ -131,7 +131,7 @@
for (int j = 0; j != length; j++)
d[j] = c[j];
- UString::Rep *r = UString::Rep::create(d, length);
+ UString::Rep *r = UString::Rep::create(d, length).release();
r->isIdentifier = 1;
r->rc = 0;
r->_hash = hash;
@@ -170,7 +170,7 @@
for (int j = 0; j != length; j++)
d[j] = s[j];
- UString::Rep *r = UString::Rep::create(d, length);
+ UString::Rep *r = UString::Rep::create(d, length).release();
r->isIdentifier = 1;
r->rc = 0;
r->_hash = hash;
1.20 +4 -3 JavaScriptCore/kjs/identifier.h
Index: identifier.h
===================================================================
RCS file: /cvs/root/JavaScriptCore/kjs/identifier.h,v
retrieving revision 1.19
retrieving revision 1.20
diff -u -r1.19 -r1.20
--- identifier.h 19 Sep 2005 06:57:27 -0000 1.19
+++ identifier.h 6 Dec 2005 09:21:04 -0000 1.20
@@ -34,7 +34,8 @@
Identifier() { }
Identifier(const char *s) : _ustring(add(s)) { }
Identifier(const UChar *s, int length) : _ustring(add(s, length)) { }
- explicit Identifier(const UString &s) : _ustring(add(s.rep)) { }
+ explicit Identifier(UString::Rep *rep) : _ustring(add(rep)) { }
+ explicit Identifier(const UString &s) : _ustring(add(s.rep())) { }
const UString &ustring() const { return _ustring; }
DOM::DOMString domString() const;
@@ -72,9 +73,9 @@
static bool equal(UString::Rep *, UString::Rep *);
static bool equal(const Identifier &a, const Identifier &b)
- { return a._ustring.rep == b._ustring.rep; }
+ { return a._ustring.rep() == b._ustring.rep(); }
static bool equal(const Identifier &a, const char *b)
- { return equal(a._ustring.rep, b); }
+ { return equal(a._ustring.rep(), b); }
static UString::Rep *add(const char *);
static UString::Rep *add(const UChar *, int length);
1.53 +5 -5 JavaScriptCore/kjs/property_map.cpp
Index: property_map.cpp
===================================================================
RCS file: /cvs/root/JavaScriptCore/kjs/property_map.cpp,v
retrieving revision 1.52
retrieving revision 1.53
diff -u -r1.52 -r1.53
--- property_map.cpp 16 Oct 2005 00:46:23 -0000 1.52
+++ property_map.cpp 6 Dec 2005 09:21:05 -0000 1.53
@@ -157,7 +157,7 @@
{
assert(!name.isNull());
- UString::Rep *rep = name._ustring.rep;
+ UString::Rep *rep = name._ustring.rep();
if (!_table) {
#if USE_SINGLE_ENTRY
@@ -198,7 +198,7 @@
{
assert(!name.isNull());
- UString::Rep *rep = name._ustring.rep;
+ UString::Rep *rep = name._ustring.rep();
if (!_table) {
#if USE_SINGLE_ENTRY
@@ -235,7 +235,7 @@
{
assert(!name.isNull());
- UString::Rep *rep = name._ustring.rep;
+ UString::Rep *rep = name._ustring.rep();
if (!_table) {
#if USE_SINGLE_ENTRY
@@ -295,7 +295,7 @@
checkConsistency();
- UString::Rep *rep = name._ustring.rep;
+ UString::Rep *rep = name._ustring.rep();
#if DEBUG_PROPERTIES
printf("adding property %s, attributes = 0x%08x (", name.ascii(), attributes);
@@ -470,7 +470,7 @@
checkConsistency();
- UString::Rep *rep = name._ustring.rep;
+ UString::Rep *rep = name._ustring.rep();
UString::Rep *key;
1.63 +75 -103 JavaScriptCore/kjs/ustring.cpp
Index: ustring.cpp
===================================================================
RCS file: /cvs/root/JavaScriptCore/kjs/ustring.cpp,v
retrieving revision 1.62
retrieving revision 1.63
diff -u -r1.62 -r1.63
--- ustring.cpp 6 Oct 2005 01:13:18 -0000 1.62
+++ ustring.cpp 6 Dec 2005 09:21:05 -0000 1.63
@@ -158,24 +158,24 @@
UCharReference& UCharReference::operator=(UChar c)
{
- str->detach();
- if (offset < str->rep->len)
- *(str->rep->data() + offset) = c;
+ str->copyForWriting();
+ if (offset < str->rep()->len)
+ *(str->rep()->data() + offset) = c;
/* TODO: lengthen string ? */
return *this;
}
UChar& UCharReference::ref() const
{
- if (offset < str->rep->len)
- return *(str->rep->data() + offset);
+ if (offset < str->rep()->len)
+ return *(str->rep()->data() + offset);
else {
static UChar callerBetterNotModifyThis('\0');
return callerBetterNotModifyThis;
}
}
-UString::Rep *UString::Rep::createCopying(const UChar *d, int l)
+PassRefPtr<UString::Rep> UString::Rep::createCopying(const UChar *d, int l)
{
int sizeInBytes = l * sizeof(UChar);
UChar *copyD = static_cast<UChar *>(fastMalloc(sizeInBytes));
@@ -184,12 +184,12 @@
return create(copyD, l);
}
-UString::Rep *UString::Rep::create(UChar *d, int l)
+PassRefPtr<UString::Rep> UString::Rep::create(UChar *d, int l)
{
Rep *r = new Rep;
r->offset = 0;
r->len = l;
- r->rc = 1;
+ r->rc = 0;
r->_hash = 0;
r->isIdentifier = 0;
r->baseString = 0;
@@ -201,7 +201,7 @@
return r;
}
-UString::Rep *UString::Rep::create(Rep *base, int offset, int length)
+PassRefPtr<UString::Rep> UString::Rep::create(PassRefPtr<Rep> base, int offset, int length)
{
assert(base);
@@ -220,8 +220,7 @@
r->rc = 1;
r->_hash = 0;
r->isIdentifier = 0;
- r->baseString = base;
- base->ref();
+ r->baseString = base.release();
r->buf = 0;
r->usedCapacity = 0;
r->capacity = 0;
@@ -345,17 +344,17 @@
inline int UString::usedCapacity() const
{
- return rep->baseString ? rep->baseString->usedCapacity : rep->usedCapacity;
+ return m_rep->baseString ? m_rep->baseString->usedCapacity : m_rep->usedCapacity;
}
inline int UString::usedPreCapacity() const
{
- return rep->baseString ? rep->baseString->usedPreCapacity : rep->usedPreCapacity;
+ return m_rep->baseString ? m_rep->baseString->usedPreCapacity : m_rep->usedPreCapacity;
}
void UString::expandCapacity(int requiredLength)
{
- Rep *r = rep->baseString ? rep->baseString : rep;
+ Rep *r = m_rep->baseString ? m_rep->baseString : rep();
if (requiredLength > r->capacity) {
int newCapacity = expandedSize(requiredLength, r->preCapacity);
@@ -369,7 +368,7 @@
void UString::expandPreCapacity(int requiredPreCap)
{
- Rep *r = rep->baseString ? rep->baseString : rep;
+ Rep *r = m_rep->baseString ? m_rep->baseString : rep();
if (requiredPreCap > r->preCapacity) {
int newCapacity = expandedSize(requiredPreCap, r->capacity);
@@ -392,64 +391,60 @@
{
UChar *d = static_cast<UChar *>(fastMalloc(sizeof(UChar)));
d[0] = c;
- rep = Rep::create(d, 1);
+ m_rep = Rep::create(d, 1);
}
UString::UString(const char *c)
{
if (!c) {
- attach(&Rep::null);
+ m_rep = &Rep::null;
return;
}
int length = strlen(c);
if (length == 0) {
- attach(&Rep::empty);
+ m_rep = &Rep::empty;
return;
}
UChar *d = static_cast<UChar *>(fastMalloc(sizeof(UChar) * length));
for (int i = 0; i < length; i++)
d[i].uc = c[i];
- rep = Rep::create(d, length);
+ m_rep = Rep::create(d, length);
}
UString::UString(const UChar *c, int length)
{
- if (length == 0) {
- attach(&Rep::empty);
- return;
- }
- rep = Rep::createCopying(c, length);
+ if (length == 0)
+ m_rep = &Rep::empty;
+ else
+ m_rep = Rep::createCopying(c, length);
}
UString::UString(UChar *c, int length, bool copy)
{
- if (length == 0) {
- attach(&Rep::empty);
- return;
- }
- if (copy) {
- rep = Rep::createCopying(c, length);
- } else {
- rep = Rep::create(c, length);
- }
+ if (length == 0)
+ m_rep = &Rep::empty;
+ else if (copy)
+ m_rep = Rep::createCopying(c, length);
+ else
+ m_rep = Rep::create(c, length);
}
UString::UString(const UString &a, const UString &b)
{
int aSize = a.size();
- int aOffset = a.rep->offset;
+ int aOffset = a.m_rep->offset;
int bSize = b.size();
- int bOffset = b.rep->offset;
+ int bOffset = b.m_rep->offset;
int length = aSize + bSize;
// possible cases:
if (aSize == 0) {
// a is empty
- attach(b.rep);
+ m_rep = b.m_rep;
} else if (bSize == 0) {
// b is empty
- attach(a.rep);
+ m_rep = a.m_rep;
} else if (aOffset + aSize == a.usedCapacity() && 4 * aSize >= bSize &&
(-bOffset != b.usedPreCapacity() || aSize >= bSize)) {
// - a reaches the end of its buffer so it qualifies for shared append
@@ -459,7 +454,7 @@
UString x(a);
x.expandCapacity(aOffset + length);
memcpy(const_cast<UChar *>(a.data() + aSize), b.data(), bSize * sizeof(UChar));
- rep = Rep::create(a.rep, 0, length);
+ m_rep = Rep::create(a.m_rep, 0, length);
} else if (-bOffset == b.usedPreCapacity() && 4 * bSize >= aSize) {
// - b reaches the beginning of its buffer so it qualifies for shared prepend
// - also, it's at least a quarter the length of a - prepending to a much shorter
@@ -467,15 +462,15 @@
UString y(b);
y.expandPreCapacity(-bOffset + aSize);
memcpy(const_cast<UChar *>(b.data() - aSize), a.data(), aSize * sizeof(UChar));
- rep = Rep::create(b.rep, -aSize, length);
+ m_rep = Rep::create(b.m_rep, -aSize, length);
} else {
// a does not qualify for append, and b does not qualify for prepend, gotta make a whole new string
int newCapacity = expandedSize(length, 0);
UChar *d = static_cast<UChar *>(fastMalloc(sizeof(UChar) * newCapacity));
memcpy(d, a.data(), aSize * sizeof(UChar));
memcpy(d + aSize, b.data(), bSize * sizeof(UChar));
- rep = Rep::create(d, length);
- rep->capacity = newCapacity;
+ m_rep = Rep::create(d, length);
+ m_rep->capacity = newCapacity;
}
}
@@ -657,11 +652,7 @@
}
}
- UString::Rep *rep = UString::Rep::create(buffer, totalLength);
- UString result = UString(rep);
- rep->deref();
-
- return result;
+ return UString(UString::Rep::create(buffer, totalLength));
}
@@ -669,7 +660,7 @@
UString &UString::append(const UString &t)
{
int thisSize = size();
- int thisOffset = rep->offset;
+ int thisOffset = m_rep->offset;
int tSize = t.size();
int length = thisSize + tSize;
@@ -679,28 +670,25 @@
*this = t;
} else if (tSize == 0) {
// t is empty
- } else if (!rep->baseString && rep->rc == 1) {
+ } else if (!m_rep->baseString && m_rep->rc == 1) {
// this is direct and has refcount of 1 (so we can just alter it directly)
expandCapacity(thisOffset + length);
memcpy(const_cast<UChar *>(data() + thisSize), t.data(), tSize * sizeof(UChar));
- rep->len = length;
- rep->_hash = 0;
+ m_rep->len = length;
+ m_rep->_hash = 0;
} else if (thisOffset + thisSize == usedCapacity()) {
// this reaches the end of the buffer - extend it
expandCapacity(thisOffset + length);
memcpy(const_cast<UChar *>(data() + thisSize), t.data(), tSize * sizeof(UChar));
- Rep *newRep = Rep::create(rep, 0, length);
- release();
- rep = newRep;
+ m_rep = Rep::create(m_rep, 0, length);
} else {
// this is shared with someone using more capacity, gotta make a whole new string
int newCapacity = expandedSize(length, 0);
UChar *d = static_cast<UChar *>(fastMalloc(sizeof(UChar) * newCapacity));
memcpy(d, data(), thisSize * sizeof(UChar));
memcpy(const_cast<UChar *>(d + thisSize), t.data(), tSize * sizeof(UChar));
- release();
- rep = Rep::create(d, length);
- rep->capacity = newCapacity;
+ m_rep = Rep::create(d, length);
+ m_rep->capacity = newCapacity;
}
return *this;
@@ -709,7 +697,7 @@
UString &UString::append(const char *t)
{
int thisSize = size();
- int thisOffset = rep->offset;
+ int thisOffset = m_rep->offset;
int tSize = strlen(t);
int length = thisSize + tSize;
@@ -719,23 +707,21 @@
*this = t;
} else if (tSize == 0) {
// t is empty, we'll just return *this below.
- } else if (!rep->baseString && rep->rc == 1) {
+ } else if (!m_rep->baseString && m_rep->rc == 1) {
// this is direct and has refcount of 1 (so we can just alter it directly)
expandCapacity(thisOffset + length);
UChar *d = const_cast<UChar *>(data());
for (int i = 0; i < tSize; ++i)
d[thisSize+i] = t[i];
- rep->len = length;
- rep->_hash = 0;
+ m_rep->len = length;
+ m_rep->_hash = 0;
} else if (thisOffset + thisSize == usedCapacity()) {
// this string reaches the end of the buffer - extend it
expandCapacity(thisOffset + length);
UChar *d = const_cast<UChar *>(data());
for (int i = 0; i < tSize; ++i)
d[thisSize+i] = t[i];
- Rep *newRep = Rep::create(rep, 0, length);
- release();
- rep = newRep;
+ m_rep = Rep::create(m_rep, 0, length);
} else {
// this is shared with someone using more capacity, gotta make a whole new string
int newCapacity = expandedSize(length, 0);
@@ -743,9 +729,8 @@
memcpy(d, data(), thisSize * sizeof(UChar));
for (int i = 0; i < tSize; ++i)
d[thisSize+i] = t[i];
- release();
- rep = Rep::create(d, length);
- rep->capacity = newCapacity;
+ m_rep = Rep::create(d, length);
+ m_rep->capacity = newCapacity;
}
return *this;
@@ -753,42 +738,38 @@
UString &UString::append(unsigned short c)
{
- int thisOffset = rep->offset;
+ int thisOffset = m_rep->offset;
int length = size();
// possible cases:
if (length == 0) {
- // this is empty - must make a new rep because we don't want to pollute the shared empty one
+ // this is empty - must make a new m_rep because we don't want to pollute the shared empty one
int newCapacity = expandedSize(1, 0);
UChar *d = static_cast<UChar *>(fastMalloc(sizeof(UChar) * newCapacity));
d[0] = c;
- release();
- rep = Rep::create(d, 1);
- rep->capacity = newCapacity;
- } else if (!rep->baseString && rep->rc == 1) {
+ m_rep = Rep::create(d, 1);
+ m_rep->capacity = newCapacity;
+ } else if (!m_rep->baseString && m_rep->rc == 1) {
// this is direct and has refcount of 1 (so we can just alter it directly)
expandCapacity(thisOffset + length + 1);
UChar *d = const_cast<UChar *>(data());
d[length] = c;
- rep->len = length + 1;
- rep->_hash = 0;
+ m_rep->len = length + 1;
+ m_rep->_hash = 0;
} else if (thisOffset + length == usedCapacity()) {
// this reaches the end of the string - extend it and share
expandCapacity(thisOffset + length + 1);
UChar *d = const_cast<UChar *>(data());
d[length] = c;
- Rep *newRep = Rep::create(rep, 0, length + 1);
- release();
- rep = newRep;
+ m_rep = Rep::create(m_rep, 0, length + 1);
} else {
// this is shared with someone using more capacity, gotta make a whole new string
int newCapacity = expandedSize((length + 1), 0);
UChar *d = static_cast<UChar *>(fastMalloc(sizeof(UChar) * newCapacity));
memcpy(d, data(), length * sizeof(UChar));
d[length] = c;
- release();
- rep = Rep::create(d, length);
- rep->capacity = newCapacity;
+ m_rep = Rep::create(d, length);
+ m_rep->capacity = newCapacity;
}
return *this;
@@ -840,13 +821,12 @@
{
int l = c ? strlen(c) : 0;
UChar *d;
- if (rep->rc == 1 && l <= rep->capacity && !rep->baseString && rep->offset == 0 && rep->preCapacity == 0) {
- d = rep->buf;
- rep->_hash = 0;
+ if (m_rep->rc == 1 && l <= m_rep->capacity && !m_rep->baseString && m_rep->offset == 0 && m_rep->preCapacity == 0) {
+ d = m_rep->buf;
+ m_rep->_hash = 0;
} else {
- release();
d = static_cast<UChar *>(fastMalloc(sizeof(UChar) * l));
- rep = Rep::create(d, l);
+ m_rep = Rep::create(d, l);
}
for (int i = 0; i < l; i++)
d[i].uc = c[i];
@@ -856,10 +836,7 @@
UString &UString::operator=(const UString &str)
{
- str.rep->ref();
- release();
- rep = str.rep;
-
+ m_rep = str.m_rep;
return *this;
}
@@ -1000,10 +977,10 @@
*ok = false;
// Empty string is not OK.
- int len = rep->len;
+ int len = m_rep->len;
if (len == 0)
return 0;
- const UChar *p = rep->data();
+ const UChar *p = m_rep->data();
unsigned short c = p->unicode();
// If the first digit is 0, only 0 itself is OK.
@@ -1140,31 +1117,26 @@
if (pos == 0 && len == s)
return *this;
- Rep *newRep = Rep::create(rep, pos, len);
- UString result(newRep);
- newRep->deref();
-
- return result;
+ return UString(Rep::create(m_rep, pos, len));
}
-void UString::detach()
+void UString::copyForWriting()
{
- if (rep->rc > 1 || rep->baseString) {
+ if (m_rep->rc > 1 || m_rep->baseString) {
int l = size();
UChar *n = static_cast<UChar *>(fastMalloc(sizeof(UChar) * l));
memcpy(n, data(), l * sizeof(UChar));
- release();
- rep = Rep::create(n, l);
+ m_rep = Rep::create(n, l);
}
}
bool operator==(const UString& s1, const UString& s2)
{
- if (s1.rep->len != s2.rep->len)
+ if (s1.m_rep->len != s2.m_rep->len)
return false;
- return (memcmp(s1.rep->data(), s2.rep->data(),
- s1.rep->len * sizeof(UChar)) == 0);
+ return (memcmp(s1.m_rep->data(), s2.m_rep->data(),
+ s1.m_rep->len * sizeof(UChar)) == 0);
}
bool operator==(const UString& s1, const char *s2)
1.45 +25 -21 JavaScriptCore/kjs/ustring.h
Index: ustring.h
===================================================================
RCS file: /cvs/root/JavaScriptCore/kjs/ustring.h,v
retrieving revision 1.44
retrieving revision 1.45
diff -u -r1.44 -r1.45
--- ustring.h 16 Oct 2005 00:46:23 -0000 1.44
+++ ustring.h 6 Dec 2005 09:21:06 -0000 1.45
@@ -25,6 +25,8 @@
#define _KJS_USTRING_H_
#include <kxmlcore/FastMalloc.h>
+#include <kxmlcore/RefPtr.h>
+#include <kxmlcore/PassRefPtr.h>
#if APPLE_CHANGES
#include <sys/types.h>
@@ -195,19 +197,20 @@
*/
class UString {
friend bool operator==(const UString&, const UString&);
- friend class UCharReference;
- friend class Identifier;
- friend class PropertyMap;
- friend class PropertyMapHashTableEntry;
+ public:
+ struct Rep;
+
+ private:
/**
* @internal
*/
struct Rep {
- static Rep *create(UChar *d, int l);
- static Rep *createCopying(const UChar *d, int l);
- static Rep *create(Rep *base, int offset, int length);
+ static PassRefPtr<Rep> create(UChar *d, int l);
+ static PassRefPtr<Rep> createCopying(const UChar *d, int l);
+ static PassRefPtr<Rep> create(PassRefPtr<Rep> base, int offset, int length);
+
void destroy();
UChar *data() const { return baseString ? (baseString->buf + baseString->preCapacity + offset) : (buf + preCapacity + offset); }
@@ -267,7 +270,7 @@
/**
* Copy constructor. Makes a shallow copy only.
*/
- UString(const UString &s) { attach(s.rep); }
+ UString(const UString &s) : m_rep(s.m_rep) {}
/**
* Convenience declaration only ! You'll be on your own to write the
* implementation for a construction from QString.
@@ -285,10 +288,9 @@
*/
UString(const UString &, const UString &);
/**
- * Destructor. If this handle was the only one holding a reference to the
- * string the data will be freed.
+ * Destructor.
*/
- ~UString() { release(); }
+ ~UString() {}
/**
* Constructs a string from an int.
@@ -375,15 +377,15 @@
/**
* @return A pointer to the internal Unicode data.
*/
- const UChar* data() const { return rep->data(); }
+ const UChar* data() const { return m_rep->data(); }
/**
* @return True if null.
*/
- bool isNull() const { return (rep == &Rep::null); }
+ bool isNull() const { return (m_rep == &Rep::null); }
/**
* @return True if null or zero length.
*/
- bool isEmpty() const { return (!rep->len); }
+ bool isEmpty() const { return (!m_rep->len); }
/**
* Use this if you want to make sure that this string is a plain ASCII
* string. For example, if you don't want to lose any information when
@@ -395,7 +397,7 @@
/**
* @return The length of the string.
*/
- int size() const { return rep->size(); }
+ int size() const { return m_rep->size(); }
/**
* Const character at specified position.
*/
@@ -461,18 +463,20 @@
*/
static void globalClear();
#endif
+
+ Rep *rep() const { return m_rep.get(); }
+ UString(PassRefPtr<Rep> r) { m_rep = r; }
+
+ void copyForWriting();
+
private:
- UString(Rep *r) { attach(r); }
- void attach(Rep *r) { rep = r; r->ref(); }
- void detach();
- void release() { rep->deref(); }
int expandedSize(int size, int otherSize) const;
int usedCapacity() const;
int usedPreCapacity() const;
void expandCapacity(int requiredLength);
void expandPreCapacity(int requiredPreCap);
- Rep *rep;
+ RefPtr<Rep> m_rep;
};
inline bool operator==(const UChar &c1, const UChar &c2) {
@@ -511,8 +515,8 @@
int decodeUTF8Sequence(const char *);
inline UString::UString()
+ : m_rep(&Rep::null)
{
- attach(&Rep::null);
}
} // namespace
1.3 +46 -20 JavaScriptCore/kxmlcore/RefPtr.h
Index: RefPtr.h
===================================================================
RCS file: /cvs/root/JavaScriptCore/kxmlcore/RefPtr.h,v
retrieving revision 1.2
retrieving revision 1.3
diff -u -r1.2 -r1.3
--- RefPtr.h 2 Dec 2005 03:48:00 -0000 1.2
+++ RefPtr.h 6 Dec 2005 09:21:08 -0000 1.3
@@ -20,25 +20,30 @@
*
*/
-#ifndef KXMLCORE_SHARED_PTR_H
-#define KXMLCORE_SHARED_PTR_H
+#ifndef KXMLCORE_REF_PTR_H
+#define KXMLCORE_REF_PTR_H
namespace KXMLCore {
- // FIXME: Change template name to RefPtr?
+ template <class T> class PassRefPtr;
+ template <class T> class PassRefPtr_Ref;
+
template <class T> class RefPtr
{
public:
RefPtr() : m_ptr(NULL) {}
RefPtr(T *ptr) : m_ptr(ptr) { if (ptr) ptr->ref(); }
- RefPtr(const RefPtr &o) : m_ptr(o.m_ptr) { if (T *ptr = m_ptr) ptr->ref(); }
+ RefPtr(const RefPtr& o) : m_ptr(o.m_ptr) { if (T *ptr = m_ptr) ptr->ref(); }
+ RefPtr(PassRefPtr<T>& o) : m_ptr(o.release()) {}
+
~RefPtr() { if (T *ptr = m_ptr) ptr->deref(); }
- template <class U> RefPtr(const RefPtr<U> &o) : m_ptr(o.get()) { if (T *ptr = m_ptr) ptr->ref(); }
+ template <class U> RefPtr(const RefPtr<U>& o) : m_ptr(o.get()) { if (T *ptr = m_ptr) ptr->ref(); }
+ template <class U> RefPtr(PassRefPtr<U>& o) : m_ptr(o.release()) { }
T *get() const { return m_ptr; }
- T &operator*() const { return *m_ptr; }
+ T& operator*() const { return *m_ptr; }
T *operator->() const { return m_ptr; }
bool operator!() const { return m_ptr == NULL; }
@@ -53,14 +58,16 @@
return m_ptr ? &RefPtr::get : 0;
}
- RefPtr &operator=(const RefPtr &);
- RefPtr &operator=(T *);
-
+ RefPtr& operator=(const RefPtr&);
+ RefPtr& operator=(T *);
+ RefPtr& operator=(PassRefPtr<T>&);
+ RefPtr& operator=(PassRefPtr_Ref<T>);
+
private:
T *m_ptr;
};
- template <class T> RefPtr<T> &RefPtr<T>::operator=(const RefPtr<T> &o)
+ template <class T> RefPtr<T>& RefPtr<T>::operator=(const RefPtr<T>& o)
{
T *optr = o.m_ptr;
if (optr)
@@ -71,7 +78,7 @@
return *this;
}
- template <class T> inline RefPtr<T> &RefPtr<T>::operator=(T *optr)
+ template <class T> inline RefPtr<T>& RefPtr<T>::operator=(T *optr)
{
if (optr)
optr->ref();
@@ -80,43 +87,62 @@
m_ptr = optr;
return *this;
}
+
+ template <class T> RefPtr<T>& RefPtr<T>::operator=(PassRefPtr_Ref<T> ref)
+ {
+ if (m_ptr)
+ m_ptr->deref();
+ m_ptr = ref.m_ptr;
+ return *this;
+ }
- template <class T> inline bool operator==(const RefPtr<T> &a, const RefPtr<T> &b)
+ template <class T> inline RefPtr<T>& RefPtr<T>::operator=(PassRefPtr<T>& o)
+ {
+ T *optr = o.release();
+ if (optr)
+ optr->ref();
+ if (T *ptr = m_ptr)
+ ptr->deref();
+ m_ptr = optr;
+ return *this;
+ }
+
+ template <class T> inline bool operator==(const RefPtr<T>& a, const RefPtr<T>& b)
{
return a.get() == b.get();
}
- template <class T> inline bool operator==(const RefPtr<T> &a, const T *b)
+ template <class T> inline bool operator==(const RefPtr<T>& a, const T *b)
{
return a.get() == b;
}
- template <class T> inline bool operator==(const T *a, const RefPtr<T> &b)
+ template <class T> inline bool operator==(const T *a, const RefPtr<T>& b)
{
return a == b.get();
}
- template <class T> inline bool operator!=(const RefPtr<T> &a, const RefPtr<T> &b)
+ template <class T> inline bool operator!=(const RefPtr<T>& a, const RefPtr<T>& b)
{
return a.get() != b.get();
}
- template <class T> inline bool operator!=(const RefPtr<T> &a, const T *b)
+ template <class T> inline bool operator!=(const RefPtr<T>& a, const T *b)
{
return a.get() != b;
}
- template <class T> inline bool operator!=(const T *a, const RefPtr<T> &b)
+ template <class T> inline bool operator!=(const T *a, const RefPtr<T>& b)
{
return a != b.get();
}
- template <class T, class U> inline RefPtr<T> static_pointer_cast(const RefPtr<U> &p)
+ template <class T, class U> inline RefPtr<T> static_pointer_cast(const RefPtr<U>& p)
{
return RefPtr<T>(static_cast<T *>(p.get()));
}
- template <class T, class U> inline RefPtr<T> const_pointer_cast(const RefPtr<U> &p)
+ template <class T, class U> inline RefPtr<T> const_pointer_cast(const RefPtr<U>& p)
{
return RefPtr<T>(const_cast<T *>(p.get()));
}
@@ -127,4 +153,4 @@
using KXMLCore::static_pointer_cast;
using KXMLCore::const_pointer_cast;
-#endif // KXMLCORE_SHARED_PTR_H
+#endif // KXMLCORE_REF_PTR_H
1.1 JavaScriptCore/kxmlcore/PassRefPtr.h
Index: PassRefPtr.h
===================================================================
// -*- mode: c++; c-basic-offset: 4 -*-
/*
* This file is part of the KDE libraries
* Copyright (C) 2005 Apple Computer, Inc.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Library General Public License for more details.
*
* You should have received a copy of the GNU Library General Public License
* along with this library; see the file COPYING.LIB. If not, write to
* the Free Software Foundation, Inc., 51 Franklin Steet, Fifth Floor,
* Boston, MA 02110-1301, USA.
*
*/
#ifndef KXMLCORE_PASS_REF_PTR_H
#define KXMLCORE_PASS_REF_PTR_H
namespace KXMLCore {
template<typename T> class RefPtr;
template<typename T> class PassRefPtr;
// PassRefPtr_Ref class is a helper to allow proper passing of PassRefPtr by value but not by const
// reference
template<typename T>
struct PassRefPtr_Ref
{
T* m_ptr;
explicit PassRefPtr_Ref(T* p) : m_ptr(p) {}
};
template<typename T>
class PassRefPtr
{
public:
PassRefPtr() : m_ptr(NULL) {}
PassRefPtr(T *ptr) : m_ptr(ptr) { if (ptr) ptr->ref(); }
PassRefPtr(const RefPtr<T>& o) : m_ptr(o.get()) { if (T *ptr = m_ptr) ptr->ref(); }
~PassRefPtr() { if (T *ptr = m_ptr) ptr->deref(); }
template <class U>
PassRefPtr(const RefPtr<U>& o) : m_ptr(o.get()) { if (T *ptr = m_ptr) ptr->ref(); }
T *get() const { return m_ptr; }
T *release() { T *tmp = m_ptr; m_ptr = 0; return tmp; }
static PassRefPtr<T> adopt(T *ptr)
{
PassRefPtr result;
result.m_ptr = ptr;
return result;
}
T& operator*() const { return *m_ptr; }
T *operator->() const { return m_ptr; }
bool operator!() const { return m_ptr == NULL; }
// this type conversion operator allows implicit conversion to
// bool but not to other integer types
typedef T * (PassRefPtr::*UnspecifiedBoolType)() const;
operator UnspecifiedBoolType() const
{
return m_ptr ? &PassRefPtr::get : 0;
}
PassRefPtr& operator=(const RefPtr<T>&);
PassRefPtr& operator=(T *);
PassRefPtr& operator=(PassRefPtr&);
PassRefPtr(PassRefPtr_Ref<T> ref) : m_ptr(ref.m_ptr) { }
PassRefPtr& operator=(PassRefPtr_Ref<T> ref)
{
if (m_ptr)
m_ptr->deref();
m_ptr = ref.m_ptr;
return *this;
}
template<typename U>
operator PassRefPtr_Ref<U>()
{
return PassRefPtr_Ref<U>(release());
}
template<typename U>
operator PassRefPtr<U>()
{
return PassRefPtr<U>(this->release());
}
private:
T *m_ptr;
};
template <class T> PassRefPtr<T>& PassRefPtr<T>::operator=(const RefPtr<T>& o)
{
T *optr = o.m_ptr;
if (optr)
optr->ref();
if (T *ptr = m_ptr)
ptr->deref();
m_ptr = optr;
return *this;
}
template <class T> inline PassRefPtr<T>& PassRefPtr<T>::operator=(T *optr)
{
if (optr)
optr->ref();
if (T *ptr = m_ptr)
ptr->deref();
m_ptr = optr;
return *this;
}
template <class T> PassRefPtr<T>& PassRefPtr<T>::operator=(PassRefPtr<T>& ref)
{
T *optr = o.release();
if (T *ptr = m_ptr)
ptr->deref();
m_ptr = optr;
return *this;
}
template <class T> inline bool operator==(const PassRefPtr<T>& a, const PassRefPtr<T>& b)
{
return a.get() == b.get();
}
template <class T> inline bool operator==(const PassRefPtr<T>& a, const RefPtr<T>& b)
{
return a.get() == b.get();
}
template <class T> inline bool operator==(const RefPtr<T>& a, const PassRefPtr<T>& b)
{
return a.get() == b.get();
}
template <class T> inline bool operator==(const PassRefPtr<T>& a, const T *b)
{
return a.get() == b;
}
template <class T> inline bool operator==(const T *a, const PassRefPtr<T>& b)
{
return a == b.get();
}
template <class T> inline bool operator!=(const PassRefPtr<T>& a, const PassRefPtr<T>& b)
{
return a.get() != b.get();
}
template <class T> inline bool operator!=(const PassRefPtr<T>& a, const RefPtr<T>& b)
{
return a.get() != b.get();
}
template <class T> inline bool operator!=(const RefPtr<T>& a, const PassRefPtr<T>& b)
{
return a.get() != b.get();
}
template <class T> inline bool operator!=(const PassRefPtr<T>& a, const T *b)
{
return a.get() != b;
}
template <class T> inline bool operator!=(const T *a, const PassRefPtr<T>& b)
{
return a != b.get();
}
template <class T, class U> inline PassRefPtr<T> static_pointer_cast(const PassRefPtr<U>& p)
{
return PassRefPtr<T>::adopt(static_cast<T *>(p.release()));
}
template <class T, class U> inline PassRefPtr<T> const_pointer_cast(const PassRefPtr<U>& p)
{
return PassRefPtr<T>::adopt(const_cast<T *>(p.release()));
}
} // namespace KXMLCore
using KXMLCore::PassRefPtr;
using KXMLCore::static_pointer_cast;
using KXMLCore::const_pointer_cast;
#endif // KXMLCORE_PASS_REF_PTR_H
1.482 +11 -0 WebCore/ChangeLog
Index: ChangeLog
===================================================================
RCS file: /cvs/root/WebCore/ChangeLog,v
retrieving revision 1.481
retrieving revision 1.482
diff -u -r1.481 -r1.482
--- ChangeLog 6 Dec 2005 04:29:18 -0000 1.481
+++ ChangeLog 6 Dec 2005 09:21:09 -0000 1.482
@@ -1,3 +1,14 @@
+2005-12-04 Maciej Stachowiak <mjs at apple.com>
+
+ 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):
+
2005-12-05 Justin Garcia <justin.garcia at apple.com>
<http://bugzilla.opendarwin.org/show_bug.cgi?id=5936>
1.1 WebCore/ForwardingHeaders/kxmlcore/PassRefPtr.h
Index: PassRefPtr.h
===================================================================
#import <JavaScriptCore/PassRefPtr.h>
1.48 +3 -3 WebCore/khtml/ecma/kjs_binding.cpp
Index: kjs_binding.cpp
===================================================================
RCS file: /cvs/root/WebCore/khtml/ecma/kjs_binding.cpp,v
retrieving revision 1.47
retrieving revision 1.48
diff -u -r1.47 -r1.48
--- kjs_binding.cpp 21 Nov 2005 01:19:54 -0000 1.47
+++ kjs_binding.cpp 6 Dec 2005 09:21:15 -0000 1.48
@@ -254,18 +254,18 @@
{
// reinterpret_cast is ugly but in this case safe, since QChar and UChar have the same
// memory layout
- rep = UString::Rep::createCopying(reinterpret_cast<const UChar *>(d.unicode()), d.length());
+ m_rep = UString::Rep::createCopying(reinterpret_cast<const UChar *>(d.unicode()), d.length());
}
UString::UString(const DOMString &d)
{
if (d.isNull()) {
- attach(&Rep::null);
+ m_rep = &Rep::null;
return;
}
// reinterpret_cast is ugly but in this case safe, since QChar and UChar have the same
// memory layout
- rep = UString::Rep::createCopying(reinterpret_cast<const UChar *>(d.unicode()), d.length());
+ m_rep = UString::Rep::createCopying(reinterpret_cast<const UChar *>(d.unicode()), d.length());
}
DOMString UString::domString() const
More information about the webkit-changes
mailing list