Version 1.2.13.

Fixed issue 397, issue 398, and issue 399.

Added support for breakpoint groups.

Fixed bugs introduced with the new global object representation.

Fixed a few bugs in the ARM code generator.


git-svn-id: http://v8.googlecode.com/svn/trunk@2406 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
diff --git a/src/jsregexp.cc b/src/jsregexp.cc
index 879f671..852d431 100644
--- a/src/jsregexp.cc
+++ b/src/jsregexp.cc
@@ -263,7 +263,6 @@
 
 // Irregexp implementation.
 
-
 // Ensures that the regexp object contains a compiled version of the
 // source for either ASCII or non-ASCII strings.
 // If the compiled version doesn't already exist, it is compiled
@@ -271,25 +270,26 @@
 // If compilation fails, an exception is thrown and this function
 // returns false.
 bool RegExpImpl::EnsureCompiledIrregexp(Handle<JSRegExp> re, bool is_ascii) {
-  int index;
-  if (is_ascii) {
-    index = JSRegExp::kIrregexpASCIICodeIndex;
-  } else {
-    index = JSRegExp::kIrregexpUC16CodeIndex;
-  }
-  Object* entry = re->DataAt(index);
-  if (!entry->IsTheHole()) {
-    // A value has already been compiled.
-    if (entry->IsJSObject()) {
-      // If it's a JS value, it's an error.
-      Top::Throw(entry);
-      return false;
-    }
-    return true;
-  }
+#ifdef V8_NATIVE_REGEXP
+  if (re->DataAt(JSRegExp::code_index(is_ascii))->IsCode()) return true;
+#else  // ! V8_NATIVE_REGEXP (RegExp interpreter code)
+  if (re->DataAt(JSRegExp::code_index(is_ascii))->IsByteArray()) return true;
+#endif
+  return CompileIrregexp(re, is_ascii);
+}
 
+
+bool RegExpImpl::CompileIrregexp(Handle<JSRegExp> re, bool is_ascii) {
   // Compile the RegExp.
   CompilationZoneScope zone_scope(DELETE_ON_EXIT);
+  Object* entry = re->DataAt(JSRegExp::code_index(is_ascii));
+  if (entry->IsJSObject()) {
+    // If it's a JSObject, a previous compilation failed and threw this object.
+    // Re-throw the object without trying again.
+    Top::Throw(entry);
+    return false;
+  }
+  ASSERT(entry->IsTheHole());
 
   JSRegExp::Flags flags = re->GetFlags();
 
@@ -302,7 +302,7 @@
   FlatStringReader reader(pattern);
   if (!ParseRegExp(&reader, flags.is_multiline(), &compile_data)) {
     // Throw an exception if we fail to parse the pattern.
-    // THIS SHOULD NOT HAPPEN. We already parsed it successfully once.
+    // THIS SHOULD NOT HAPPEN. We already pre-parsed it successfully once.
     ThrowRegExpException(re,
                          pattern,
                          compile_data.error,
@@ -325,17 +325,15 @@
     Handle<Object> regexp_err =
         Factory::NewSyntaxError("malformed_regexp", array);
     Top::Throw(*regexp_err);
-    re->SetDataAt(index, *regexp_err);
+    re->SetDataAt(JSRegExp::code_index(is_ascii), *regexp_err);
     return false;
   }
 
-  NoHandleAllocation no_handles;
-
-  FixedArray* data = FixedArray::cast(re->data());
-  data->set(index, result.code);
-  int register_max = IrregexpMaxRegisterCount(data);
+  Handle<FixedArray> data = Handle<FixedArray>(FixedArray::cast(re->data()));
+  data->set(JSRegExp::code_index(is_ascii), result.code);
+  int register_max = IrregexpMaxRegisterCount(*data);
   if (result.num_registers > register_max) {
-    SetIrregexpMaxRegisterCount(data, result.num_registers);
+    SetIrregexpMaxRegisterCount(*data, result.num_registers);
   }
 
   return true;
@@ -364,24 +362,12 @@
 
 
 ByteArray* RegExpImpl::IrregexpByteCode(FixedArray* re, bool is_ascii) {
-  int index;
-  if (is_ascii) {
-    index = JSRegExp::kIrregexpASCIICodeIndex;
-  } else {
-    index = JSRegExp::kIrregexpUC16CodeIndex;
-  }
-  return ByteArray::cast(re->get(index));
+  return ByteArray::cast(re->get(JSRegExp::code_index(is_ascii)));
 }
 
 
 Code* RegExpImpl::IrregexpNativeCode(FixedArray* re, bool is_ascii) {
-  int index;
-  if (is_ascii) {
-    index = JSRegExp::kIrregexpASCIICodeIndex;
-  } else {
-    index = JSRegExp::kIrregexpUC16CodeIndex;
-  }
-  return Code::cast(re->get(index));
+  return Code::cast(re->get(JSRegExp::code_index(is_ascii)));
 }
 
 
@@ -408,6 +394,7 @@
   int number_of_capture_registers =
       (IrregexpNumberOfCaptures(FixedArray::cast(jsregexp->data())) + 1) * 2;
 
+#ifndef V8_NATIVE_REGEXP
 #ifdef DEBUG
   if (FLAG_trace_regexp_bytecodes) {
     String* pattern = jsregexp->Pattern();
@@ -415,6 +402,7 @@
     PrintF("\n\nSubject string: '%s'\n\n", *(subject->ToCString()));
   }
 #endif
+#endif
 
   if (!subject->IsFlat()) {
     FlattenString(subject);
@@ -422,88 +410,83 @@
 
   last_match_info->EnsureSize(number_of_capture_registers + kLastMatchOverhead);
 
-  bool rc;
-  // We have to initialize this with something to make gcc happy but we can't
-  // initialize it with its real value until after the GC-causing things are
-  // over.
-  FixedArray* array = NULL;
+  Handle<FixedArray> array;
 
   // Dispatch to the correct RegExp implementation.
-  Handle<String> original_subject = subject;
   Handle<FixedArray> regexp(FixedArray::cast(jsregexp->data()));
-  if (UseNativeRegexp()) {
+#ifdef V8_NATIVE_REGEXP
 #if V8_TARGET_ARCH_IA32
-    OffsetsVector captures(number_of_capture_registers);
-    int* captures_vector = captures.vector();
-    RegExpMacroAssemblerIA32::Result res;
-    do {
-      bool is_ascii = subject->IsAsciiRepresentation();
-      if (!EnsureCompiledIrregexp(jsregexp, is_ascii)) {
-        return Handle<Object>::null();
-      }
-      Handle<Code> code(RegExpImpl::IrregexpNativeCode(*regexp, is_ascii));
-      res = RegExpMacroAssemblerIA32::Match(code,
-                                            subject,
-                                            captures_vector,
-                                            captures.length(),
-                                            previous_index);
-      // If result is RETRY, the string have changed representation, and we
-      // must restart from scratch.
-    } while (res == RegExpMacroAssemblerIA32::RETRY);
-    if (res == RegExpMacroAssemblerIA32::EXCEPTION) {
-      ASSERT(Top::has_pending_exception());
-      return Handle<Object>::null();
-    }
-    ASSERT(res == RegExpMacroAssemblerIA32::SUCCESS
-        || res == RegExpMacroAssemblerIA32::FAILURE);
-
-    rc = (res == RegExpMacroAssemblerIA32::SUCCESS);
-    if (!rc) return Factory::null_value();
-
-    array = last_match_info->elements();
-    ASSERT(array->length() >= number_of_capture_registers + kLastMatchOverhead);
-    // The captures come in (start, end+1) pairs.
-    for (int i = 0; i < number_of_capture_registers; i += 2) {
-      SetCapture(array, i, captures_vector[i]);
-      SetCapture(array, i + 1, captures_vector[i + 1]);
-    }
-#else  // !V8_TARGET_ARCH_IA32
-    UNREACHABLE();
-#endif
-  } else {
+  OffsetsVector captures(number_of_capture_registers);
+  int* captures_vector = captures.vector();
+  RegExpMacroAssemblerIA32::Result res;
+  do {
     bool is_ascii = subject->IsAsciiRepresentation();
     if (!EnsureCompiledIrregexp(jsregexp, is_ascii)) {
       return Handle<Object>::null();
     }
-    // Now that we have done EnsureCompiledIrregexp we can get the number of
-    // registers.
-    int number_of_registers =
-        IrregexpNumberOfRegisters(FixedArray::cast(jsregexp->data()));
-    OffsetsVector registers(number_of_registers);
-    int* register_vector = registers.vector();
-    for (int i = number_of_capture_registers - 1; i >= 0; i--) {
-      register_vector[i] = -1;
-    }
-    Handle<ByteArray> byte_codes(IrregexpByteCode(*regexp, is_ascii));
+    Handle<Code> code(RegExpImpl::IrregexpNativeCode(*regexp, is_ascii));
+    res = RegExpMacroAssemblerIA32::Match(code,
+                                          subject,
+                                          captures_vector,
+                                          captures.length(),
+                                          previous_index);
+    // If result is RETRY, the string have changed representation, and we
+    // must restart from scratch.
+  } while (res == RegExpMacroAssemblerIA32::RETRY);
+  if (res == RegExpMacroAssemblerIA32::EXCEPTION) {
+    ASSERT(Top::has_pending_exception());
+    return Handle<Object>::null();
+  }
+  ASSERT(res == RegExpMacroAssemblerIA32::SUCCESS
+      || res == RegExpMacroAssemblerIA32::FAILURE);
 
-    rc = IrregexpInterpreter::Match(byte_codes,
-                                    subject,
-                                    register_vector,
-                                    previous_index);
-    if (!rc) return Factory::null_value();
+  if (res != RegExpMacroAssemblerIA32::SUCCESS) return Factory::null_value();
 
-    array = last_match_info->elements();
-    ASSERT(array->length() >= number_of_capture_registers + kLastMatchOverhead);
-    // The captures come in (start, end+1) pairs.
-    for (int i = 0; i < number_of_capture_registers; i += 2) {
-      SetCapture(array, i, register_vector[i]);
-      SetCapture(array, i + 1, register_vector[i + 1]);
-    }
+  array = Handle<FixedArray>(last_match_info->elements());
+  ASSERT(array->length() >= number_of_capture_registers + kLastMatchOverhead);
+  // The captures come in (start, end+1) pairs.
+  for (int i = 0; i < number_of_capture_registers; i += 2) {
+    SetCapture(*array, i, captures_vector[i]);
+    SetCapture(*array, i + 1, captures_vector[i + 1]);
+  }
+#else  // !V8_TARGET_ARCH_IA32
+    UNREACHABLE();
+#endif  // V8_TARGET_ARCH_IA32
+#else  // !V8_NATIVE_REGEXP
+  bool is_ascii = subject->IsAsciiRepresentation();
+  if (!EnsureCompiledIrregexp(jsregexp, is_ascii)) {
+    return Handle<Object>::null();
+  }
+  // Now that we have done EnsureCompiledIrregexp we can get the number of
+  // registers.
+  int number_of_registers =
+      IrregexpNumberOfRegisters(FixedArray::cast(jsregexp->data()));
+  OffsetsVector registers(number_of_registers);
+  int* register_vector = registers.vector();
+  for (int i = number_of_capture_registers - 1; i >= 0; i--) {
+    register_vector[i] = -1;
+  }
+  Handle<ByteArray> byte_codes(IrregexpByteCode(*regexp, is_ascii));
+
+  if (!IrregexpInterpreter::Match(byte_codes,
+                                  subject,
+                                  register_vector,
+                                  previous_index)) {
+    return Factory::null_value();
   }
 
-  SetLastCaptureCount(array, number_of_capture_registers);
-  SetLastSubject(array, *original_subject);
-  SetLastInput(array, *original_subject);
+  array = Handle<FixedArray>(last_match_info->elements());
+  ASSERT(array->length() >= number_of_capture_registers + kLastMatchOverhead);
+  // The captures come in (start, end+1) pairs.
+  for (int i = 0; i < number_of_capture_registers; i += 2) {
+    SetCapture(*array, i, register_vector[i]);
+    SetCapture(*array, i + 1, register_vector[i + 1]);
+  }
+#endif  // V8_NATIVE_REGEXP
+
+  SetLastCaptureCount(*array, number_of_capture_registers);
+  SetLastSubject(*array, *subject);
+  SetLastInput(*array, *subject);
 
   return last_match_info;
 }
@@ -4474,35 +4457,38 @@
 
   NodeInfo info = *node->info();
 
-  if (RegExpImpl::UseNativeRegexp()) {
+#ifdef V8_NATIVE_REGEXP
 #ifdef V8_TARGET_ARCH_ARM
-    UNREACHABLE();
+  // ARM native regexp not implemented yet.
+  UNREACHABLE();
 #endif
 #ifdef V8_TARGET_ARCH_X64
-    UNREACHABLE();
+  // X64 native regexp not implemented yet.
+  UNREACHABLE();
 #endif
 #ifdef V8_TARGET_ARCH_IA32
-    RegExpMacroAssemblerIA32::Mode mode;
-    if (is_ascii) {
-      mode = RegExpMacroAssemblerIA32::ASCII;
-    } else {
-      mode = RegExpMacroAssemblerIA32::UC16;
-    }
-    RegExpMacroAssemblerIA32 macro_assembler(mode,
-                                             (data->capture_count + 1) * 2);
-    return compiler.Assemble(&macro_assembler,
-                             node,
-                             data->capture_count,
-                             pattern);
-#endif
+  RegExpMacroAssemblerIA32::Mode mode;
+  if (is_ascii) {
+    mode = RegExpMacroAssemblerIA32::ASCII;
+  } else {
+    mode = RegExpMacroAssemblerIA32::UC16;
   }
+  RegExpMacroAssemblerIA32 macro_assembler(mode,
+                                           (data->capture_count + 1) * 2);
+  return compiler.Assemble(&macro_assembler,
+                           node,
+                           data->capture_count,
+                           pattern);
+#endif
+#else  // ! V8_NATIVE_REGEXP
+  // Interpreted regexp.
   EmbeddedVector<byte, 1024> codes;
   RegExpMacroAssemblerIrregexp macro_assembler(codes);
   return compiler.Assemble(&macro_assembler,
                            node,
                            data->capture_count,
                            pattern);
+#endif  // V8_NATIVE_REGEXP
 }
 
-
 }}  // namespace v8::internal