summaryrefslogtreecommitdiff
path: root/Source/JavaScriptCore/runtime/JSStringJoiner.cpp
diff options
context:
space:
mode:
authorLorry Tar Creator <lorry-tar-importer@lorry>2015-05-20 09:56:07 +0000
committerLorry Tar Creator <lorry-tar-importer@lorry>2015-05-20 09:56:07 +0000
commit41386e9cb918eed93b3f13648cbef387e371e451 (patch)
treea97f9d7bd1d9d091833286085f72da9d83fd0606 /Source/JavaScriptCore/runtime/JSStringJoiner.cpp
parente15dd966d523731101f70ccf768bba12435a0208 (diff)
downloadWebKitGtk-tarball-41386e9cb918eed93b3f13648cbef387e371e451.tar.gz
webkitgtk-2.4.9webkitgtk-2.4.9
Diffstat (limited to 'Source/JavaScriptCore/runtime/JSStringJoiner.cpp')
-rw-r--r--Source/JavaScriptCore/runtime/JSStringJoiner.cpp141
1 files changed, 76 insertions, 65 deletions
diff --git a/Source/JavaScriptCore/runtime/JSStringJoiner.cpp b/Source/JavaScriptCore/runtime/JSStringJoiner.cpp
index 6f1959388..b6461c750 100644
--- a/Source/JavaScriptCore/runtime/JSStringJoiner.cpp
+++ b/Source/JavaScriptCore/runtime/JSStringJoiner.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2012-2015 Apple Inc. All rights reserved.
+ * Copyright (C) 2012, 2013 Apple Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -26,94 +26,105 @@
#include "config.h"
#include "JSStringJoiner.h"
-#include "JSCInlines.h"
+#include "ExceptionHelpers.h"
+#include "JSScope.h"
+#include "JSString.h"
+#include "Operations.h"
+#include <wtf/text/StringImpl.h>
namespace JSC {
-template<typename CharacterType>
-static inline void appendStringToData(CharacterType*& data, StringView string)
+// The destination is 16bits, at least one string is 16 bits.
+static inline void appendStringToData(UChar*& data, const String& string)
{
- string.getCharactersWithUpconvert(data);
- data += string.length();
-}
+ if (string.isNull())
+ return;
-template<typename CharacterType>
-static inline String joinStrings(const Vector<StringViewWithUnderlyingString>& strings, StringView separator, unsigned joinedLength)
-{
- ASSERT(joinedLength);
+ unsigned length = string.length();
+ const StringImpl* stringImpl = string.impl();
- CharacterType* data;
- String result = StringImpl::tryCreateUninitialized(joinedLength, data);
- if (result.isNull())
- return result;
-
- appendStringToData(data, strings[0].view);
-
- unsigned size = strings.size();
-
- switch (separator.length()) {
- case 0:
- for (unsigned i = 1; i < size; ++i)
- appendStringToData(data, strings[i].view);
- break;
- case 1: {
- CharacterType separatorCharacter = separator[0];
- for (unsigned i = 1; i < size; ++i) {
- *data++ = separatorCharacter;
- appendStringToData(data, strings[i].view);
+ if (stringImpl->is8Bit()) {
+ for (unsigned i = 0; i < length; ++i) {
+ *data = stringImpl->characters8()[i];
+ ++data;
}
- break;
- }
- default:
- for (unsigned i = 1; i < size; ++i) {
- appendStringToData(data, separator);
- appendStringToData(data, strings[i].view);
+ } else {
+ for (unsigned i = 0; i < length; ++i) {
+ *data = stringImpl->characters16()[i];
+ ++data;
}
}
- ASSERT(data == result.characters<CharacterType>() + joinedLength);
-
- return result;
}
-inline unsigned JSStringJoiner::joinedLength(ExecState& state) const
+// If the destination is 8bits, we know every string has to be 8bit.
+static inline void appendStringToData(LChar*& data, const String& string)
{
- unsigned numberOfStrings = m_strings.size();
- if (!numberOfStrings)
- return 0;
+ if (string.isNull())
+ return;
+ ASSERT(string.is8Bit());
- Checked<unsigned, RecordOverflow> separatorLength = m_separator.length();
- Checked<unsigned, RecordOverflow> totalSeparatorsLength = separatorLength * (numberOfStrings - 1);
- Checked<unsigned, RecordOverflow> totalLength = totalSeparatorsLength + m_accumulatedStringsLength;
+ unsigned length = string.length();
+ const StringImpl* stringImpl = string.impl();
- unsigned result;
- if (totalLength.safeGet(result) == CheckedState::DidOverflow) {
- throwOutOfMemoryError(&state);
- return 0;
+ for (unsigned i = 0; i < length; ++i) {
+ *data = stringImpl->characters8()[i];
+ ++data;
}
- return result;
}
-JSValue JSStringJoiner::join(ExecState& state)
+template<typename CharacterType>
+static inline PassRefPtr<StringImpl> joinStrings(const Vector<String>& strings, const String& separator, unsigned outputLength)
{
- ASSERT(m_strings.size() <= m_strings.capacity());
+ ASSERT(outputLength);
- unsigned length = joinedLength(state);
- if (state.hadException())
- return jsUndefined();
+ CharacterType* data;
+ RefPtr<StringImpl> outputStringImpl = StringImpl::tryCreateUninitialized(outputLength, data);
+ if (!outputStringImpl)
+ return PassRefPtr<StringImpl>();
+
+ const String firstString = strings.first();
+ appendStringToData(data, firstString);
- if (!length)
- return jsEmptyString(&state);
+ for (size_t i = 1; i < strings.size(); ++i) {
+ appendStringToData(data, separator);
+ appendStringToData(data, strings[i]);
+ }
+
+ ASSERT(data == (outputStringImpl->getCharacters<CharacterType>() + outputStringImpl->length()));
+ return outputStringImpl.release();
+}
- String result;
- if (m_isAll8Bit)
- result = joinStrings<LChar>(m_strings, m_separator, length);
+JSValue JSStringJoiner::join(ExecState* exec)
+{
+ if (!m_isValid)
+ return throwOutOfMemoryError(exec);
+
+ if (!m_strings.size())
+ return jsEmptyString(exec);
+
+ Checked<unsigned, RecordOverflow> separatorLength = m_separator.length();
+ // FIXME: add special cases of joinStrings() for (separatorLength == 0) and (separatorLength == 1).
+ ASSERT(m_strings.size() > 0);
+ Checked<unsigned, RecordOverflow> totalSeparactorsLength = separatorLength * (m_strings.size() - 1);
+ Checked<unsigned, RecordOverflow> outputStringSize = totalSeparactorsLength + m_accumulatedStringsLength;
+
+ unsigned finalSize;
+ if (outputStringSize.safeGet(finalSize) == CheckedState::DidOverflow)
+ return throwOutOfMemoryError(exec);
+
+ if (!outputStringSize)
+ return jsEmptyString(exec);
+
+ RefPtr<StringImpl> outputStringImpl;
+ if (m_is8Bits)
+ outputStringImpl = joinStrings<LChar>(m_strings, m_separator, finalSize);
else
- result = joinStrings<UChar>(m_strings, m_separator, length);
+ outputStringImpl = joinStrings<UChar>(m_strings, m_separator, finalSize);
- if (result.isNull())
- return throwOutOfMemoryError(&state);
+ if (!outputStringImpl)
+ return throwOutOfMemoryError(exec);
- return jsString(&state, WTF::move(result));
+ return JSString::create(exec->vm(), outputStringImpl.release());
}
}