Index: src/regexp/jsregexp.cc |
diff --git a/src/regexp/jsregexp.cc b/src/regexp/jsregexp.cc |
index c0897bebcff36bf638b989460c47577048d1caaf..de703f4d3d98cea6a2a85e280aaa81d854cf9c67 100644 |
--- a/src/regexp/jsregexp.cc |
+++ b/src/regexp/jsregexp.cc |
@@ -194,7 +194,7 @@ MaybeHandle<Object> RegExpImpl::Compile(Handle<JSRegExp> re, |
MaybeHandle<Object> RegExpImpl::Exec(Handle<JSRegExp> regexp, |
Handle<String> subject, int index, |
- Handle<JSObject> last_match_info) { |
+ Handle<RegExpMatchInfo> last_match_info) { |
switch (regexp->TypeTag()) { |
case JSRegExp::ATOM: |
return AtomExec(regexp, subject, index, last_match_info); |
@@ -222,17 +222,14 @@ void RegExpImpl::AtomCompile(Handle<JSRegExp> re, |
match_pattern); |
} |
- |
-static void SetAtomLastCapture(FixedArray* array, |
- String* subject, |
- int from, |
- int to) { |
- SealHandleScope shs(array->GetIsolate()); |
- RegExpImpl::SetLastCaptureCount(array, 2); |
- RegExpImpl::SetLastSubject(array, subject); |
- RegExpImpl::SetLastInput(array, subject); |
- RegExpImpl::SetCapture(array, 0, from); |
- RegExpImpl::SetCapture(array, 1, to); |
+static void SetAtomLastCapture(Handle<RegExpMatchInfo> last_match_info, |
+ String* subject, int from, int to) { |
+ SealHandleScope shs(last_match_info->GetIsolate()); |
+ last_match_info->SetNumberOfCaptureRegisters(2); |
+ last_match_info->SetLastSubject(subject); |
+ last_match_info->SetLastInput(subject); |
+ last_match_info->SetCapture(0, from); |
+ last_match_info->SetCapture(1, to); |
} |
@@ -289,7 +286,7 @@ int RegExpImpl::AtomExecRaw(Handle<JSRegExp> regexp, |
Handle<Object> RegExpImpl::AtomExec(Handle<JSRegExp> re, Handle<String> subject, |
int index, |
- Handle<JSObject> last_match_info) { |
+ Handle<RegExpMatchInfo> last_match_info) { |
Isolate* isolate = re->GetIsolate(); |
static const int kNumRegisters = 2; |
@@ -302,8 +299,8 @@ Handle<Object> RegExpImpl::AtomExec(Handle<JSRegExp> re, Handle<String> subject, |
DCHECK_EQ(res, RegExpImpl::RE_SUCCESS); |
SealHandleScope shs(isolate); |
- FixedArray* array = FixedArray::cast(last_match_info->elements()); |
- SetAtomLastCapture(array, *subject, output_registers[0], output_registers[1]); |
+ SetAtomLastCapture(last_match_info, *subject, output_registers[0], |
+ output_registers[1]); |
return last_match_info; |
} |
@@ -566,10 +563,9 @@ int RegExpImpl::IrregexpExecRaw(Handle<JSRegExp> regexp, |
#endif // V8_INTERPRETED_REGEXP |
} |
-MaybeHandle<Object> RegExpImpl::IrregexpExec(Handle<JSRegExp> regexp, |
- Handle<String> subject, |
- int previous_index, |
- Handle<JSObject> last_match_info) { |
+MaybeHandle<Object> RegExpImpl::IrregexpExec( |
+ Handle<JSRegExp> regexp, Handle<String> subject, int previous_index, |
+ Handle<RegExpMatchInfo> last_match_info) { |
Isolate* isolate = regexp->GetIsolate(); |
DCHECK_EQ(regexp->TypeTag(), JSRegExp::IRREGEXP); |
@@ -613,31 +609,40 @@ MaybeHandle<Object> RegExpImpl::IrregexpExec(Handle<JSRegExp> regexp, |
return isolate->factory()->null_value(); |
} |
-static void EnsureSize(Handle<JSObject> array, uint32_t minimum_size) { |
- if (static_cast<uint32_t>(array->elements()->length()) < minimum_size) { |
- array->GetElementsAccessor()->GrowCapacityAndConvert(array, minimum_size); |
- } |
-} |
+Handle<RegExpMatchInfo> RegExpImpl::SetLastMatchInfo( |
+ Handle<RegExpMatchInfo> last_match_info, Handle<String> subject, |
+ int capture_count, int32_t* match) { |
+ // This is the only place where match infos can grow. If, after executing the |
+ // regexp, RegExpExecStub finds that the match info is too small, it restarts |
+ // execution in RegExpImpl::Exec, which finally grows the match info right |
+ // here. |
-Handle<JSObject> RegExpImpl::SetLastMatchInfo(Handle<JSObject> last_match_info, |
- Handle<String> subject, |
- int capture_count, |
- int32_t* match) { |
- DCHECK(last_match_info->HasFastObjectElements()); |
int capture_register_count = (capture_count + 1) * 2; |
- EnsureSize(last_match_info, capture_register_count + kLastMatchOverhead); |
+ Handle<RegExpMatchInfo> result = |
+ RegExpMatchInfo::ReserveCaptures(last_match_info, capture_register_count); |
+ result->SetNumberOfCaptureRegisters(capture_register_count); |
+ |
+ if (*result != *last_match_info) { |
+ // The match info has been reallocated, update the corresponding reference |
+ // on the native context. |
+ Isolate* isolate = last_match_info->GetIsolate(); |
+ if (*last_match_info == *isolate->regexp_last_match_info()) { |
+ isolate->native_context()->set_regexp_last_match_info(*result); |
+ } else if (*last_match_info == *isolate->regexp_internal_match_info()) { |
+ isolate->native_context()->set_regexp_internal_match_info(*result); |
+ } |
+ } |
+ |
DisallowHeapAllocation no_allocation; |
- FixedArray* array = FixedArray::cast(last_match_info->elements()); |
if (match != NULL) { |
for (int i = 0; i < capture_register_count; i += 2) { |
- SetCapture(array, i, match[i]); |
- SetCapture(array, i + 1, match[i + 1]); |
+ result->SetCapture(i, match[i]); |
+ result->SetCapture(i + 1, match[i + 1]); |
} |
} |
- SetLastCaptureCount(array, capture_register_count); |
- SetLastSubject(array, *subject); |
- SetLastInput(array, *subject); |
- return last_match_info; |
+ result->SetLastSubject(*subject); |
+ result->SetLastInput(*subject); |
+ return result; |
} |