- 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;
-
- // 15.10.6.4 specifies that RegExp.prototype.toString must return '/' + source + '/',
- // and also states that the result must be a valid RegularExpressionLiteral. '//' is
- // not a valid RegularExpressionLiteral (since it is a single line comment), and hence
- // source cannot ever validly be "". If the source is empty, return a different Pattern
- // that would match the same thing.
- if (!length)
- return jsNontrivialString(exec, ASCIILiteral("(?:)"));
-
- // early return for strings that don't contain a forwards slash and LineTerminator
- for (unsigned i = 0; i < length; ++i) {
- CharacterType ch = characters[i];
- if (!previousCharacterWasBackslash) {
- if (inBrackets) {
- if (ch == ']')
- inBrackets = false;
- } else {
- if (ch == '/') {
- shouldEscape = true;
- break;
- }
- if (ch == '[')
- inBrackets = true;
- }
- }
-
- if (Lexer<CharacterType>::isLineTerminator(ch)) {
- shouldEscape = true;
- break;
- }
-
- if (previousCharacterWasBackslash)
- previousCharacterWasBackslash = false;
- else
- previousCharacterWasBackslash = ch == '\\';
- }
-
- if (!shouldEscape)
- return jsString(exec, pattern);
-
- previousCharacterWasBackslash = false;
- inBrackets = false;
- StringBuilder result;
- for (unsigned i = 0; i < length; ++i) {
- CharacterType ch = characters[i];
- if (!previousCharacterWasBackslash) {
- if (inBrackets) {
- if (ch == ']')
- inBrackets = false;
- } else {
- if (ch == '/')
- result.append('\\');
- else if (ch == '[')
- inBrackets = true;
- }
- }
-
- // escape LineTerminator
- if (Lexer<CharacterType>::isLineTerminator(ch)) {
- if (!previousCharacterWasBackslash)
- result.append('\\');
-
- appendLineTerminatorEscape<CharacterType>(result, ch);
- } else
- result.append(ch);
-
- if (previousCharacterWasBackslash)
- previousCharacterWasBackslash = false;
- else
- previousCharacterWasBackslash = ch == '\\';
- }
-
- return jsString(exec, result.toString());