Chromium Code Reviews| Index: src/runtime.cc |
| diff --git a/src/runtime.cc b/src/runtime.cc |
| index 0b80effbf21e86138f7e66ea6290998d3922b7de..47a0eaf5abed9648b2ce0c8066f48bd9f15498fb 100644 |
| --- a/src/runtime.cc |
| +++ b/src/runtime.cc |
| @@ -3795,62 +3795,73 @@ static bool SearchStringMultiple(Isolate* isolate, |
| } |
| -static RegExpImpl::IrregexpResult SearchRegExpNoCaptureMultiple( |
| +static int SearchRegExpNoCaptureMultiple( |
| Isolate* isolate, |
| Handle<String> subject, |
| Handle<JSRegExp> regexp, |
| Handle<JSArray> last_match_array, |
| FixedArrayBuilder* builder) { |
| ASSERT(subject->IsFlat()); |
| + ASSERT(regexp->CaptureCount() == 0); |
| int match_start = -1; |
| int match_end = 0; |
| int pos = 0; |
| - int required_registers = RegExpImpl::IrregexpPrepare(regexp, subject); |
| - if (required_registers < 0) return RegExpImpl::RE_EXCEPTION; |
| - |
| - OffsetsVector registers(required_registers, isolate); |
| + int registers_per_match = RegExpImpl::IrregexpPrepare(regexp, subject); |
| + if (registers_per_match < 0) return RegExpImpl::RE_EXCEPTION; |
| + |
| + int max_matches; |
| + int num_registers = RegExpImpl::GlobalOffsetsVectorSize(regexp, |
| + registers_per_match, |
| + &max_matches); |
| + OffsetsVector registers(num_registers, isolate); |
| Vector<int32_t> register_vector(registers.vector(), registers.length()); |
| int subject_length = subject->length(); |
| bool first = true; |
| - |
| for (;;) { // Break on failure, return on exception. |
| - RegExpImpl::IrregexpResult result = |
| - RegExpImpl::IrregexpExecOnce(regexp, |
| - subject, |
| - pos, |
| - register_vector); |
| - if (result == RegExpImpl::RE_SUCCESS) { |
| - match_start = register_vector[0]; |
| - builder->EnsureCapacity(kMaxBuilderEntriesPerRegExpMatch); |
| - if (match_end < match_start) { |
| - ReplacementStringBuilder::AddSubjectSlice(builder, |
| - match_end, |
| - match_start); |
| - } |
| - match_end = register_vector[1]; |
| - HandleScope loop_scope(isolate); |
| - if (!first) { |
| - builder->Add(*isolate->factory()->NewProperSubString(subject, |
| - match_start, |
| - match_end)); |
| - } else { |
| - builder->Add(*isolate->factory()->NewSubString(subject, |
| - match_start, |
| - match_end)); |
| + int num_matches = RegExpImpl::IrregexpExecRaw(regexp, |
| + subject, |
| + pos, |
| + register_vector); |
| + if (num_matches > 0) { |
| + for (int match_index = 0; match_index < num_matches; match_index++) { |
| + int32_t* current_match = ®ister_vector[match_index * 2]; |
| + match_start = current_match[0]; |
| + builder->EnsureCapacity(kMaxBuilderEntriesPerRegExpMatch); |
| + if (match_end < match_start) { |
| + ReplacementStringBuilder::AddSubjectSlice(builder, |
| + match_end, |
| + match_start); |
| + } |
| + match_end = current_match[1]; |
| + HandleScope loop_scope(isolate); |
| + if (!first) { |
| + builder->Add(*isolate->factory()->NewProperSubString(subject, |
| + match_start, |
| + match_end)); |
| + } else { |
| + builder->Add(*isolate->factory()->NewSubString(subject, |
| + match_start, |
| + match_end)); |
| + first = false; |
| + } |
| } |
| + |
| + // If we did not get the maximum number of matches, we can stop here |
| + // since there are no matches left. |
| + if (num_matches < max_matches) break; |
| + |
| if (match_start != match_end) { |
| pos = match_end; |
| } else { |
| pos = match_end + 1; |
| if (pos > subject_length) break; |
| } |
| - } else if (result == RegExpImpl::RE_FAILURE) { |
| + } else if (num_matches == 0) { |
| break; |
| } else { |
| - ASSERT_EQ(result, RegExpImpl::RE_EXCEPTION); |
| - return result; |
| + ASSERT_EQ(num_matches, RegExpImpl::RE_EXCEPTION); |
| + return num_matches; |
|
Erik Corry
2012/05/22 08:32:46
Perhaps it is clearer to write "return RegExpImpl:
|
| } |
| - first = false; |
| } |
| if (match_start >= 0) { |
| @@ -3872,7 +3883,7 @@ static RegExpImpl::IrregexpResult SearchRegExpNoCaptureMultiple( |
| // Only called from Runtime_RegExpExecMultiple so it doesn't need to maintain |
| // separate last match info. See comment on that function. |
| -static RegExpImpl::IrregexpResult SearchRegExpMultiple( |
| +static int SearchRegExpMultiple( |
| Isolate* isolate, |
| Handle<String> subject, |
| Handle<JSRegExp> regexp, |
| @@ -3880,17 +3891,20 @@ static RegExpImpl::IrregexpResult SearchRegExpMultiple( |
| FixedArrayBuilder* builder) { |
| ASSERT(subject->IsFlat()); |
| - int required_registers = RegExpImpl::IrregexpPrepare(regexp, subject); |
| - if (required_registers < 0) return RegExpImpl::RE_EXCEPTION; |
| - |
| - OffsetsVector registers(required_registers, isolate); |
| + int registers_per_match = RegExpImpl::IrregexpPrepare(regexp, subject); |
| + if (registers_per_match < 0) return RegExpImpl::RE_EXCEPTION; |
| + |
| + int max_matches; |
| + int num_registers = RegExpImpl::GlobalOffsetsVectorSize(regexp, |
| + registers_per_match, |
| + &max_matches); |
| + OffsetsVector registers(num_registers, isolate); |
| Vector<int32_t> register_vector(registers.vector(), registers.length()); |
| - RegExpImpl::IrregexpResult result = |
| - RegExpImpl::IrregexpExecOnce(regexp, |
| - subject, |
| - 0, |
| - register_vector); |
| + int num_matches = RegExpImpl::IrregexpExecRaw(regexp, |
| + subject, |
| + 0, |
| + register_vector); |
| int capture_count = regexp->CaptureCount(); |
| int subject_length = subject->length(); |
| @@ -3899,60 +3913,65 @@ static RegExpImpl::IrregexpResult SearchRegExpMultiple( |
| int pos = 0; |
| // End of previous match. Differs from pos if match was empty. |
| int match_end = 0; |
| - if (result == RegExpImpl::RE_SUCCESS) { |
| - bool first = true; |
| + bool first = true; |
| + |
| + if (num_matches > 0) { |
| do { |
| - int match_start = register_vector[0]; |
| - builder->EnsureCapacity(kMaxBuilderEntriesPerRegExpMatch); |
| - if (match_end < match_start) { |
| - ReplacementStringBuilder::AddSubjectSlice(builder, |
| - match_end, |
| - match_start); |
| - } |
| - match_end = register_vector[1]; |
| - |
| - { |
| - // Avoid accumulating new handles inside loop. |
| - HandleScope temp_scope(isolate); |
| - // Arguments array to replace function is match, captures, index and |
| - // subject, i.e., 3 + capture count in total. |
| - Handle<FixedArray> elements = |
| - isolate->factory()->NewFixedArray(3 + capture_count); |
| - Handle<String> match; |
| - if (!first) { |
| - match = isolate->factory()->NewProperSubString(subject, |
| - match_start, |
| - match_end); |
| - } else { |
| - match = isolate->factory()->NewSubString(subject, |
| - match_start, |
| - match_end); |
| + int match_start = 0; |
| + for (int match_index = 0; match_index < num_matches; match_index++) { |
| + int32_t* current_match = |
| + ®ister_vector[match_index * registers_per_match]; |
| + match_start = current_match[0]; |
| + builder->EnsureCapacity(kMaxBuilderEntriesPerRegExpMatch); |
| + if (match_end < match_start) { |
| + ReplacementStringBuilder::AddSubjectSlice(builder, |
| + match_end, |
| + match_start); |
| } |
| - elements->set(0, *match); |
| - for (int i = 1; i <= capture_count; i++) { |
| - int start = register_vector[i * 2]; |
| - if (start >= 0) { |
| - int end = register_vector[i * 2 + 1]; |
| - ASSERT(start <= end); |
| - Handle<String> substring; |
| - if (!first) { |
| - substring = isolate->factory()->NewProperSubString(subject, |
| - start, |
| - end); |
| + match_end = current_match[1]; |
| + |
| + { |
| + // Avoid accumulating new handles inside loop. |
| + HandleScope temp_scope(isolate); |
| + // Arguments array to replace function is match, captures, index and |
| + // subject, i.e., 3 + capture count in total. |
| + Handle<FixedArray> elements = |
| + isolate->factory()->NewFixedArray(3 + capture_count); |
| + Handle<String> match; |
| + if (!first) { |
| + match = isolate->factory()->NewProperSubString(subject, |
| + match_start, |
| + match_end); |
| + } else { |
| + match = isolate->factory()->NewSubString(subject, |
| + match_start, |
| + match_end); |
| + first = false; |
| + } |
| + elements->set(0, *match); |
| + for (int i = 1; i <= capture_count; i++) { |
| + int start = current_match[i * 2]; |
| + if (start >= 0) { |
| + int end = current_match[i * 2 + 1]; |
| + ASSERT(start <= end); |
| + Handle<String> substring = |
| + isolate->factory()->NewProperSubString(subject, start, end); |
| + elements->set(i, *substring); |
| } else { |
| - substring = isolate->factory()->NewSubString(subject, start, end); |
| + ASSERT(current_match[i * 2 + 1] < 0); |
| + elements->set(i, isolate->heap()->undefined_value()); |
| } |
| - elements->set(i, *substring); |
| - } else { |
| - ASSERT(register_vector[i * 2 + 1] < 0); |
| - elements->set(i, isolate->heap()->undefined_value()); |
| } |
| + elements->set(capture_count + 1, Smi::FromInt(match_start)); |
| + elements->set(capture_count + 2, *subject); |
| + builder->Add(*isolate->factory()->NewJSArrayWithElements(elements)); |
| } |
| - elements->set(capture_count + 1, Smi::FromInt(match_start)); |
| - elements->set(capture_count + 2, *subject); |
| - builder->Add(*isolate->factory()->NewJSArrayWithElements(elements)); |
| } |
| + // If we did not get the maximum number of matches, we can stop here |
| + // since there are no matches left. |
| + if (num_matches < max_matches) break; |
| + |
| if (match_end > match_start) { |
| pos = match_end; |
| } else { |
| @@ -3962,14 +3981,13 @@ static RegExpImpl::IrregexpResult SearchRegExpMultiple( |
| } |
| } |
| - result = RegExpImpl::IrregexpExecOnce(regexp, |
| - subject, |
| - pos, |
| - register_vector); |
| - first = false; |
| - } while (result == RegExpImpl::RE_SUCCESS); |
| + num_matches = RegExpImpl::IrregexpExecRaw(regexp, |
| + subject, |
| + pos, |
| + register_vector); |
| + } while (num_matches > 0); |
| - if (result != RegExpImpl::RE_EXCEPTION) { |
| + if (num_matches != RegExpImpl::RE_EXCEPTION) { |
| // Finished matching, with at least one match. |
| if (match_end < subject_length) { |
| ReplacementStringBuilder::AddSubjectSlice(builder, |
| @@ -3993,7 +4011,7 @@ static RegExpImpl::IrregexpResult SearchRegExpMultiple( |
| } |
| } |
| // No matches at all, return failure or exception result directly. |
| - return result; |
| + return num_matches; |
| } |
| @@ -4035,7 +4053,7 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_RegExpExecMultiple) { |
| ASSERT_EQ(regexp->TypeTag(), JSRegExp::IRREGEXP); |
| - RegExpImpl::IrregexpResult result; |
| + int result; |
| if (regexp->CaptureCount() == 0) { |
| result = SearchRegExpNoCaptureMultiple(isolate, |
| subject, |