Index: src/runtime.cc |
diff --git a/src/runtime.cc b/src/runtime.cc |
index a86aa409b329f731c74d2c4f4a38c4efc87e98a0..a009d3aae442689462272fbfb3f87b8bafcd71e0 100644 |
--- a/src/runtime.cc |
+++ b/src/runtime.cc |
@@ -2888,7 +2888,7 @@ void FindStringIndicesDispatch(Isolate* isolate, |
template<typename ResultSeqString> |
-MUST_USE_RESULT static MaybeObject* StringReplaceAtomRegExpWithString( |
+MUST_USE_RESULT static MaybeObject* StringReplaceGlobalAtomRegExpWithString( |
Isolate* isolate, |
Handle<String> subject, |
Handle<JSRegExp> pattern_regexp, |
@@ -2911,9 +2911,7 @@ MUST_USE_RESULT static MaybeObject* StringReplaceAtomRegExpWithString( |
isolate, *subject, pattern, &indices, 0xffffffff, zone); |
int matches = indices.length(); |
- if (matches == 0) { |
- return isolate->heap()->undefined_value(); |
- } |
+ if (matches == 0) return *subject; |
// Detect integer overflow. |
int64_t result_len_64 = |
@@ -2973,7 +2971,7 @@ MUST_USE_RESULT static MaybeObject* StringReplaceAtomRegExpWithString( |
} |
-MUST_USE_RESULT static MaybeObject* StringReplaceRegExpWithString( |
+MUST_USE_RESULT static MaybeObject* StringReplaceGlobalRegExpWithString( |
Isolate* isolate, |
Handle<String> subject, |
Handle<JSRegExp> regexp, |
@@ -2982,7 +2980,6 @@ MUST_USE_RESULT static MaybeObject* StringReplaceRegExpWithString( |
ASSERT(subject->IsFlat()); |
ASSERT(replacement->IsFlat()); |
- bool is_global = regexp->GetFlags().is_global(); |
int capture_count = regexp->CaptureCount(); |
int subject_length = subject->length(); |
@@ -2995,33 +2992,30 @@ MUST_USE_RESULT static MaybeObject* StringReplaceRegExpWithString( |
subject_length); |
// Shortcut for simple non-regexp global replacements |
- if (is_global && |
- regexp->TypeTag() == JSRegExp::ATOM && |
- simple_replace) { |
+ if (regexp->TypeTag() == JSRegExp::ATOM && simple_replace) { |
if (subject->IsOneByteConvertible() && |
replacement->IsOneByteConvertible()) { |
- return StringReplaceAtomRegExpWithString<SeqOneByteString>( |
+ return StringReplaceGlobalAtomRegExpWithString<SeqOneByteString>( |
isolate, subject, regexp, replacement, last_match_info); |
} else { |
- return StringReplaceAtomRegExpWithString<SeqTwoByteString>( |
+ return StringReplaceGlobalAtomRegExpWithString<SeqTwoByteString>( |
isolate, subject, regexp, replacement, last_match_info); |
} |
} |
- RegExpImpl::GlobalCache global_cache(regexp, subject, is_global, isolate); |
+ RegExpImpl::GlobalCache global_cache(regexp, subject, true, isolate); |
if (global_cache.HasException()) return Failure::Exception(); |
int32_t* current_match = global_cache.FetchNext(); |
if (current_match == NULL) { |
if (global_cache.HasException()) return Failure::Exception(); |
- return isolate->heap()->undefined_value(); |
+ return *subject; |
} |
// Guessing the number of parts that the final result string is built |
// from. Global regexps can match any number of times, so we guess |
// conservatively. |
- int expected_parts = |
- (compiled_replacement.parts() + 1) * (is_global ? 4 : 1) + 1; |
+ int expected_parts = (compiled_replacement.parts() + 1) * 4 + 1; |
ReplacementStringBuilder builder(isolate->heap(), |
subject, |
expected_parts); |
@@ -3053,9 +3047,6 @@ MUST_USE_RESULT static MaybeObject* StringReplaceRegExpWithString( |
} |
prev = end; |
- // Only continue checking for global regexps. |
- if (!is_global) break; |
- |
current_match = global_cache.FetchNext(); |
} while (current_match != NULL); |
@@ -3076,43 +3067,32 @@ MUST_USE_RESULT static MaybeObject* StringReplaceRegExpWithString( |
template <typename ResultSeqString> |
-MUST_USE_RESULT static MaybeObject* StringReplaceRegExpWithEmptyString( |
+MUST_USE_RESULT static MaybeObject* StringReplaceGlobalRegExpWithEmptyString( |
Isolate* isolate, |
Handle<String> subject, |
Handle<JSRegExp> regexp, |
Handle<JSArray> last_match_info) { |
ASSERT(subject->IsFlat()); |
- bool is_global = regexp->GetFlags().is_global(); |
- |
// Shortcut for simple non-regexp global replacements |
- if (is_global && |
- regexp->TypeTag() == JSRegExp::ATOM) { |
+ if (regexp->TypeTag() == JSRegExp::ATOM) { |
Handle<String> empty_string = isolate->factory()->empty_string(); |
if (subject->IsOneByteRepresentation()) { |
- return StringReplaceAtomRegExpWithString<SeqOneByteString>( |
- isolate, |
- subject, |
- regexp, |
- empty_string, |
- last_match_info); |
+ return StringReplaceGlobalAtomRegExpWithString<SeqOneByteString>( |
+ isolate, subject, regexp, empty_string, last_match_info); |
} else { |
- return StringReplaceAtomRegExpWithString<SeqTwoByteString>( |
- isolate, |
- subject, |
- regexp, |
- empty_string, |
- last_match_info); |
+ return StringReplaceGlobalAtomRegExpWithString<SeqTwoByteString>( |
+ isolate, subject, regexp, empty_string, last_match_info); |
} |
} |
- RegExpImpl::GlobalCache global_cache(regexp, subject, is_global, isolate); |
+ RegExpImpl::GlobalCache global_cache(regexp, subject, true, isolate); |
if (global_cache.HasException()) return Failure::Exception(); |
int32_t* current_match = global_cache.FetchNext(); |
if (current_match == NULL) { |
if (global_cache.HasException()) return Failure::Exception(); |
- return isolate->heap()->undefined_value(); |
+ return *subject; |
} |
int start = current_match[0]; |
@@ -3132,23 +3112,6 @@ MUST_USE_RESULT static MaybeObject* StringReplaceRegExpWithEmptyString( |
isolate->factory()->NewRawTwoByteString(new_length)); |
} |
- if (!is_global) { |
- RegExpImpl::SetLastMatchInfo( |
- last_match_info, subject, capture_count, current_match); |
- if (start == end) { |
- return *subject; |
- } else { |
- if (start > 0) { |
- String::WriteToFlat(*subject, answer->GetChars(), 0, start); |
- } |
- if (end < subject_length) { |
- String::WriteToFlat( |
- *subject, answer->GetChars() + start, end, subject_length); |
- } |
- return *answer; |
- } |
- } |
- |
int prev = 0; |
int position = 0; |
@@ -3157,8 +3120,7 @@ MUST_USE_RESULT static MaybeObject* StringReplaceRegExpWithEmptyString( |
end = current_match[1]; |
if (prev < start) { |
// Add substring subject[prev;start] to answer string. |
- String::WriteToFlat( |
- *subject, answer->GetChars() + position, prev, start); |
+ String::WriteToFlat(*subject, answer->GetChars() + position, prev, start); |
position += start - prev; |
} |
prev = end; |
@@ -3200,7 +3162,7 @@ MUST_USE_RESULT static MaybeObject* StringReplaceRegExpWithEmptyString( |
} |
-RUNTIME_FUNCTION(MaybeObject*, Runtime_StringReplaceRegExpWithString) { |
+RUNTIME_FUNCTION(MaybeObject*, Runtime_StringReplaceGlobalRegExpWithString) { |
ASSERT(args.length() == 4); |
HandleScope scope(isolate); |
@@ -3210,6 +3172,8 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_StringReplaceRegExpWithString) { |
CONVERT_ARG_HANDLE_CHECKED(JSRegExp, regexp, 1); |
CONVERT_ARG_HANDLE_CHECKED(JSArray, last_match_info, 3); |
+ ASSERT(regexp->GetFlags().is_global()); |
+ |
if (!subject->IsFlat()) subject = FlattenGetString(subject); |
if (!replacement->IsFlat()) replacement = FlattenGetString(replacement); |
@@ -3218,15 +3182,15 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_StringReplaceRegExpWithString) { |
if (replacement->length() == 0) { |
if (subject->IsOneByteConvertible()) { |
- return StringReplaceRegExpWithEmptyString<SeqOneByteString>( |
+ return StringReplaceGlobalRegExpWithEmptyString<SeqOneByteString>( |
isolate, subject, regexp, last_match_info); |
} else { |
- return StringReplaceRegExpWithEmptyString<SeqTwoByteString>( |
+ return StringReplaceGlobalRegExpWithEmptyString<SeqTwoByteString>( |
isolate, subject, regexp, last_match_info); |
} |
} |
- return StringReplaceRegExpWithString( |
+ return StringReplaceGlobalRegExpWithString( |
isolate, subject, regexp, replacement, last_match_info); |
} |