diff options
author | Jocelyn Turcotte <jocelyn.turcotte@nokia.com> | 2010-04-06 10:36:47 (GMT) |
---|---|---|
committer | Jocelyn Turcotte <jocelyn.turcotte@nokia.com> | 2010-04-06 10:36:47 (GMT) |
commit | bb35b65bbfba82e0dd0ac306d3dab54436cdaff6 (patch) | |
tree | 8174cb262a960ff7b2e4aa8f1aaf154db71d2636 /src/3rdparty/webkit/JavaScriptCore/runtime/JSString.cpp | |
parent | 4b27d0d887269583a0f76e922948f8c25e96ab88 (diff) | |
download | Qt-bb35b65bbfba82e0dd0ac306d3dab54436cdaff6.zip Qt-bb35b65bbfba82e0dd0ac306d3dab54436cdaff6.tar.gz Qt-bb35b65bbfba82e0dd0ac306d3dab54436cdaff6.tar.bz2 |
Update src/3rdparty/webkit from trunk.
Imported from 839d8709327f925aacb3b6362c06152594def97e
in branch qtwebkit-2.0 of repository
git://gitorious.org/+qtwebkit-developers/webkit/qtwebkit.git
Rubber-stamped-by: Simon Hausmann
Diffstat (limited to 'src/3rdparty/webkit/JavaScriptCore/runtime/JSString.cpp')
-rw-r--r-- | src/3rdparty/webkit/JavaScriptCore/runtime/JSString.cpp | 112 |
1 files changed, 99 insertions, 13 deletions
diff --git a/src/3rdparty/webkit/JavaScriptCore/runtime/JSString.cpp b/src/3rdparty/webkit/JavaScriptCore/runtime/JSString.cpp index 20ba868..815198b 100644 --- a/src/3rdparty/webkit/JavaScriptCore/runtime/JSString.cpp +++ b/src/3rdparty/webkit/JavaScriptCore/runtime/JSString.cpp @@ -25,41 +25,127 @@ #include "JSGlobalObject.h" #include "JSObject.h" +#include "Operations.h" #include "StringObject.h" #include "StringPrototype.h" namespace JSC { +// Overview: this methods converts a JSString from holding a string in rope form +// down to a simple UString representation. It does so by building up the string +// backwards, since we want to avoid recursion, we expect that the tree structure +// representing the rope is likely imbalanced with more nodes down the left side +// (since appending to the string is likely more common) - and as such resolving +// in this fashion should minimize work queue size. (If we built the queue forwards +// we would likely have to place all of the constituent UStringImpls into the +// Vector before performing any concatenation, but by working backwards we likely +// only fill the queue with the number of substrings at any given level in a +// rope-of-ropes.) +void JSString::resolveRope(ExecState* exec) const +{ + ASSERT(isRope()); + + // Allocate the buffer to hold the final string, position initially points to the end. + UChar* buffer; + if (PassRefPtr<UStringImpl> newImpl = UStringImpl::tryCreateUninitialized(m_length, buffer)) + m_value = newImpl; + else { + for (unsigned i = 0; i < m_fiberCount; ++i) { + m_other.m_fibers[i]->deref(); + m_other.m_fibers[i] = 0; + } + m_fiberCount = 0; + ASSERT(!isRope()); + ASSERT(m_value == UString()); + throwOutOfMemoryError(exec); + return; + } + UChar* position = buffer + m_length; + + // Start with the current Rope. + Vector<Rope::Fiber, 32> workQueue; + Rope::Fiber currentFiber; + for (unsigned i = 0; i < (m_fiberCount - 1); ++i) + workQueue.append(m_other.m_fibers[i]); + currentFiber = m_other.m_fibers[m_fiberCount - 1]; + while (true) { + if (currentFiber->isRope()) { + Rope* rope = static_cast<URopeImpl*>(currentFiber); + // Copy the contents of the current rope into the workQueue, with the last item in 'currentFiber' + // (we will be working backwards over the rope). + unsigned fiberCountMinusOne = rope->fiberCount() - 1; + for (unsigned i = 0; i < fiberCountMinusOne; ++i) + workQueue.append(rope->fibers(i)); + currentFiber = rope->fibers(fiberCountMinusOne); + } else { + UStringImpl* string = static_cast<UStringImpl*>(currentFiber); + unsigned length = string->length(); + position -= length; + UStringImpl::copyChars(position, string->characters(), length); + + // Was this the last item in the work queue? + if (workQueue.isEmpty()) { + // Create a string from the UChar buffer, clear the rope RefPtr. + ASSERT(buffer == position); + for (unsigned i = 0; i < m_fiberCount; ++i) { + m_other.m_fibers[i]->deref(); + m_other.m_fibers[i] = 0; + } + m_fiberCount = 0; + + ASSERT(!isRope()); + return; + } + + // No! - set the next item up to process. + currentFiber = workQueue.last(); + workQueue.removeLast(); + } + } +} + +JSString* JSString::getIndexSlowCase(ExecState* exec, unsigned i) +{ + ASSERT(isRope()); + resolveRope(exec); + // Return a safe no-value result, this should never be used, since the excetion will be thrown. + if (exec->exception()) + return jsString(exec, ""); + ASSERT(!isRope()); + ASSERT(i < m_value.size()); + return jsSingleCharacterSubstring(exec, m_value, i); +} + JSValue JSString::toPrimitive(ExecState*, PreferredPrimitiveType) const { return const_cast<JSString*>(this); } -bool JSString::getPrimitiveNumber(ExecState*, double& number, JSValue& value) +bool JSString::getPrimitiveNumber(ExecState* exec, double& number, JSValue& result) { - value = this; - number = m_value.toDouble(); + result = this; + number = value(exec).toDouble(); return false; } bool JSString::toBoolean(ExecState*) const { - return !m_value.isEmpty(); + return m_length; } -double JSString::toNumber(ExecState*) const +double JSString::toNumber(ExecState* exec) const { - return m_value.toDouble(); + return value(exec).toDouble(); } -UString JSString::toString(ExecState*) const +UString JSString::toString(ExecState* exec) const { - return m_value; + return value(exec); } -UString JSString::toThisString(ExecState*) const +UString JSString::toThisString(ExecState* exec) const { - return m_value; + return value(exec); } JSString* JSString::toThisJSString(ExecState*) @@ -106,14 +192,14 @@ bool JSString::getOwnPropertySlot(ExecState* exec, const Identifier& propertyNam bool JSString::getStringPropertyDescriptor(ExecState* exec, const Identifier& propertyName, PropertyDescriptor& descriptor) { if (propertyName == exec->propertyNames().length) { - descriptor.setDescriptor(jsNumber(exec, m_value.size()), DontEnum | DontDelete | ReadOnly); + descriptor.setDescriptor(jsNumber(exec, m_length), DontEnum | DontDelete | ReadOnly); return true; } bool isStrictUInt32; unsigned i = propertyName.toStrictUInt32(&isStrictUInt32); - if (isStrictUInt32 && i < static_cast<unsigned>(m_value.size())) { - descriptor.setDescriptor(jsSingleCharacterSubstring(exec, m_value, i), DontDelete | ReadOnly); + if (isStrictUInt32 && i < m_length) { + descriptor.setDescriptor(getIndex(exec, i), DontDelete | ReadOnly); return true; } |