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

Unified Diff: src/runtime.cc

Issue 2814050: Version 2.2.23... (Closed) Base URL: http://v8.googlecode.com/svn/trunk/
Patch Set: '' Created 10 years, 5 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/parser.cc ('k') | src/spaces.cc » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: src/runtime.cc
===================================================================
--- src/runtime.cc (revision 5030)
+++ src/runtime.cc (working copy)
@@ -2285,6 +2285,134 @@
}
+template <typename ResultSeqString>
+static Object* StringReplaceRegExpWithEmptyString(String* subject,
+ JSRegExp* regexp,
+ JSArray* last_match_info) {
+ ASSERT(subject->IsFlat());
+
+ HandleScope handles;
+
+ Handle<String> subject_handle(subject);
+ Handle<JSRegExp> regexp_handle(regexp);
+ Handle<JSArray> last_match_info_handle(last_match_info);
+ Handle<Object> match = RegExpImpl::Exec(regexp_handle,
+ subject_handle,
+ 0,
+ last_match_info_handle);
+ if (match.is_null()) return Failure::Exception();
+ if (match->IsNull()) return *subject_handle;
+
+ ASSERT(last_match_info_handle->HasFastElements());
+
+ HandleScope loop_scope;
+ int start, end;
+ {
+ AssertNoAllocation match_info_array_is_not_in_a_handle;
+ FixedArray* match_info_array =
+ FixedArray::cast(last_match_info_handle->elements());
+
+ start = RegExpImpl::GetCapture(match_info_array, 0);
+ end = RegExpImpl::GetCapture(match_info_array, 1);
+ }
+
+ int length = subject->length();
+ int new_length = length - (end - start);
+ if (new_length == 0) {
+ return Heap::empty_string();
+ }
+ Handle<ResultSeqString> answer;
+ if (ResultSeqString::kHasAsciiEncoding) {
+ answer =
+ Handle<ResultSeqString>::cast(Factory::NewRawAsciiString(new_length));
+ } else {
+ answer =
+ Handle<ResultSeqString>::cast(Factory::NewRawTwoByteString(new_length));
+ }
+
+ // If the regexp isn't global, only match once.
+ if (!regexp_handle->GetFlags().is_global()) {
+ if (start > 0) {
+ String::WriteToFlat(*subject_handle,
+ answer->GetChars(),
+ 0,
+ start);
+ }
+ if (end < length) {
+ String::WriteToFlat(*subject_handle,
+ answer->GetChars() + start,
+ end,
+ length);
+ }
+ return *answer;
+ }
+
+ int prev = 0; // Index of end of last match.
+ int next = 0; // Start of next search (prev unless last match was empty).
+ int position = 0;
+
+ do {
+ if (prev < start) {
+ // Add substring subject[prev;start] to answer string.
+ String::WriteToFlat(*subject_handle,
+ answer->GetChars() + position,
+ prev,
+ start);
+ position += start - prev;
+ }
+ prev = end;
+ next = end;
+ // Continue from where the match ended, unless it was an empty match.
+ if (start == end) {
+ next++;
+ if (next > length) break;
+ }
+ match = RegExpImpl::Exec(regexp_handle,
+ subject_handle,
+ next,
+ last_match_info_handle);
+ if (match.is_null()) return Failure::Exception();
+ if (match->IsNull()) break;
+
+ ASSERT(last_match_info_handle->HasFastElements());
+ HandleScope loop_scope;
+ {
+ AssertNoAllocation match_info_array_is_not_in_a_handle;
+ FixedArray* match_info_array =
+ FixedArray::cast(last_match_info_handle->elements());
+ start = RegExpImpl::GetCapture(match_info_array, 0);
+ end = RegExpImpl::GetCapture(match_info_array, 1);
+ }
+ } while (true);
+
+ if (prev < length) {
+ // Add substring subject[prev;length] to answer string.
+ String::WriteToFlat(*subject_handle,
+ answer->GetChars() + position,
+ prev,
+ length);
+ position += length - prev;
+ }
+
+ if (position == 0) {
+ return Heap::empty_string();
+ }
+
+ // Shorten string and fill
+ int string_size = ResultSeqString::SizeFor(position);
+ int allocated_string_size = ResultSeqString::SizeFor(new_length);
+ int delta = allocated_string_size - string_size;
+
+ answer->set_length(position);
+ if (delta == 0) return *answer;
+
+ Address end_of_string = answer->address() + string_size;
+ Heap::CreateFillerObjectAt(end_of_string, delta);
+
+ return *answer;
+}
+
+
static Object* Runtime_StringReplaceRegExpWithString(Arguments args) {
ASSERT(args.length() == 4);
@@ -2311,6 +2439,16 @@
ASSERT(last_match_info->HasFastElements());
+ if (replacement->length() == 0) {
+ if (subject->HasOnlyAsciiChars()) {
+ return StringReplaceRegExpWithEmptyString<SeqAsciiString>(
+ subject, regexp, last_match_info);
+ } else {
+ return StringReplaceRegExpWithEmptyString<SeqTwoByteString>(
+ subject, regexp, last_match_info);
+ }
+ }
+
return StringReplaceRegExpWithString(subject,
regexp,
replacement,
@@ -5437,7 +5575,7 @@
CONVERT_DOUBLE_CHECKED(x, args[0]);
CONVERT_DOUBLE_CHECKED(y, args[1]);
- return Heap::AllocateHeapNumber(x + y);
+ return Heap::NumberFromDouble(x + y);
}
@@ -5447,7 +5585,7 @@
CONVERT_DOUBLE_CHECKED(x, args[0]);
CONVERT_DOUBLE_CHECKED(y, args[1]);
- return Heap::AllocateHeapNumber(x - y);
+ return Heap::NumberFromDouble(x - y);
}
@@ -5457,7 +5595,7 @@
CONVERT_DOUBLE_CHECKED(x, args[0]);
CONVERT_DOUBLE_CHECKED(y, args[1]);
- return Heap::AllocateHeapNumber(x * y);
+ return Heap::NumberFromDouble(x * y);
}
@@ -5466,7 +5604,7 @@
ASSERT(args.length() == 1);
CONVERT_DOUBLE_CHECKED(x, args[0]);
- return Heap::AllocateHeapNumber(-x);
+ return Heap::NumberFromDouble(-x);
}
@@ -6068,7 +6206,7 @@
// custom powi() function than the generic pow().
if (args[1]->IsSmi()) {
int y = Smi::cast(args[1])->value();
- return Heap::AllocateHeapNumber(powi(x, y));
+ return Heap::NumberFromDouble(powi(x, y));
}
CONVERT_DOUBLE_CHECKED(y, args[1]);
« no previous file with comments | « src/parser.cc ('k') | src/spaces.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698