Index: src/jsregexp.cc |
=================================================================== |
--- src/jsregexp.cc (revision 5888) |
+++ src/jsregexp.cc (working copy) |
@@ -33,6 +33,7 @@ |
#include "factory.h" |
#include "jsregexp.h" |
#include "platform.h" |
+#include "string-search.h" |
#include "runtime.h" |
#include "top.h" |
#include "compilation-cache.h" |
@@ -120,7 +121,7 @@ |
re->set_data(*cached); |
return re; |
} |
- FlattenString(pattern); |
+ pattern = FlattenGetString(pattern); |
CompilationZoneScope zone_scope(DELETE_ON_EXIT); |
PostponeInterruptsScope postpone; |
RegExpCompileData parse_result; |
@@ -205,23 +206,61 @@ |
RegExpImpl::SetCapture(array, 1, to); |
} |
+ /* template <typename SubjectChar>, typename PatternChar> |
+static int ReStringMatch(Vector<const SubjectChar> sub_vector, |
+ Vector<const PatternChar> pat_vector, |
+ int start_index) { |
+ int pattern_length = pat_vector.length(); |
+ if (pattern_length == 0) return start_index; |
+ |
+ int subject_length = sub_vector.length(); |
+ if (start_index + pattern_length > subject_length) return -1; |
+ return SearchString(sub_vector, pat_vector, start_index); |
+} |
+ */ |
Handle<Object> RegExpImpl::AtomExec(Handle<JSRegExp> re, |
Handle<String> subject, |
int index, |
Handle<JSArray> last_match_info) { |
- Handle<String> needle(String::cast(re->DataAt(JSRegExp::kAtomPatternIndex))); |
+ ASSERT(0 <= index); |
+ ASSERT(index <= subject->length()); |
- uint32_t start_index = index; |
+ if (!subject->IsFlat()) FlattenString(subject); |
+ AssertNoAllocation no_heap_allocation; // ensure vectors stay valid |
+ // Extract flattened substrings of cons strings before determining asciiness. |
+ String* seq_sub = *subject; |
+ if (seq_sub->IsConsString()) seq_sub = ConsString::cast(seq_sub)->first(); |
- int value = Runtime::StringMatch(subject, needle, start_index); |
- if (value == -1) return Factory::null_value(); |
+ String* needle = String::cast(re->DataAt(JSRegExp::kAtomPatternIndex)); |
+ int needle_len = needle->length(); |
+ |
+ if (needle_len != 0) { |
+ if (index + needle_len > subject->length()) return Factory::null_value(); |
+ // dispatch on type of strings |
+ index = (needle->IsAsciiRepresentation() |
+ ? (seq_sub->IsAsciiRepresentation() |
+ ? SearchString(seq_sub->ToAsciiVector(), |
+ needle->ToAsciiVector(), |
+ index) |
+ : SearchString(seq_sub->ToUC16Vector(), |
+ needle->ToAsciiVector(), |
+ index)) |
+ : (seq_sub->IsAsciiRepresentation() |
+ ? SearchString(seq_sub->ToAsciiVector(), |
+ needle->ToUC16Vector(), |
+ index) |
+ : SearchString(seq_sub->ToUC16Vector(), |
+ needle->ToUC16Vector(), |
+ index))); |
+ if (index == -1) return Factory::null_value(); |
+ } |
ASSERT(last_match_info->HasFastElements()); |
{ |
NoHandleAllocation no_handles; |
FixedArray* array = FixedArray::cast(last_match_info->elements()); |
- SetAtomLastCapture(array, *subject, value, value + needle->length()); |
+ SetAtomLastCapture(array, *subject, index, index + needle_len); |
} |
return last_match_info; |
} |
@@ -364,7 +403,7 @@ |
AssertNoAllocation no_gc; |
String* sequential_string = *subject; |
if (subject->IsConsString()) { |
- sequential_string = ConsString::cast(*subject)->first(); |
+ sequential_string = ConsString::cast(*subject)->first(); |
} |
is_ascii = sequential_string->IsAsciiRepresentation(); |
} |