Changeset 51671 in webkit for trunk/JavaScriptCore/runtime/JSString.h
- Timestamp:
- Dec 3, 2009, 6:15:18 PM (15 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/JavaScriptCore/runtime/JSString.h
r49649 r51671 61 61 62 62 class JSString : public JSCell { 63 public: 63 64 friend class JIT; 64 65 friend struct VPtrSet; 65 66 66 public: 67 // A Rope is a string composed of a set of substrings. 68 class Rope : public RefCounted<Rope> { 69 public: 70 // A Rope is composed from a set of smaller strings called Fibers. 71 // Each Fiber in a rope is either UString::Rep or another Rope. 72 class Fiber { 73 public: 74 Fiber() {} 75 Fiber(UString::Rep* string) : m_value(reinterpret_cast<intptr_t>(string)) {} 76 Fiber(Rope* rope) : m_value(reinterpret_cast<intptr_t>(rope) | 1) {} 77 78 bool isRope() { return m_value & 1; } 79 Rope* rope() { return reinterpret_cast<Rope*>(m_value & ~1); } 80 bool isString() { return !isRope(); } 81 UString::Rep* string() { return reinterpret_cast<UString::Rep*>(m_value); } 82 83 private: 84 intptr_t m_value; 85 }; 86 87 // Creates a Rope comprising of 'ropeLength' Fibers. 88 // The Rope is constructed in an uninitialized state - initialize must be called for each Fiber in the Rope. 89 static PassRefPtr<Rope> create(unsigned ropeLength) { return adoptRef(new (ropeLength) Rope(ropeLength)); } 90 91 ~Rope(); 92 93 void initializeFiber(unsigned index, UString::Rep* string) 94 { 95 string->ref(); 96 m_fibers[index] = Fiber(string); 97 m_stringLength += string->len; 98 } 99 void initializeFiber(unsigned index, Rope* rope) 100 { 101 rope->ref(); 102 m_fibers[index] = Fiber(rope); 103 m_stringLength += rope->stringLength(); 104 } 105 void initializeFiber(unsigned index, JSString* jsString) 106 { 107 if (jsString->isRope()) 108 initializeFiber(index, jsString->rope()); 109 else 110 initializeFiber(index, jsString->string().rep()); 111 } 112 113 unsigned ropeLength() { return m_ropeLength; } 114 unsigned stringLength() { return m_stringLength; } 115 Fiber& fibers(unsigned index) { return m_fibers[index]; } 116 117 private: 118 Rope(unsigned ropeLength) : m_ropeLength(ropeLength), m_stringLength(0) {} 119 void* operator new(size_t, unsigned ropeLength) { return fastMalloc(sizeof(Rope) + (ropeLength - 1) * sizeof(UString::Rep*)); } 120 121 unsigned m_ropeLength; 122 unsigned m_stringLength; 123 Fiber m_fibers[1]; 124 }; 125 67 126 JSString(JSGlobalData* globalData, const UString& value) 68 127 : JSCell(globalData->stringStructure.get()) 128 , m_length(value.size()) 69 129 , m_value(value) 70 130 { … … 75 135 JSString(JSGlobalData* globalData, const UString& value, HasOtherOwnerType) 76 136 : JSCell(globalData->stringStructure.get()) 137 , m_length(value.size()) 77 138 , m_value(value) 78 139 { … … 80 141 JSString(JSGlobalData* globalData, PassRefPtr<UString::Rep> value, HasOtherOwnerType) 81 142 : JSCell(globalData->stringStructure.get()) 143 , m_length(value->size()) 82 144 , m_value(value) 83 145 { 84 146 } 147 JSString(JSGlobalData* globalData, PassRefPtr<JSString::Rope> rope) 148 : JSCell(globalData->stringStructure.get()) 149 , m_length(rope->stringLength()) 150 , m_rope(rope) 151 { 152 } 85 153 86 const UString& value() const { return m_value; } 154 const UString& value() const 155 { 156 if (m_rope) 157 resolveRope(); 158 return m_value; 159 } 160 unsigned length() { return m_length; } 161 162 bool isRope() const { return m_rope; } 163 Rope* rope() { ASSERT(isRope()); return m_rope.get(); } 164 UString& string() { ASSERT(!isRope()); return m_value; } 87 165 88 166 bool getStringPropertySlot(ExecState*, const Identifier& propertyName, PropertySlot&); … … 90 168 bool getStringPropertyDescriptor(ExecState*, const Identifier& propertyName, PropertyDescriptor&); 91 169 92 bool canGetIndex(unsigned i) { return i < static_cast<unsigned>(m_value.size()); }170 bool canGetIndex(unsigned i) { return i < m_length; } 93 171 JSString* getIndex(JSGlobalData*, unsigned); 94 172 … … 101 179 { 102 180 } 181 182 void resolveRope() const; 103 183 104 184 virtual JSValue toPrimitive(ExecState*, PreferredPrimitiveType) const; … … 118 198 virtual bool getOwnPropertyDescriptor(ExecState*, const Identifier&, PropertyDescriptor&); 119 199 120 UString m_value; 200 // A string is represented either by a UString or a Rope. 201 unsigned m_length; 202 mutable UString m_value; 203 mutable RefPtr<Rope> m_rope; 121 204 }; 122 205 … … 147 230 if (c <= 0xFF) 148 231 return globalData->smallStrings.singleCharacterString(globalData, c); 149 return new (globalData) JSString(globalData, UString ::Rep::create(s.rep(), offset, 1));232 return new (globalData) JSString(globalData, UString(UString::Rep::create(s.rep(), offset, 1))); 150 233 } 151 234 … … 167 250 { 168 251 ASSERT(canGetIndex(i)); 169 return jsSingleCharacterSubstring(globalData, m_value, i);252 return jsSingleCharacterSubstring(globalData, value(), i); 170 253 } 171 254 … … 195 278 return globalData->smallStrings.singleCharacterString(globalData, c); 196 279 } 197 return new (globalData) JSString(globalData, UString ::Rep::create(s.rep(), offset, length));280 return new (globalData) JSString(globalData, UString(UString::Rep::create(s.rep(), offset, length))); 198 281 } 199 282 … … 223 306 { 224 307 if (propertyName == exec->propertyNames().length) { 225 slot.setValue(jsNumber(exec, m_ value.size()));308 slot.setValue(jsNumber(exec, m_length)); 226 309 return true; 227 310 } … … 229 312 bool isStrictUInt32; 230 313 unsigned i = propertyName.toStrictUInt32(&isStrictUInt32); 231 if (isStrictUInt32 && i < static_cast<unsigned>(m_value.size())) {232 slot.setValue(jsSingleCharacterSubstring(exec, m_value, i));314 if (isStrictUInt32 && i < m_length) { 315 slot.setValue(jsSingleCharacterSubstring(exec, value(), i)); 233 316 return true; 234 317 } … … 239 322 ALWAYS_INLINE bool JSString::getStringPropertySlot(ExecState* exec, unsigned propertyName, PropertySlot& slot) 240 323 { 241 if (propertyName < static_cast<unsigned>(m_value.size())) {242 slot.setValue(jsSingleCharacterSubstring(exec, m_value, propertyName));324 if (propertyName < m_length) { 325 slot.setValue(jsSingleCharacterSubstring(exec, value(), propertyName)); 243 326 return true; 244 327 }
Note:
See TracChangeset
for help on using the changeset viewer.