Revert svn r4269 and r4298.

The C++ implementation of String.prototype.replace triggers an assert
in debug builds.

See http://code.google.com/p/v8/issues/detail?id=667

Review URL: http://codereview.chromium.org/1515005

git-svn-id: http://v8.googlecode.com/svn/trunk@4315 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
diff --git a/src/runtime.cc b/src/runtime.cc
index 7d104fa..b349815 100644
--- a/src/runtime.cc
+++ b/src/runtime.cc
@@ -1228,62 +1228,6 @@
 }
 
 
-static Object* Runtime_RegExpInitializeObject(Arguments args) {
-  AssertNoAllocation no_alloc;
-  ASSERT(args.length() == 5);
-  CONVERT_CHECKED(JSRegExp, regexp, args[0]);
-  CONVERT_CHECKED(String, source, args[1]);
-
-  Object* global = args[2];
-  if (!global->IsTrue()) global = Heap::false_value();
-
-  Object* ignoreCase = args[3];
-  if (!ignoreCase->IsTrue()) ignoreCase = Heap::false_value();
-
-  Object* multiline = args[4];
-  if (!multiline->IsTrue()) multiline = Heap::false_value();
-
-  Map* map = regexp->map();
-  Object* constructor = map->constructor();
-  if (constructor->IsJSFunction() &&
-      JSFunction::cast(constructor)->initial_map() == map) {
-    // If we still have the original map, set in-object properties directly.
-    regexp->InObjectPropertyAtPut(JSRegExp::kSourceFieldIndex, source);
-    // TODO(lrn): Consider skipping write barrier on booleans as well.
-    // Both true and false should be in oldspace at all times.
-    regexp->InObjectPropertyAtPut(JSRegExp::kGlobalFieldIndex, global);
-    regexp->InObjectPropertyAtPut(JSRegExp::kIgnoreCaseFieldIndex, ignoreCase);
-    regexp->InObjectPropertyAtPut(JSRegExp::kMultilineFieldIndex, multiline);
-    regexp->InObjectPropertyAtPut(JSRegExp::kLastIndexFieldIndex,
-                                  Smi::FromInt(0),
-                                  SKIP_WRITE_BARRIER);
-    return regexp;
-  }
-
-  // Map has changed, so use generic, but slower, method.
-  PropertyAttributes final =
-      static_cast<PropertyAttributes>(READ_ONLY | DONT_ENUM | DONT_DELETE);
-  PropertyAttributes writable =
-      static_cast<PropertyAttributes>(DONT_ENUM | DONT_DELETE);
-  regexp->IgnoreAttributesAndSetLocalProperty(Heap::source_symbol(),
-                                              source,
-                                              final);
-  regexp->IgnoreAttributesAndSetLocalProperty(Heap::global_symbol(),
-                                              global,
-                                              final);
-  regexp->IgnoreAttributesAndSetLocalProperty(Heap::ignore_case_symbol(),
-                                              ignoreCase,
-                                              final);
-  regexp->IgnoreAttributesAndSetLocalProperty(Heap::multiline_symbol(),
-                                              multiline,
-                                              final);
-  regexp->IgnoreAttributesAndSetLocalProperty(Heap::last_index_symbol(),
-                                              Smi::FromInt(0),
-                                              writable);
-  return regexp;
-}
-
-
 static Object* Runtime_FinishArrayPrototypeSetup(Arguments args) {
   HandleScope scope;
   ASSERT(args.length() == 1);
@@ -1623,91 +1567,9 @@
   return CharFromCode(args[0]);
 }
 
-
-class FixedArrayBuilder {
- public:
-  explicit FixedArrayBuilder(int initial_capacity)
-      : array_(Factory::NewFixedArrayWithHoles(initial_capacity)),
-        length_(0) {
-    // Require a non-zero initial size. Ensures that doubling the size to
-    // extend the array will work.
-    ASSERT(initial_capacity > 0);
-  }
-
-  explicit FixedArrayBuilder(Handle<FixedArray> backing_store)
-      : array_(backing_store),
-        length_(0) {
-    // Require a non-zero initial size. Ensures that doubling the size to
-    // extend the array will work.
-    ASSERT(backing_store->length() > 0);
-  }
-
-  bool HasCapacity(int elements) {
-    int length = array_->length();
-    int required_length = length_ + elements;
-    return (length >= required_length);
-  }
-
-  void EnsureCapacity(int elements) {
-    int length = array_->length();
-    int required_length = length_ + elements;
-    if (length < required_length) {
-      int new_length = length;
-      do {
-        new_length *= 2;
-      } while (new_length < required_length);
-      Handle<FixedArray> extended_array =
-          Factory::NewFixedArrayWithHoles(new_length);
-      array_->CopyTo(0, *extended_array, 0, length_);
-      array_ = extended_array;
-    }
-  }
-
-  void Add(Object* value) {
-    ASSERT(length_ < capacity());
-    array_->set(length_, value);
-    length_++;
-  }
-
-  void Add(Smi* value) {
-    ASSERT(length_ < capacity());
-    array_->set(length_, value);
-    length_++;
-  }
-
-  Handle<FixedArray> array() {
-    return array_;
-  }
-
-  int length() {
-    return length_;
-  }
-
-  int capacity() {
-    return array_->length();
-  }
-
-  Handle<JSArray> ToJSArray() {
-    Handle<JSArray> result_array = Factory::NewJSArrayWithElements(array_);
-    result_array->set_length(Smi::FromInt(length_));
-    return result_array;
-  }
-
-  Handle<JSArray> ToJSArray(Handle<JSArray> target_array) {
-    target_array->set_elements(*array_);
-    target_array->set_length(Smi::FromInt(length_));
-    return target_array;
-  }
-
- private:
-  Handle<FixedArray> array_;
-  int length_;
-};
-
-
 // Forward declarations.
-const int kStringBuilderConcatHelperLengthBits = 11;
-const int kStringBuilderConcatHelperPositionBits = 19;
+static const int kStringBuilderConcatHelperLengthBits = 11;
+static const int kStringBuilderConcatHelperPositionBits = 19;
 
 template <typename schar>
 static inline void StringBuilderConcatHelper(String*,
@@ -1715,19 +1577,15 @@
                                              FixedArray*,
                                              int);
 
-typedef BitField<int, 0, kStringBuilderConcatHelperLengthBits>
-    StringBuilderSubstringLength;
-typedef BitField<int,
-                 kStringBuilderConcatHelperLengthBits,
-                 kStringBuilderConcatHelperPositionBits>
-    StringBuilderSubstringPosition;
-
+typedef BitField<int, 0, 11> StringBuilderSubstringLength;
+typedef BitField<int, 11, 19> StringBuilderSubstringPosition;
 
 class ReplacementStringBuilder {
  public:
   ReplacementStringBuilder(Handle<String> subject, int estimated_part_count)
-      : array_builder_(estimated_part_count),
-        subject_(subject),
+      : subject_(subject),
+        parts_(Factory::NewFixedArray(estimated_part_count)),
+        part_count_(0),
         character_count_(0),
         is_ascii_(subject->IsAsciiRepresentation()) {
     // Require a non-zero initial size. Ensures that doubling the size to
@@ -1735,35 +1593,38 @@
     ASSERT(estimated_part_count > 0);
   }
 
-  static inline void AddSubjectSlice(FixedArrayBuilder* builder,
-                                     int from,
-                                     int to) {
+  void EnsureCapacity(int elements) {
+    int length = parts_->length();
+    int required_length = part_count_ + elements;
+    if (length < required_length) {
+      int new_length = length;
+      do {
+        new_length *= 2;
+      } while (new_length < required_length);
+      Handle<FixedArray> extended_array =
+          Factory::NewFixedArray(new_length);
+      parts_->CopyTo(0, *extended_array, 0, part_count_);
+      parts_ = extended_array;
+    }
+  }
+
+  void AddSubjectSlice(int from, int to) {
     ASSERT(from >= 0);
     int length = to - from;
     ASSERT(length > 0);
+    // Can we encode the slice in 11 bits for length and 19 bits for
+    // start position - as used by StringBuilderConcatHelper?
     if (StringBuilderSubstringLength::is_valid(length) &&
         StringBuilderSubstringPosition::is_valid(from)) {
       int encoded_slice = StringBuilderSubstringLength::encode(length) |
           StringBuilderSubstringPosition::encode(from);
-      builder->Add(Smi::FromInt(encoded_slice));
+      AddElement(Smi::FromInt(encoded_slice));
     } else {
       // Otherwise encode as two smis.
-      builder->Add(Smi::FromInt(-length));
-      builder->Add(Smi::FromInt(from));
+      AddElement(Smi::FromInt(-length));
+      AddElement(Smi::FromInt(from));
     }
-  }
-
-
-  void EnsureCapacity(int elements) {
-    array_builder_.EnsureCapacity(elements);
-  }
-
-
-  void AddSubjectSlice(int from, int to) {
-    AddSubjectSlice(&array_builder_, from, to);
-    // Can we encode the slice in 11 bits for length and 19 bits for
-    // start position - as used by StringBuilderConcatHelper?
-    IncrementCharacterCount(to - from);
+    IncrementCharacterCount(length);
   }
 
 
@@ -1779,7 +1640,7 @@
 
 
   Handle<String> ToString() {
-    if (array_builder_.length() == 0) {
+    if (part_count_ == 0) {
       return Factory::empty_string();
     }
 
@@ -1791,8 +1652,8 @@
       char* char_buffer = seq->GetChars();
       StringBuilderConcatHelper(*subject_,
                                 char_buffer,
-                                *array_builder_.array(),
-                                array_builder_.length());
+                                *parts_,
+                                part_count_);
     } else {
       // Non-ASCII.
       joined_string = NewRawTwoByteString(character_count_);
@@ -1801,8 +1662,8 @@
       uc16* char_buffer = seq->GetChars();
       StringBuilderConcatHelper(*subject_,
                                 char_buffer,
-                                *array_builder_.array(),
-                                array_builder_.length());
+                                *parts_,
+                                part_count_);
     }
     return joined_string;
   }
@@ -1815,14 +1676,8 @@
     character_count_ += by;
   }
 
-  Handle<JSArray> GetParts() {
-    Handle<JSArray> result =
-        Factory::NewJSArrayWithElements(array_builder_.array());
-    result->set_length(Smi::FromInt(array_builder_.length()));
-    return result;
-  }
-
  private:
+
   Handle<String> NewRawAsciiString(int size) {
     CALL_HEAP_FUNCTION(Heap::AllocateRawAsciiString(size), String);
   }
@@ -1835,12 +1690,14 @@
 
   void AddElement(Object* element) {
     ASSERT(element->IsSmi() || element->IsString());
-    ASSERT(array_builder_.capacity() > array_builder_.length());
-    array_builder_.Add(element);
+    ASSERT(parts_->length() > part_count_);
+    parts_->set(part_count_, element);
+    part_count_++;
   }
 
-  FixedArrayBuilder array_builder_;
   Handle<String> subject_;
+  Handle<FixedArray> parts_;
+  int part_count_;
   int character_count_;
   bool is_ascii_;
 };
@@ -2248,6 +2105,7 @@
 }
 
 
+
 // Cap on the maximal shift in the Boyer-Moore implementation. By setting a
 // limit, we can fix the size of tables.
 static const int kBMMaxShift = 0xff;
@@ -3011,468 +2869,6 @@
 }
 
 
-// Two smis before and after the match, for very long strings.
-const int kMaxBuilderEntriesPerRegExpMatch = 5;
-
-
-static void SetLastMatchInfoNoCaptures(Handle<String> subject,
-                                       Handle<JSArray> last_match_info,
-                                       int match_start,
-                                       int match_end) {
-  // Fill last_match_info with a single capture.
-  last_match_info->EnsureSize(2 + RegExpImpl::kLastMatchOverhead);
-  AssertNoAllocation no_gc;
-  FixedArray* elements = FixedArray::cast(last_match_info->elements());
-  RegExpImpl::SetLastCaptureCount(elements, 2);
-  RegExpImpl::SetLastInput(elements, *subject);
-  RegExpImpl::SetLastSubject(elements, *subject);
-  RegExpImpl::SetCapture(elements, 0, match_start);
-  RegExpImpl::SetCapture(elements, 1, match_end);
-}
-
-
-template <typename schar>
-static bool SearchCharMultiple(Vector<schar> subject,
-                               String* pattern,
-                               schar pattern_char,
-                               FixedArrayBuilder* builder,
-                               int* match_pos) {
-  // Position of last match.
-  int pos = *match_pos;
-  int subject_length = subject.length();
-  while (pos < subject_length) {
-    int match_end = pos + 1;
-    if (!builder->HasCapacity(kMaxBuilderEntriesPerRegExpMatch)) {
-      *match_pos = pos;
-      return false;
-    }
-    int new_pos = SingleCharIndexOf(subject, pattern_char, match_end);
-    if (new_pos >= 0) {
-      // Match has been found.
-      if (new_pos > match_end) {
-        ReplacementStringBuilder::AddSubjectSlice(builder, match_end, new_pos);
-      }
-      pos = new_pos;
-      builder->Add(pattern);
-    } else {
-      break;
-    }
-  }
-  if (pos + 1 < subject_length) {
-    ReplacementStringBuilder::AddSubjectSlice(builder, pos + 1, subject_length);
-  }
-  *match_pos = pos;
-  return true;
-}
-
-
-static bool SearchCharMultiple(Handle<String> subject,
-                               Handle<String> pattern,
-                               Handle<JSArray> last_match_info,
-                               FixedArrayBuilder* builder) {
-  ASSERT(subject->IsFlat());
-  ASSERT_EQ(1, pattern->length());
-  uc16 pattern_char = pattern->Get(0);
-  // Treating position before first as initial "previous match position".
-  int match_pos = -1;
-
-  for (;;) {  // Break when search complete.
-    builder->EnsureCapacity(kMaxBuilderEntriesPerRegExpMatch);
-    AssertNoAllocation no_gc;
-    if (subject->IsAsciiRepresentation()) {
-      if (pattern_char > String::kMaxAsciiCharCode) {
-        break;
-      }
-      Vector<const char> subject_vector = subject->ToAsciiVector();
-      char pattern_ascii_char = static_cast<char>(pattern_char);
-      bool complete = SearchCharMultiple<const char>(subject_vector,
-                                                     *pattern,
-                                                     pattern_ascii_char,
-                                                     builder,
-                                                     &match_pos);
-      if (complete) break;
-    } else {
-      Vector<const uc16> subject_vector = subject->ToUC16Vector();
-      bool complete = SearchCharMultiple<const uc16>(subject_vector,
-                                                     *pattern,
-                                                     pattern_char,
-                                                     builder,
-                                                     &match_pos);
-      if (complete) break;
-    }
-  }
-
-  if (match_pos >= 0) {
-    SetLastMatchInfoNoCaptures(subject,
-                               last_match_info,
-                               match_pos,
-                               match_pos + 1);
-    return true;
-  }
-  return false;  // No matches at all.
-}
-
-
-template <typename schar, typename pchar>
-static bool SearchStringMultiple(Vector<schar> subject,
-                                 String* pattern,
-                                 Vector<pchar> pattern_string,
-                                 FixedArrayBuilder* builder,
-                                 int* match_pos) {
-  int pos = *match_pos;
-  int subject_length = subject.length();
-  int pattern_length = pattern_string.length();
-  int max_search_start = subject_length - pattern_length;
-  bool is_ascii = (sizeof(schar) == 1);
-  StringSearchStrategy strategy =
-      InitializeStringSearch(pattern_string, is_ascii);
-  switch (strategy) {
-    case SEARCH_FAIL: return false;
-    case SEARCH_SHORT:
-      while (pos <= max_search_start) {
-        if (!builder->HasCapacity(kMaxBuilderEntriesPerRegExpMatch)) {
-          *match_pos = pos;
-          return false;
-        }
-        // Position of end of previous match.
-        int match_end = pos + pattern_length;
-        int new_pos = SimpleIndexOf(subject, pattern_string, match_end);
-        if (new_pos >= 0) {
-          // A match.
-          if (new_pos > match_end) {
-            ReplacementStringBuilder::AddSubjectSlice(builder,
-                                                      match_end,
-                                                      new_pos);
-          }
-          pos = new_pos;
-          builder->Add(pattern);
-        } else {
-          break;
-        }
-      }
-      break;
-    case SEARCH_LONG:
-      while (pos  <= max_search_start) {
-        if (!builder->HasCapacity(kMaxBuilderEntriesPerRegExpMatch)) {
-         *match_pos = pos;
-         return false;
-        }
-        int new_pos = ComplexIndexOf(subject,
-                                     pattern_string,
-                                     pos + pattern_length);
-        if (new_pos >= 0) {
-         // A match has been found.
-          if (new_pos > pos) {
-           ReplacementStringBuilder::AddSubjectSlice(builder, pos, new_pos);
-          }
-          pos = new_pos;
-          builder->Add(pattern);
-        } else {
-         break;
-        }
-      }
-      break;
-  }
-  if (pos < max_search_start) {
-    ReplacementStringBuilder::AddSubjectSlice(builder,
-                                              pos + pattern_length,
-                                              subject_length);
-  }
-  *match_pos = pos;
-  return true;
-}
-
-
-static bool SearchStringMultiple(Handle<String> subject,
-                                 Handle<String> pattern,
-                                 Handle<JSArray> last_match_info,
-                                 FixedArrayBuilder* builder) {
-  ASSERT(subject->IsFlat());
-  ASSERT(pattern->IsFlat());
-  ASSERT(pattern->length() > 1);
-
-  // Treating as if a previous match was before first character.
-  int match_pos = -pattern->length();
-
-  for (;;) {  // Break when search complete.
-    builder->EnsureCapacity(kMaxBuilderEntriesPerRegExpMatch);
-    AssertNoAllocation no_gc;
-    if (subject->IsAsciiRepresentation()) {
-      Vector<const char> subject_vector = subject->ToAsciiVector();
-      if (pattern->IsAsciiRepresentation()) {
-        if (SearchStringMultiple(subject_vector,
-                                 *pattern,
-                                 pattern->ToAsciiVector(),
-                                 builder,
-                                 &match_pos)) break;
-      } else {
-        if (SearchStringMultiple(subject_vector,
-                                 *pattern,
-                                 pattern->ToUC16Vector(),
-                                 builder,
-                                 &match_pos)) break;
-      }
-    } else {
-      Vector<const uc16> subject_vector = subject->ToUC16Vector();
-      if (pattern->IsAsciiRepresentation()) {
-        if (SearchStringMultiple(subject_vector,
-                                 *pattern,
-                                 pattern->ToAsciiVector(),
-                                 builder,
-                                 &match_pos)) break;
-      } else {
-        if (SearchStringMultiple(subject_vector,
-                                 *pattern,
-                                 pattern->ToUC16Vector(),
-                                 builder,
-                                 &match_pos)) break;
-      }
-    }
-  }
-
-  if (match_pos >= 0) {
-    SetLastMatchInfoNoCaptures(subject,
-                               last_match_info,
-                               match_pos,
-                               match_pos + pattern->length());
-    return true;
-  }
-  return false;  // No matches at all.
-}
-
-
-static RegExpImpl::IrregexpResult SearchRegExpNoCaptureMultiple(
-    Handle<String> subject,
-    Handle<JSRegExp> regexp,
-    Handle<JSArray> last_match_array,
-    FixedArrayBuilder* builder) {
-  ASSERT(subject->IsFlat());
-  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);
-  Vector<int> register_vector(registers.vector(), registers.length());
-  int subject_length = subject->length();
-
-  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;
-      builder->Add(*Factory::NewSubString(subject, match_start, match_end));
-      if (match_start != match_end) {
-        pos = match_end;
-      } else {
-        pos = match_end + 1;
-        if (pos > subject_length) break;
-      }
-    } else if (result == RegExpImpl::RE_FAILURE) {
-      break;
-    } else {
-      ASSERT_EQ(result, RegExpImpl::RE_EXCEPTION);
-      return result;
-    }
-  }
-
-  if (match_start >= 0) {
-    if (match_end < subject_length) {
-      ReplacementStringBuilder::AddSubjectSlice(builder,
-                                                match_end,
-                                                subject_length);
-    }
-    SetLastMatchInfoNoCaptures(subject,
-                               last_match_array,
-                               match_start,
-                               match_end);
-    return RegExpImpl::RE_SUCCESS;
-  } else {
-    return RegExpImpl::RE_FAILURE;  // No matches at all.
-  }
-}
-
-
-static RegExpImpl::IrregexpResult SearchRegExpMultiple(
-    Handle<String> subject,
-    Handle<JSRegExp> regexp,
-    Handle<JSArray> last_match_array,
-    FixedArrayBuilder* builder) {
-
-  ASSERT(subject->IsFlat());
-  int required_registers = RegExpImpl::IrregexpPrepare(regexp, subject);
-  if (required_registers < 0) return RegExpImpl::RE_EXCEPTION;
-
-  OffsetsVector registers(required_registers);
-  Vector<int> register_vector(registers.vector(), registers.length());
-
-  RegExpImpl::IrregexpResult result =
-      RegExpImpl::IrregexpExecOnce(regexp,
-                                   subject,
-                                   0,
-                                   register_vector);
-
-  int capture_count = regexp->CaptureCount();
-  int subject_length = subject->length();
-
-  // Position to search from.
-  int pos = 0;
-  // End of previous match. Differs from pos if match was empty.
-  int match_end = 0;
-  if (result == RegExpImpl::RE_SUCCESS) {
-    // Need to keep a copy of the previous match for creating last_match_info
-    // at the end, so we have two vectors that we swap between.
-    OffsetsVector registers2(required_registers);
-    Vector<int> prev_register_vector(registers2.vector(), registers2.length());
-
-    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;
-        // Arguments array to replace function is match, captures, index and
-        // subject, i.e., 3 + capture count in total.
-        Handle<FixedArray> elements = Factory::NewFixedArray(3 + capture_count);
-        elements->set(0, *Factory::NewSubString(subject,
-                                                match_start,
-                                                match_end));
-        for (int i = 1; i <= capture_count; i++) {
-          Handle<String> substring =
-              Factory::NewSubString(subject,
-                                    register_vector[i * 2],
-                                    register_vector[i * 2 + 1]);
-          elements->set(i, *substring);
-        }
-        elements->set(capture_count + 1, Smi::FromInt(match_start));
-        elements->set(capture_count + 2, *subject);
-        builder->Add(*Factory::NewJSArrayWithElements(elements));
-      }
-      // Swap register vectors, so the last successful match is in
-      // prev_register_vector.
-      Vector<int> tmp = prev_register_vector;
-      prev_register_vector = register_vector;
-      register_vector = tmp;
-
-      if (match_end > match_start) {
-        pos = match_end;
-      } else {
-        pos = match_end + 1;
-        if (pos > subject_length) {
-          break;
-        }
-      }
-
-      result = RegExpImpl::IrregexpExecOnce(regexp,
-                                            subject,
-                                            pos,
-                                            register_vector);
-    } while (result == RegExpImpl::RE_SUCCESS);
-
-    if (result != RegExpImpl::RE_EXCEPTION) {
-      // Finished matching, with at least one match.
-      if (match_end < subject_length) {
-        ReplacementStringBuilder::AddSubjectSlice(builder,
-                                                  match_end,
-                                                  subject_length);
-      }
-
-      int last_match_capture_count = (capture_count + 1) * 2;
-      int last_match_array_size =
-          last_match_capture_count + RegExpImpl::kLastMatchOverhead;
-      last_match_array->EnsureSize(last_match_array_size);
-      AssertNoAllocation no_gc;
-      FixedArray* elements = FixedArray::cast(last_match_array->elements());
-      RegExpImpl::SetLastCaptureCount(elements, last_match_capture_count);
-      RegExpImpl::SetLastSubject(elements, *subject);
-      RegExpImpl::SetLastInput(elements, *subject);
-      for (int i = 0; i < last_match_capture_count; i++) {
-        RegExpImpl::SetCapture(elements, i, prev_register_vector[i]);
-      }
-      return RegExpImpl::RE_SUCCESS;
-    }
-  }
-  // No matches at all, return failure or exception result directly.
-  return result;
-}
-
-
-static Object* Runtime_RegExpExecMultiple(Arguments args) {
-  ASSERT(args.length() == 4);
-  HandleScope handles;
-
-  CONVERT_ARG_CHECKED(String, subject, 1);
-  if (!subject->IsFlat()) { FlattenString(subject); }
-  CONVERT_ARG_CHECKED(JSRegExp, regexp, 0);
-  CONVERT_ARG_CHECKED(JSArray, last_match_info, 2);
-  CONVERT_ARG_CHECKED(JSArray, result_array, 3);
-
-  ASSERT(last_match_info->HasFastElements());
-  ASSERT(regexp->GetFlags().is_global());
-  Handle<FixedArray> result_elements;
-  if (result_array->HasFastElements()) {
-    result_elements =
-        Handle<FixedArray>(FixedArray::cast(result_array->elements()));
-  } else {
-    result_elements = Factory::NewFixedArrayWithHoles(16);
-  }
-  FixedArrayBuilder builder(result_elements);
-
-  if (regexp->TypeTag() == JSRegExp::ATOM) {
-    Handle<String> pattern(
-        String::cast(regexp->DataAt(JSRegExp::kAtomPatternIndex)));
-    int pattern_length = pattern->length();
-    if (pattern_length == 1) {
-      if (SearchCharMultiple(subject, pattern, last_match_info, &builder)) {
-        return *builder.ToJSArray(result_array);
-      }
-      return Heap::null_value();
-    }
-
-    if (!pattern->IsFlat()) FlattenString(pattern);
-    if (SearchStringMultiple(subject, pattern, last_match_info, &builder)) {
-      return *builder.ToJSArray(result_array);
-    }
-    return Heap::null_value();
-  }
-
-  ASSERT_EQ(regexp->TypeTag(), JSRegExp::IRREGEXP);
-
-  RegExpImpl::IrregexpResult result;
-  if (regexp->CaptureCount() == 0) {
-    result = SearchRegExpNoCaptureMultiple(subject,
-                                           regexp,
-                                           last_match_info,
-                                           &builder);
-  } else {
-    result = SearchRegExpMultiple(subject, regexp, last_match_info, &builder);
-  }
-  if (result == RegExpImpl::RE_SUCCESS) return *builder.ToJSArray(result_array);
-  if (result == RegExpImpl::RE_FAILURE) return Heap::null_value();
-  ASSERT_EQ(result, RegExpImpl::RE_EXCEPTION);
-  return Failure::Exception();
-}
-
-
 static Object* Runtime_NumberToRadixString(Arguments args) {
   NoHandleAllocation ha;
   ASSERT(args.length() == 2);