Modified: trunk/Source/_javascript_Core/ChangeLog (133332 => 133333)
--- trunk/Source/_javascript_Core/ChangeLog 2012-11-02 19:58:52 UTC (rev 133332)
+++ trunk/Source/_javascript_Core/ChangeLog 2012-11-02 20:20:50 UTC (rev 133333)
@@ -1,3 +1,18 @@
+2012-11-02 Michael Saboff <msab...@apple.com>
+
+ RegExp.prototype.toString Should Produce an 8 bit JSString if possible.
+ https://bugs.webkit.org/show_bug.cgi?id=101003
+
+ Reviewed by Geoffrey Garen.
+
+ Took the logic of regExpObjectSource() and created two templated helpers that uses the
+ source character type when appending to the StringBuilder.
+
+ * runtime/RegExpObject.cpp:
+ (JSC::appendLineTerminatorEscape): Checks line terminate type to come up with escaped version.
+ (JSC::regExpObjectSourceInternal): Templated version of original.
+ (JSC::regExpObjectSource): Wrapper function.
+
2012-11-02 Adam Barth <aba...@webkit.org>
ENABLE(UNDO_MANAGER) is disabled everywhere and is not under active development
Modified: trunk/Source/_javascript_Core/runtime/RegExpObject.cpp (133332 => 133333)
--- trunk/Source/_javascript_Core/runtime/RegExpObject.cpp 2012-11-02 19:58:52 UTC (rev 133332)
+++ trunk/Source/_javascript_Core/runtime/RegExpObject.cpp 2012-11-02 20:20:50 UTC (rev 133333)
@@ -178,11 +178,34 @@
return jsBoolean(asRegExpObject(slotBase)->regExp()->multiline());
}
-JSValue regExpObjectSource(ExecState* exec, JSValue slotBase, PropertyName)
+template <typename CharacterType>
+static inline void appendLineTerminatorEscape(StringBuilder&, CharacterType);
+
+template <>
+inline void appendLineTerminatorEscape<LChar>(StringBuilder& builder, LChar lineTerminator)
{
- String pattern = asRegExpObject(slotBase)->regExp()->pattern();
- unsigned length = pattern.length();
- const UChar* characters = pattern.characters();
+ if (lineTerminator == '\n')
+ builder.append('n');
+ else
+ builder.append('r');
+}
+
+template <>
+inline void appendLineTerminatorEscape<UChar>(StringBuilder& builder, UChar lineTerminator)
+{
+ if (lineTerminator == '\n')
+ builder.append('n');
+ else if (lineTerminator == '\r')
+ builder.append('r');
+ else if (lineTerminator == 0x2028)
+ builder.appendLiteral("u2028");
+ else
+ builder.appendLiteral("u2029");
+}
+
+template <typename CharacterType>
+static inline JSValue regExpObjectSourceInternal(ExecState* exec, String pattern, const CharacterType* characters, unsigned length)
+{
bool previousCharacterWasBackslash = false;
bool inBrackets = false;
bool shouldEscape = false;
@@ -197,7 +220,7 @@
// early return for strings that don't contain a forwards slash and LineTerminator
for (unsigned i = 0; i < length; ++i) {
- UChar ch = characters[i];
+ CharacterType ch = characters[i];
if (!previousCharacterWasBackslash) {
if (inBrackets) {
if (ch == ']')
@@ -212,7 +235,7 @@
}
}
- if (Lexer<UChar>::isLineTerminator(ch)) {
+ if (Lexer<CharacterType>::isLineTerminator(ch)) {
shouldEscape = true;
break;
}
@@ -230,7 +253,7 @@
inBrackets = false;
StringBuilder result;
for (unsigned i = 0; i < length; ++i) {
- UChar ch = characters[i];
+ CharacterType ch = characters[i];
if (!previousCharacterWasBackslash) {
if (inBrackets) {
if (ch == ']')
@@ -244,18 +267,11 @@
}
// escape LineTerminator
- if (Lexer<UChar>::isLineTerminator(ch)) {
+ if (Lexer<CharacterType>::isLineTerminator(ch)) {
if (!previousCharacterWasBackslash)
result.append('\\');
- if (ch == '\n')
- result.append('n');
- else if (ch == '\r')
- result.append('r');
- else if (ch == 0x2028)
- result.appendLiteral("u2028");
- else
- result.appendLiteral("u2029");
+ appendLineTerminatorEscape<CharacterType>(result, ch);
} else
result.append(ch);
@@ -268,6 +284,14 @@
return jsString(exec, result.toString());
}
+JSValue regExpObjectSource(ExecState* exec, JSValue slotBase, PropertyName)
+{
+ String pattern = asRegExpObject(slotBase)->regExp()->pattern();
+ if (pattern.is8Bit())
+ return regExpObjectSourceInternal(exec, pattern, pattern.characters8(), pattern.length());
+ return regExpObjectSourceInternal(exec, pattern, pattern.characters16(), pattern.length());
+}
+
void RegExpObject::put(JSCell* cell, ExecState* exec, PropertyName propertyName, JSValue value, PutPropertySlot& slot)
{
if (propertyName == exec->propertyNames().lastIndex) {