Index: src/runtime.cc |
diff --git a/src/runtime.cc b/src/runtime.cc |
index d804979d2e3927e1affde0146643f534e96fdf07..50f565e062ccec1c6f8495a008c66e77620d8612 100644 |
--- a/src/runtime.cc |
+++ b/src/runtime.cc |
@@ -2898,7 +2898,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, |
@@ -2921,9 +2921,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 = |
@@ -2983,7 +2981,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, |
@@ -2992,7 +2990,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(); |
@@ -3005,33 +3002,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); |
@@ -3063,9 +3057,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); |
@@ -3086,43 +3077,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]; |
@@ -3142,23 +3122,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; |
@@ -3167,8 +3130,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; |
@@ -3210,7 +3172,7 @@ MUST_USE_RESULT static MaybeObject* StringReplaceRegExpWithEmptyString( |
} |
-RUNTIME_FUNCTION(MaybeObject*, Runtime_StringReplaceRegExpWithString) { |
+RUNTIME_FUNCTION(MaybeObject*, Runtime_StringReplaceGlobalRegExpWithString) { |
ASSERT(args.length() == 4); |
HandleScope scope(isolate); |
@@ -3220,23 +3182,23 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_StringReplaceRegExpWithString) { |
CONVERT_ARG_HANDLE_CHECKED(JSRegExp, regexp, 1); |
CONVERT_ARG_HANDLE_CHECKED(JSArray, last_match_info, 3); |
- if (!subject->IsFlat()) subject = FlattenGetString(subject); |
- |
- if (!replacement->IsFlat()) replacement = FlattenGetString(replacement); |
+ ASSERT(regexp->GetFlags().is_global()); |
- ASSERT(last_match_info->HasFastObjectElements()); |
+ if (!subject->IsFlat()) subject = FlattenGetString(subject); |
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( |
+ if (!replacement->IsFlat()) replacement = FlattenGetString(replacement); |
+ |
+ return StringReplaceGlobalRegExpWithString( |
isolate, subject, regexp, replacement, last_match_info); |
} |
@@ -3774,7 +3736,6 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_RegExpExecMultiple) { |
CONVERT_ARG_HANDLE_CHECKED(JSArray, last_match_info, 2); |
CONVERT_ARG_HANDLE_CHECKED(JSArray, result_array, 3); |
- ASSERT(last_match_info->HasFastObjectElements()); |
ASSERT(regexp->GetFlags().is_global()); |
if (regexp->CaptureCount() == 0) { |