Changeset 36006 in webkit for trunk/JavaScriptCore/kjs/ustring.cpp
- Timestamp:
- Aug 30, 2008, 11:58:07 PM (17 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/JavaScriptCore/kjs/ustring.cpp
r35691 r36006 395 395 396 396 // put these early so they can be inlined 397 inline size_t UString::expandedSize(size_t size, size_t otherSize) const397 inline size_t UString::expandedSize(size_t size, size_t otherSize) 398 398 { 399 399 // Do the size calculation in two parts, returning overflowIndicator if … … 432 432 if (!r->buf) { 433 433 r->buf = oldBuf; 434 m _rep = &Rep::null;434 makeNull(); 435 435 return; 436 436 } … … 455 455 UChar* newBuf = allocChars(newCapacity); 456 456 if (!newBuf) { 457 m _rep = &Rep::null;457 makeNull(); 458 458 return; 459 459 } … … 485 485 UChar* d = allocChars(length); 486 486 if (!d) 487 m _rep = &Rep::null;487 makeNull(); 488 488 else { 489 489 for (size_t i = 0; i < length; i++) … … 519 519 } 520 520 521 522 UString::UString(const UString& a, const UString& b) 523 { 524 a.rep()->checkConsistency(); 525 b.rep()->checkConsistency(); 526 527 int aSize = a.size(); 528 int aOffset = a.m_rep->offset; 529 int bSize = b.size(); 530 int bOffset = b.m_rep->offset; 521 PassRefPtr<UString::Rep> concatenate(UString::Rep* a, UString::Rep* b) 522 { 523 a->checkConsistency(); 524 b->checkConsistency(); 525 526 int aSize = a->size(); 527 int aOffset = a->offset; 528 int bSize = b->size(); 529 int bOffset = b->offset; 531 530 int length = aSize + bSize; 532 531 533 532 // possible cases: 534 533 535 if (aSize == 0) { 536 // a is empty 537 m_rep = b.m_rep; 538 } else if (bSize == 0) { 539 // b is empty 540 m_rep = a.m_rep; 541 } else if (aOffset + aSize == a.usedCapacity() && aSize >= minShareSize && 4 * aSize >= bSize && 542 (-bOffset != b.usedPreCapacity() || aSize >= bSize)) { 534 // a is empty 535 if (aSize == 0) 536 return b; 537 // b is empty 538 if (bSize == 0) 539 return a; 540 541 if (bSize == 1 && aOffset + aSize == a->baseString->usedCapacity && aOffset + length <= a->baseString->capacity) { 542 // b is a single character (common fast case) 543 a->baseString->usedCapacity = aOffset + length; 544 a->data()[aSize] = b->data()[0]; 545 return UString::Rep::create(a, 0, length); 546 } 547 548 if (aOffset + aSize == a->baseString->usedCapacity && aSize >= minShareSize && 4 * aSize >= bSize && 549 (-bOffset != b->baseString->usedPreCapacity || aSize >= bSize)) { 543 550 // - a reaches the end of its buffer so it qualifies for shared append 544 551 // - also, it's at least a quarter the length of b - appending to a much shorter … … 547 554 UString x(a); 548 555 x.expandCapacity(aOffset + length); 549 if (a.data() && x.data()) { 550 memcpy(const_cast<UChar*>(a.data() + aSize), b.data(), bSize * sizeof(UChar)); 551 m_rep = Rep::create(a.m_rep, 0, length); 552 } else 553 m_rep = &Rep::null; 554 } else if (-bOffset == b.usedPreCapacity() && bSize >= minShareSize && 4 * bSize >= aSize) { 556 if (!a->data() || !x.data()) 557 return 0; 558 memcpy(a->data() + aSize, b->data(), bSize * sizeof(UChar)); 559 PassRefPtr<UString::Rep> result = UString::Rep::create(a, 0, length); 560 561 a->checkConsistency(); 562 b->checkConsistency(); 563 result->checkConsistency(); 564 565 return result; 566 } 567 568 if (-bOffset == b->baseString->usedPreCapacity && bSize >= minShareSize && 4 * bSize >= aSize) { 555 569 // - b reaches the beginning of its buffer so it qualifies for shared prepend 556 570 // - also, it's at least a quarter the length of a - prepending to a much shorter … … 558 572 UString y(b); 559 573 y.expandPreCapacity(-bOffset + aSize); 560 if (b.data() && y.data()) { 561 memcpy(const_cast<UChar *>(b.data() - aSize), a.data(), aSize * sizeof(UChar)); 562 m_rep = Rep::create(b.m_rep, -aSize, length); 563 } else 564 m_rep = &Rep::null; 565 } else { 566 // a does not qualify for append, and b does not qualify for prepend, gotta make a whole new string 567 size_t newCapacity = expandedSize(length, 0); 568 UChar* d = allocChars(newCapacity); 569 if (!d) 570 m_rep = &Rep::null; 571 else { 572 memcpy(d, a.data(), aSize * sizeof(UChar)); 573 memcpy(d + aSize, b.data(), bSize * sizeof(UChar)); 574 m_rep = Rep::create(d, length); 575 m_rep->capacity = newCapacity; 576 } 577 } 578 a.rep()->checkConsistency(); 579 b.rep()->checkConsistency(); 580 m_rep->checkConsistency(); 574 if (!b->data() || !y.data()) 575 return 0; 576 memcpy(b->data() - aSize, a->data(), aSize * sizeof(UChar)); 577 PassRefPtr<UString::Rep> result = UString::Rep::create(b, -aSize, length); 578 579 a->checkConsistency(); 580 b->checkConsistency(); 581 result->checkConsistency(); 582 583 return result; 584 } 585 586 // a does not qualify for append, and b does not qualify for prepend, gotta make a whole new string 587 size_t newCapacity = UString::expandedSize(length, 0); 588 UChar* d = allocChars(newCapacity); 589 if (!d) 590 return 0; 591 memcpy(d, a->data(), aSize * sizeof(UChar)); 592 memcpy(d + aSize, b->data(), bSize * sizeof(UChar)); 593 PassRefPtr<UString::Rep> result = UString::Rep::create(d, length); 594 result->capacity = newCapacity; 595 596 a->checkConsistency(); 597 b->checkConsistency(); 598 result->checkConsistency(); 599 600 return result; 581 601 } 582 602 … … 807 827 UChar* d = allocChars(newCapacity); 808 828 if (!d) 809 m _rep = &Rep::null;829 makeNull(); 810 830 else { 811 831 memcpy(d, data(), thisSize * sizeof(UChar)); … … 856 876 UChar* d = allocChars(newCapacity); 857 877 if (!d) 858 m _rep = &Rep::null;878 makeNull(); 859 879 else { 860 880 memcpy(d, data(), thisSize * sizeof(UChar)); … … 909 929 UChar* d = allocChars(newCapacity); 910 930 if (!d) 911 m _rep = &Rep::null;931 makeNull(); 912 932 else { 913 933 memcpy(d, data(), thisSize * sizeof(UChar)); … … 937 957 UChar* d = allocChars(newCapacity); 938 958 if (!d) 939 m _rep = &Rep::null;959 makeNull(); 940 960 else { 941 961 d[0] = c; … … 965 985 UChar* d = allocChars(newCapacity); 966 986 if (!d) 967 m _rep = &Rep::null;987 makeNull(); 968 988 else { 969 989 memcpy(d, data(), length * sizeof(UChar)); … … 1043 1063 d = allocChars(l); 1044 1064 if (!d) { 1045 m _rep = &Rep::null;1065 makeNull(); 1046 1066 return *this; 1047 1067 } … … 1076 1096 double UString::toDouble(bool tolerateTrailingJunk, bool tolerateEmptyString) const 1077 1097 { 1078 double d; 1098 if (size() == 1) { 1099 UChar c = data()[0]; 1100 if (isASCIIDigit(c)) 1101 return c - '0'; 1102 if (isASCIISpace(c) && tolerateEmptyString) 1103 return 0; 1104 return NaN; 1105 } 1079 1106 1080 1107 // FIXME: If tolerateTrailingJunk is true, then we want to tolerate non-8-bit junk … … 1092 1119 if (*c == '\0') 1093 1120 return tolerateEmptyString ? 0.0 : NaN; 1121 1122 double d; 1094 1123 1095 1124 // hex number ? … … 1335 1364 bool operator==(const UString& s1, const UString& s2) 1336 1365 { 1337 if (s1.m_rep->len != s2.m_rep->len) 1338 return false; 1339 1340 return (memcmp(s1.m_rep->data(), s2.m_rep->data(), s1.m_rep->len * sizeof(UChar)) == 0); 1366 int size = s1.size(); 1367 switch (size) { 1368 case 0: 1369 return !s2.size(); 1370 case 1: 1371 return s2.size() == 1 && s1.data()[0] == s2.data()[0]; 1372 default: 1373 return s2.size() == size && memcmp(s1.data(), s2.data(), size * sizeof(UChar)) == 0; 1374 } 1341 1375 } 1342 1376 … … 1449 1483 } 1450 1484 1485 // For use in error handling code paths -- having this not be inlined helps avoid PIC branches to fetch the global on Mac OS X. 1486 NEVER_INLINE void UString::makeNull() 1487 { 1488 m_rep = &Rep::null; 1489 } 1490 1491 // For use in error handling code paths -- having this not be inlined helps avoid PIC branches to fetch the global on Mac OS X. 1492 NEVER_INLINE UString::Rep* UString::nullRep() 1493 { 1494 return &Rep::null; 1495 } 1496 1451 1497 } // namespace KJS
Note:
See TracChangeset
for help on using the changeset viewer.