summaryrefslogtreecommitdiffstats
path: root/src/3rdparty/webkit/JavaScriptCore/runtime/JSString.cpp
diff options
context:
space:
mode:
authorJocelyn Turcotte <jocelyn.turcotte@nokia.com>2010-04-06 10:36:47 (GMT)
committerJocelyn Turcotte <jocelyn.turcotte@nokia.com>2010-04-06 10:36:47 (GMT)
commitbb35b65bbfba82e0dd0ac306d3dab54436cdaff6 (patch)
tree8174cb262a960ff7b2e4aa8f1aaf154db71d2636 /src/3rdparty/webkit/JavaScriptCore/runtime/JSString.cpp
parent4b27d0d887269583a0f76e922948f8c25e96ab88 (diff)
downloadQt-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.cpp112
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;
}