diff options
Diffstat (limited to 'JavaScriptCore/runtime/UString.h')
-rw-r--r-- | JavaScriptCore/runtime/UString.h | 193 |
1 files changed, 107 insertions, 86 deletions
diff --git a/JavaScriptCore/runtime/UString.h b/JavaScriptCore/runtime/UString.h index 7d9ec49..da1065e 100644 --- a/JavaScriptCore/runtime/UString.h +++ b/JavaScriptCore/runtime/UString.h @@ -31,9 +31,9 @@ #include <wtf/CrossThreadRefCounted.h> #include <wtf/OwnFastMallocPtr.h> #include <wtf/PassRefPtr.h> -#include <wtf/PtrAndFlags.h> #include <wtf/RefPtr.h> #include <wtf/Vector.h> +#include <wtf/text/CString.h> #include <wtf/unicode/Unicode.h> namespace JSC { @@ -41,39 +41,6 @@ namespace JSC { using WTF::PlacementNewAdoptType; using WTF::PlacementNewAdopt; - class CString { - public: - CString() - : m_length(0) - , m_data(0) - { - } - - CString(const char*); - CString(const char*, size_t); - CString(const CString&); - - ~CString(); - - static CString adopt(char*, size_t); // buffer should be allocated with new[]. - - CString& append(const CString&); - CString& operator=(const char* c); - CString& operator=(const CString&); - CString& operator+=(const CString& c) { return append(c); } - - size_t size() const { return m_length; } - const char* c_str() const { return m_data; } - - private: - size_t m_length; - char* m_data; - }; - - bool operator==(const CString&, const CString&); - - typedef Vector<char, 32> CStringBuffer; - class UString { friend class JIT; @@ -81,10 +48,10 @@ namespace JSC { typedef UStringImpl Rep; public: - UString(); + UString() {} UString(const char*); // Constructor for null-terminated string. - UString(const char*, int length); - UString(const UChar*, int length); + UString(const char*, unsigned length); + UString(const UChar*, unsigned length); UString(const Vector<UChar>& buffer); UString(const UString& s) @@ -98,10 +65,6 @@ namespace JSC { { } - ~UString() - { - } - template<size_t inlineCapacity> static PassRefPtr<UStringImpl> adopt(Vector<UChar, inlineCapacity>& vector) { @@ -110,12 +73,10 @@ namespace JSC { static UString from(int); static UString from(long long); - static UString from(unsigned int); + static UString from(unsigned); static UString from(long); static UString from(double); - bool getCString(CStringBuffer&) const; - // NOTE: This method should only be used for *debugging* purposes as it // is neither Unicode safe nor free from side effects nor thread-safe. char* ascii() const; @@ -130,16 +91,26 @@ namespace JSC { */ CString UTF8String(bool strict = false) const; - const UChar* data() const { return m_rep->data(); } + const UChar* data() const + { + if (!m_rep) + return 0; + return m_rep->characters(); + } - bool isNull() const { return m_rep == s_nullRep; } - bool isEmpty() const { return !m_rep->size(); } + unsigned size() const + { + if (!m_rep) + return 0; + return m_rep->length(); + } - bool is8Bit() const; + bool isNull() const { return !m_rep; } + bool isEmpty() const { return !m_rep || !m_rep->length(); } - int size() const { return m_rep->size(); } + bool is8Bit() const; - UChar operator[](int pos) const; + UChar operator[](unsigned pos) const; double toDouble(bool tolerateTrailingJunk, bool tolerateEmptyString) const; double toDouble(bool tolerateTrailingJunk) const; @@ -151,12 +122,13 @@ namespace JSC { unsigned toArrayIndex(bool* ok = 0) const; - int find(const UString& f, int pos = 0) const; - int find(UChar, int pos = 0) const; - int rfind(const UString& f, int pos) const; - int rfind(UChar, int pos) const; + static const unsigned NotFound = 0xFFFFFFFFu; + unsigned find(const UString& f, unsigned pos = 0) const; + unsigned find(UChar, unsigned pos = 0) const; + unsigned rfind(const UString& f, unsigned pos) const; + unsigned rfind(UChar, unsigned pos) const; - UString substr(int pos = 0, int len = -1) const; + UString substr(unsigned pos = 0, unsigned len = 0xFFFFFFFF) const; static const UString& null() { return *s_nullUString; } @@ -165,15 +137,18 @@ namespace JSC { UString(PassRefPtr<Rep> r) : m_rep(r) { - ASSERT(m_rep); } - size_t cost() const { return m_rep->cost(); } + size_t cost() const + { + if (!m_rep) + return 0; + return m_rep->cost(); + } private: RefPtr<Rep> m_rep; - JS_EXPORTDATA static Rep* s_nullRep; static UString* s_nullUString; friend void initializeUString(); @@ -182,7 +157,7 @@ namespace JSC { ALWAYS_INLINE bool operator==(const UString& s1, const UString& s2) { - int size = s1.size(); + unsigned size = s1.size(); switch (size) { case 0: return !s2.size(); @@ -228,11 +203,6 @@ namespace JSC { int compare(const UString&, const UString&); - inline UString::UString() - : m_rep(s_nullRep) - { - } - // Rule from ECMA 15.2 about what an array index is. // Must exactly match string form of an unsigned integer, and be less than 2^32 - 1. inline unsigned UString::toArrayIndex(bool* ok) const @@ -246,9 +216,7 @@ namespace JSC { // We'd rather not do shared substring append for small strings, since // this runs too much risk of a tiny initial string holding down a // huge buffer. - // FIXME: this should be size_t but that would cause warnings until we - // fix UString sizes to be size_t instead of int - static const int minShareSize = Heap::minExtraCost / sizeof(UChar); + static const unsigned minShareSize = Heap::minExtraCost / sizeof(UChar); struct IdentifierRepHash : PtrHash<RefPtr<JSC::UString::Rep> > { static unsigned hash(const RefPtr<JSC::UString::Rep>& key) { return key->existingHash(); } @@ -327,6 +295,14 @@ namespace JSC { unsigned m_length; }; + inline void sumWithOverflow(unsigned& total, unsigned addend, bool& overflow) + { + unsigned oldTotal = total; + total = oldTotal + addend; + if (total < oldTotal) + overflow = true; + } + template<typename StringType1, typename StringType2> PassRefPtr<UStringImpl> tryMakeString(StringType1 string1, StringType2 string2) { @@ -334,7 +310,11 @@ namespace JSC { StringTypeAdapter<StringType2> adapter2(string2); UChar* buffer; - unsigned length = adapter1.length() + adapter2.length(); + bool overflow = false; + unsigned length = adapter1.length(); + sumWithOverflow(length, adapter2.length(), overflow); + if (overflow) + return 0; PassRefPtr<UStringImpl> resultImpl = UStringImpl::tryCreateUninitialized(length, buffer); if (!resultImpl) return 0; @@ -355,7 +335,12 @@ namespace JSC { StringTypeAdapter<StringType3> adapter3(string3); UChar* buffer; - unsigned length = adapter1.length() + adapter2.length() + adapter3.length(); + bool overflow = false; + unsigned length = adapter1.length(); + sumWithOverflow(length, adapter2.length(), overflow); + sumWithOverflow(length, adapter3.length(), overflow); + if (overflow) + return 0; PassRefPtr<UStringImpl> resultImpl = UStringImpl::tryCreateUninitialized(length, buffer); if (!resultImpl) return 0; @@ -379,7 +364,13 @@ namespace JSC { StringTypeAdapter<StringType4> adapter4(string4); UChar* buffer; - unsigned length = adapter1.length() + adapter2.length() + adapter3.length() + adapter4.length(); + bool overflow = false; + unsigned length = adapter1.length(); + sumWithOverflow(length, adapter2.length(), overflow); + sumWithOverflow(length, adapter3.length(), overflow); + sumWithOverflow(length, adapter4.length(), overflow); + if (overflow) + return 0; PassRefPtr<UStringImpl> resultImpl = UStringImpl::tryCreateUninitialized(length, buffer); if (!resultImpl) return 0; @@ -406,7 +397,14 @@ namespace JSC { StringTypeAdapter<StringType5> adapter5(string5); UChar* buffer; - unsigned length = adapter1.length() + adapter2.length() + adapter3.length() + adapter4.length() + adapter5.length(); + bool overflow = false; + unsigned length = adapter1.length(); + sumWithOverflow(length, adapter2.length(), overflow); + sumWithOverflow(length, adapter3.length(), overflow); + sumWithOverflow(length, adapter4.length(), overflow); + sumWithOverflow(length, adapter5.length(), overflow); + if (overflow) + return 0; PassRefPtr<UStringImpl> resultImpl = UStringImpl::tryCreateUninitialized(length, buffer); if (!resultImpl) return 0; @@ -436,7 +434,15 @@ namespace JSC { StringTypeAdapter<StringType6> adapter6(string6); UChar* buffer; - unsigned length = adapter1.length() + adapter2.length() + adapter3.length() + adapter4.length() + adapter5.length() + adapter6.length(); + bool overflow = false; + unsigned length = adapter1.length(); + sumWithOverflow(length, adapter2.length(), overflow); + sumWithOverflow(length, adapter3.length(), overflow); + sumWithOverflow(length, adapter4.length(), overflow); + sumWithOverflow(length, adapter5.length(), overflow); + sumWithOverflow(length, adapter6.length(), overflow); + if (overflow) + return 0; PassRefPtr<UStringImpl> resultImpl = UStringImpl::tryCreateUninitialized(length, buffer); if (!resultImpl) return 0; @@ -469,7 +475,16 @@ namespace JSC { StringTypeAdapter<StringType7> adapter7(string7); UChar* buffer; - unsigned length = adapter1.length() + adapter2.length() + adapter3.length() + adapter4.length() + adapter5.length() + adapter6.length() + adapter7.length(); + bool overflow = false; + unsigned length = adapter1.length(); + sumWithOverflow(length, adapter2.length(), overflow); + sumWithOverflow(length, adapter3.length(), overflow); + sumWithOverflow(length, adapter4.length(), overflow); + sumWithOverflow(length, adapter5.length(), overflow); + sumWithOverflow(length, adapter6.length(), overflow); + sumWithOverflow(length, adapter7.length(), overflow); + if (overflow) + return 0; PassRefPtr<UStringImpl> resultImpl = UStringImpl::tryCreateUninitialized(length, buffer); if (!resultImpl) return 0; @@ -505,7 +520,17 @@ namespace JSC { StringTypeAdapter<StringType8> adapter8(string8); UChar* buffer; - unsigned length = adapter1.length() + adapter2.length() + adapter3.length() + adapter4.length() + adapter5.length() + adapter6.length() + adapter7.length() + adapter8.length(); + bool overflow = false; + unsigned length = adapter1.length(); + sumWithOverflow(length, adapter2.length(), overflow); + sumWithOverflow(length, adapter3.length(), overflow); + sumWithOverflow(length, adapter4.length(), overflow); + sumWithOverflow(length, adapter5.length(), overflow); + sumWithOverflow(length, adapter6.length(), overflow); + sumWithOverflow(length, adapter7.length(), overflow); + sumWithOverflow(length, adapter8.length(), overflow); + if (overflow) + return 0; PassRefPtr<UStringImpl> resultImpl = UStringImpl::tryCreateUninitialized(length, buffer); if (!resultImpl) return 0; @@ -602,7 +627,7 @@ namespace WTF { template<> struct StrHash<JSC::UString::Rep*> { static unsigned hash(const JSC::UString::Rep* key) { return key->hash(); } - static bool equal(const JSC::UString::Rep* a, const JSC::UString::Rep* b) { return JSC::equal(a, b); } + static bool equal(const JSC::UString::Rep* a, const JSC::UString::Rep* b) { return ::equal(a, b); } static const bool safeToCompareToEmptyOrDeleted = false; }; @@ -610,22 +635,18 @@ namespace WTF { using StrHash<JSC::UString::Rep*>::hash; static unsigned hash(const RefPtr<JSC::UString::Rep>& key) { return key->hash(); } using StrHash<JSC::UString::Rep*>::equal; - static bool equal(const RefPtr<JSC::UString::Rep>& a, const RefPtr<JSC::UString::Rep>& b) { return JSC::equal(a.get(), b.get()); } - static bool equal(const JSC::UString::Rep* a, const RefPtr<JSC::UString::Rep>& b) { return JSC::equal(a, b.get()); } - static bool equal(const RefPtr<JSC::UString::Rep>& a, const JSC::UString::Rep* b) { return JSC::equal(a.get(), b); } + static bool equal(const RefPtr<JSC::UString::Rep>& a, const RefPtr<JSC::UString::Rep>& b) { return ::equal(a.get(), b.get()); } + static bool equal(const JSC::UString::Rep* a, const RefPtr<JSC::UString::Rep>& b) { return ::equal(a, b.get()); } + static bool equal(const RefPtr<JSC::UString::Rep>& a, const JSC::UString::Rep* b) { return ::equal(a.get(), b); } static const bool safeToCompareToEmptyOrDeleted = false; }; - template<> struct DefaultHash<JSC::UString::Rep*> { - typedef StrHash<JSC::UString::Rep*> Hash; - }; - - template<> struct DefaultHash<RefPtr<JSC::UString::Rep> > { - typedef StrHash<RefPtr<JSC::UString::Rep> > Hash; - + template <> struct VectorTraits<JSC::UString> : SimpleClassVectorTraits + { + static const bool canInitializeWithMemset = true; }; - + } // namespace WTF #endif |