Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(333)

Unified Diff: src/jsregexp.cc

Issue 40290: Experimental: Merge 1395:1441 from bleeding_edge branch to the... (Closed) Base URL: http://v8.googlecode.com/svn/branches/experimental/global/
Patch Set: Created 11 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « src/jsregexp.h ('k') | src/list.h » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: src/jsregexp.cc
===================================================================
--- src/jsregexp.cc (revision 1441)
+++ src/jsregexp.cc (working copy)
@@ -256,14 +256,12 @@
Handle<Object> RegExpImpl::Exec(Handle<JSRegExp> regexp,
Handle<String> subject,
- int index,
- Handle<JSArray> last_match_info) {
+ Handle<Object> index) {
switch (regexp->TypeTag()) {
case JSRegExp::ATOM:
- return AtomExec(regexp, subject, index, last_match_info);
+ return AtomExec(regexp, subject, index);
case JSRegExp::IRREGEXP: {
- Handle<Object> result =
- IrregexpExec(regexp, subject, index, last_match_info);
+ Handle<Object> result = IrregexpExec(regexp, subject, index);
ASSERT(!result.is_null() || Top::has_pending_exception());
return result;
}
@@ -275,14 +273,12 @@
Handle<Object> RegExpImpl::ExecGlobal(Handle<JSRegExp> regexp,
- Handle<String> subject,
- Handle<JSArray> last_match_info) {
+ Handle<String> subject) {
switch (regexp->TypeTag()) {
case JSRegExp::ATOM:
- return AtomExecGlobal(regexp, subject, last_match_info);
+ return AtomExecGlobal(regexp, subject);
case JSRegExp::IRREGEXP: {
- Handle<Object> result =
- IrregexpExecGlobal(regexp, subject, last_match_info);
+ Handle<Object> result = IrregexpExecGlobal(regexp, subject);
ASSERT(!result.is_null() || Top::has_pending_exception());
return result;
}
@@ -305,79 +301,51 @@
}
-static void SetAtomLastCapture(FixedArray* array,
- String* subject,
- int from,
- int to) {
- RegExpImpl::SetLastCaptureCount(array, 2);
- RegExpImpl::SetLastSubject(array, subject);
- RegExpImpl::SetLastInput(array, subject);
- RegExpImpl::SetCapture(array, 0, from);
- RegExpImpl::SetCapture(array, 1, to);
-}
-
-
Handle<Object> RegExpImpl::AtomExec(Handle<JSRegExp> re,
Handle<String> subject,
- int index,
- Handle<JSArray> last_match_info) {
+ Handle<Object> index) {
Handle<String> needle(String::cast(re->DataAt(JSRegExp::kAtomPatternIndex)));
- uint32_t start_index = index;
+ uint32_t start_index;
+ if (!Array::IndexFromObject(*index, &start_index)) {
+ return Handle<Smi>(Smi::FromInt(-1));
+ }
int value = Runtime::StringMatch(subject, needle, start_index);
if (value == -1) return Factory::null_value();
- ASSERT(last_match_info->HasFastElements());
- Handle<FixedArray> array(last_match_info->elements());
- SetAtomLastCapture(*array, *subject, value, value + needle->length());
- return last_match_info;
+ Handle<FixedArray> array = Factory::NewFixedArray(2);
+ array->set(0, Smi::FromInt(value));
+ array->set(1, Smi::FromInt(value + needle->length()));
+ return Factory::NewJSArrayWithElements(array);
}
Handle<Object> RegExpImpl::AtomExecGlobal(Handle<JSRegExp> re,
- Handle<String> subject,
- Handle<JSArray> last_match_info) {
+ Handle<String> subject) {
Handle<String> needle(String::cast(re->DataAt(JSRegExp::kAtomPatternIndex)));
- ASSERT(last_match_info->HasFastElements());
Handle<JSArray> result = Factory::NewJSArray(1);
int index = 0;
int match_count = 0;
int subject_length = subject->length();
int needle_length = needle->length();
- int last_value = -1;
while (true) {
- HandleScope scope;
int value = -1;
if (index + needle_length <= subject_length) {
value = Runtime::StringMatch(subject, needle, index);
}
- if (value == -1) {
- if (last_value != -1) {
- Handle<FixedArray> array(last_match_info->elements());
- SetAtomLastCapture(*array,
- *subject,
- last_value,
- last_value + needle->length());
- }
- break;
- }
-
+ if (value == -1) break;
+ HandleScope scope;
int end = value + needle_length;
- // Create an array that looks like the static last_match_info array
- // that is attached to the global RegExp object. We will be returning
- // an array of these.
- Handle<FixedArray> array = Factory::NewFixedArray(kFirstCapture + 2);
- SetCapture(*array, 0, value);
- SetCapture(*array, 1, end);
- SetLastCaptureCount(*array, 2);
+ Handle<FixedArray> array = Factory::NewFixedArray(2);
+ array->set(0, Smi::FromInt(value));
+ array->set(1, Smi::FromInt(end));
Handle<JSArray> pair = Factory::NewJSArrayWithElements(array);
SetElement(result, match_count, pair);
match_count++;
index = end;
if (needle_length == 0) index++;
- last_value = value;
}
return result;
}
@@ -477,8 +445,7 @@
Handle<Object> RegExpImpl::IrregexpExec(Handle<JSRegExp> regexp,
Handle<String> subject,
- int index,
- Handle<JSArray> last_match_info) {
+ Handle<Object> index) {
ASSERT_EQ(regexp->TypeTag(), JSRegExp::IRREGEXP);
ASSERT(regexp->DataAt(JSRegExp::kIrregexpDataIndex)->IsFixedArray());
@@ -490,12 +457,13 @@
}
// Prepare space for the return values.
- int number_of_capture_registers =
- (IrregexpNumberOfCaptures(irregexp) + 1) * 2;
- OffsetsVector offsets(number_of_capture_registers);
+ int number_of_registers = IrregexpNumberOfRegisters(irregexp);
+ OffsetsVector offsets(number_of_registers);
- int previous_index = index;
+ int num_captures = IrregexpNumberOfCaptures(irregexp);
+ int previous_index = static_cast<int>(DoubleToInteger(index->Number()));
+
#ifdef DEBUG
if (FLAG_trace_regexp_bytecodes) {
String* pattern = regexp->Pattern();
@@ -508,11 +476,8 @@
FlattenString(subject);
}
- last_match_info->EnsureSize(number_of_capture_registers + kLastMatchOverhead);
-
return IrregexpExecOnce(irregexp,
- number_of_capture_registers,
- last_match_info,
+ num_captures,
subject,
previous_index,
offsets.vector(),
@@ -521,8 +486,7 @@
Handle<Object> RegExpImpl::IrregexpExecGlobal(Handle<JSRegExp> regexp,
- Handle<String> subject,
- Handle<JSArray> last_match_info) {
+ Handle<String> subject) {
ASSERT_EQ(regexp->TypeTag(), JSRegExp::IRREGEXP);
bool is_ascii = StringShape(*subject).IsAsciiRepresentation();
@@ -532,22 +496,19 @@
}
// Prepare space for the return values.
- int number_of_capture_registers =
- (IrregexpNumberOfCaptures(irregexp) + 1) * 2;
- OffsetsVector offsets(number_of_capture_registers);
+ int number_of_registers = IrregexpNumberOfRegisters(irregexp);
+ OffsetsVector offsets(number_of_registers);
int previous_index = 0;
Handle<JSArray> result = Factory::NewJSArray(0);
- int result_length = 0;
+ int i = 0;
Handle<Object> matches;
if (!subject->IsFlat(StringShape(*subject))) {
FlattenString(subject);
}
- last_match_info->EnsureSize(number_of_capture_registers + kLastMatchOverhead);
-
while (true) {
if (previous_index > subject->length() || previous_index < 0) {
// Per ECMA-262 15.10.6.2, if the previous index is greater than the
@@ -562,10 +523,8 @@
PrintF("\n\nSubject string: '%s'\n\n", *(subject->ToCString()));
}
#endif
- HandleScope scope;
matches = IrregexpExecOnce(irregexp,
- number_of_capture_registers,
- last_match_info,
+ IrregexpNumberOfCaptures(irregexp),
subject,
previous_index,
offsets.vector(),
@@ -577,25 +536,12 @@
}
if (matches->IsJSArray()) {
- // Create an array that looks like the static last_match_info array
- // that is attached to the global RegExp object. We will be returning
- // an array of these.
- Handle<FixedArray> matches_array(JSArray::cast(*matches)->elements());
- Handle<JSArray> latest_match =
- Factory::NewJSArray(kFirstCapture + number_of_capture_registers);
- Handle<FixedArray> latest_match_array(latest_match->elements());
-
- for (int i = 0; i < number_of_capture_registers; i++) {
- SetCapture(*latest_match_array, i, GetCapture(*matches_array, i));
- }
- SetLastCaptureCount(*latest_match_array, number_of_capture_registers);
-
- SetElement(result, result_length, latest_match);
- result_length++;
- previous_index = GetCapture(*matches_array, 1);
- if (GetCapture(*matches_array, 0) == previous_index)
+ SetElement(result, i, matches);
+ i++;
+ previous_index = offsets.vector()[1];
+ if (offsets.vector()[0] == offsets.vector()[1]) {
previous_index++;
-
+ }
} else {
ASSERT(matches->IsNull());
return result;
@@ -606,8 +552,7 @@
Handle<Object> RegExpImpl::IrregexpExecOnce(Handle<FixedArray> irregexp,
- int number_of_capture_registers,
- Handle<JSArray> last_match_info,
+ int num_captures,
Handle<String> subject,
int previous_index,
int* offsets_vector,
@@ -697,7 +642,7 @@
#endif
}
case RegExpMacroAssembler::kBytecodeImplementation: {
- for (int i = number_of_capture_registers - 1; i >= 0; i--) {
+ for (int i = (num_captures + 1) * 2 - 1; i >= 0; i--) {
offsets_vector[i] = -1;
}
Handle<ByteArray> byte_codes = IrregexpByteCode(irregexp);
@@ -719,16 +664,13 @@
return Factory::null_value();
}
- Handle<FixedArray> array(last_match_info->elements());
+ Handle<FixedArray> array = Factory::NewFixedArray(2 * (num_captures+1));
// The captures come in (start, end+1) pairs.
- for (int i = 0; i < number_of_capture_registers; i += 2) {
- SetCapture(*array, i, offsets_vector[i]);
- SetCapture(*array, i + 1, offsets_vector[i + 1]);
+ for (int i = 0; i < 2 * (num_captures + 1); i += 2) {
+ array->set(i, Smi::FromInt(offsets_vector[i]));
+ array->set(i + 1, Smi::FromInt(offsets_vector[i + 1]));
}
- SetLastCaptureCount(*array, number_of_capture_registers);
- SetLastSubject(*array, *subject);
- SetLastInput(*array, *subject);
- return last_match_info;
+ return Factory::NewJSArrayWithElements(array);
}
@@ -3781,6 +3723,9 @@
// |
// [if r >= f] \----> ...
//
+ //
+ // TODO(someone): clear captures on repetition and handle empty
+ // matches.
// 15.10.2.5 RepeatMatcher algorithm.
// The parser has already eliminated the case where max is 0. In the case
« no previous file with comments | « src/jsregexp.h ('k') | src/list.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698