diff options
Diffstat (limited to 'JavaScriptCore/runtime/JSString.cpp')
| -rw-r--r-- | JavaScriptCore/runtime/JSString.cpp | 58 |
1 files changed, 55 insertions, 3 deletions
diff --git a/JavaScriptCore/runtime/JSString.cpp b/JavaScriptCore/runtime/JSString.cpp index fbc7d72..473eb77 100644 --- a/JavaScriptCore/runtime/JSString.cpp +++ b/JavaScriptCore/runtime/JSString.cpp @@ -57,7 +57,8 @@ void JSString::resolveRope(ExecState* exec) const m_fiberCount = 0; ASSERT(!isRope()); ASSERT(m_value == UString()); - throwOutOfMemoryError(exec); + if (exec) + throwOutOfMemoryError(exec); return; } UChar* position = buffer + m_length; @@ -75,8 +76,8 @@ void JSString::resolveRope(ExecState* exec) const // (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); + workQueue.append(rope->fibers()[i]); + currentFiber = rope->fibers()[fiberCountMinusOne]; } else { UStringImpl* string = static_cast<UStringImpl*>(currentFiber); unsigned length = string->length(); @@ -104,6 +105,57 @@ void JSString::resolveRope(ExecState* exec) const } } +JSValue JSString::replaceCharacter(ExecState* exec, UChar character, const UString& replacement) +{ + if (!isRope()) { + unsigned matchPosition = m_value.find(character); + if (matchPosition == UString::NotFound) + return JSValue(this); + return jsString(exec, m_value.substr(0, matchPosition), replacement, m_value.substr(matchPosition + 1)); + } + + RopeIterator end; + + // Count total fibers and find matching string. + size_t fiberCount = 0; + UStringImpl* matchString = 0; + int matchPosition = -1; + for (RopeIterator it(m_other.m_fibers, m_fiberCount); it != end; ++it) { + ++fiberCount; + if (matchString) + continue; + + UStringImpl* string = *it; + matchPosition = string->find(character); + if (matchPosition == -1) + continue; + matchString = string; + } + + if (!matchString) + return this; + + RopeBuilder builder(replacement.size() ? fiberCount + 2 : fiberCount + 1); + if (UNLIKELY(builder.isOutOfMemory())) + return throwOutOfMemoryError(exec); + + for (RopeIterator it(m_other.m_fibers, m_fiberCount); it != end; ++it) { + UStringImpl* string = *it; + if (string != matchString) { + builder.append(UString(string)); + continue; + } + + builder.append(UString(string).substr(0, matchPosition)); + if (replacement.size()) + builder.append(replacement); + builder.append(UString(string).substr(matchPosition + 1)); + } + + JSGlobalData* globalData = &exec->globalData(); + return JSValue(new (globalData) JSString(globalData, builder.release())); +} + JSString* JSString::getIndexSlowCase(ExecState* exec, unsigned i) { ASSERT(isRope()); |
