Author: [email protected]
Date: Tue Jun 23 00:47:04 2009
New Revision: 2248

Added:
    branches/1.1/test/mjsunit/regexp-captures.js
    branches/1.1/test/mjsunit/regress/regress-6-9-regexp.js
Modified:
    branches/1.1/ChangeLog
    branches/1.1/src/api.cc
    branches/1.1/src/jsregexp.cc

Log:
Merge two regular expression engine fixes to 1.1 branch.
Review URL: http://codereview.chromium.org/146019

Modified: branches/1.1/ChangeLog
==============================================================================
--- branches/1.1/ChangeLog      (original)
+++ branches/1.1/ChangeLog      Tue Jun 23 00:47:04 2009
@@ -1,3 +1,8 @@
+2009-06-23: Version 1.1.10.14
+
+       Fixed two bugs in the regular expression engine.
+
+
  2009-05-18: Version 1.1.10.13

          Added multiple generations to the script compilation cache to

Modified: branches/1.1/src/api.cc
==============================================================================
--- branches/1.1/src/api.cc     (original)
+++ branches/1.1/src/api.cc     Tue Jun 23 00:47:04 2009
@@ -2373,7 +2373,7 @@


  const char* v8::V8::GetVersion() {
-  return "1.1.10.13";
+  return "1.1.10.14";
  }



Modified: branches/1.1/src/jsregexp.cc
==============================================================================
--- branches/1.1/src/jsregexp.cc        (original)
+++ branches/1.1/src/jsregexp.cc        Tue Jun 23 00:47:04 2009
@@ -400,7 +400,6 @@
    // Prepare space for the return values.
    int number_of_capture_registers =
        (IrregexpNumberOfCaptures(FixedArray::cast(jsregexp->data())) + 1) *  
2;
-  OffsetsVector offsets(number_of_capture_registers);

  #ifdef DEBUG
    if (FLAG_trace_regexp_bytecodes) {
@@ -416,17 +415,18 @@

    last_match_info->EnsureSize(number_of_capture_registers +  
kLastMatchOverhead);

-  int* offsets_vector = offsets.vector();
    bool rc;
+  FixedArray* array;

    // Dispatch to the correct RegExp implementation.
-
    Handle<String> original_subject = subject;
    Handle<FixedArray> regexp(FixedArray::cast(jsregexp->data()));
    if (UseNativeRegexp()) {
  #ifdef ARM
      UNREACHABLE();
  #else
+    OffsetsVector captures(number_of_capture_registers);
+    int* captures_vector = captures.vector();
      RegExpMacroAssemblerIA32::Result res;
      do {
        bool is_ascii = StringShape(*subject).IsAsciiRepresentation();
@@ -436,8 +436,8 @@
        Handle<Code> code(RegExpImpl::IrregexpNativeCode(*regexp, is_ascii));
        res = RegExpMacroAssemblerIA32::Match(code,
                                              subject,
-                                            offsets_vector,
-                                            offsets.length(),
+                                            captures_vector,
+                                            captures.length(),
                                              previous_index);
        // If result is RETRY, the string have changed representation, and we
        // must restart from scratch.
@@ -450,39 +450,51 @@
          || 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]);
+    }
  #endif
    } else {
      bool is_ascii = StringShape(*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--) {
-      offsets_vector[i] = -1;
+      register_vector[i] = -1;
      }
      Handle<ByteArray> byte_codes(IrregexpByteCode(*regexp, is_ascii));

      rc = IrregexpInterpreter::Match(byte_codes,
                                      subject,
-                                    offsets_vector,
+                                    register_vector,
                                      previous_index);
-  }
-
-  // Handle results from RegExp implementation.
+    if (!rc) return Factory::null_value();

-  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, register_vector[i]);
+      SetCapture(array, i + 1, register_vector[i + 1]);
+    }
    }

-  FixedArray* array = last_match_info->elements();
-  ASSERT(array->length() >= number_of_capture_registers +  
kLastMatchOverhead);
-  // The captures come in (start, end+1) pairs.
    SetLastCaptureCount(array, number_of_capture_registers);
    SetLastSubject(array, *original_subject);
    SetLastInput(array, *original_subject);
-  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]);
-  }
+
    return last_match_info;
  }

@@ -891,12 +903,13 @@
    // The "+1" is to avoid a push_limit of zero if stack_limit_slack() is 1.
    const int push_limit = (assembler->stack_limit_slack() + 1) / 2;

+  // Count pushes performed to force a stack limit check occasionally.
+  int pushes = 0;
+
    for (int reg = 0; reg <= max_register; reg++) {
      if (!affected_registers.Get(reg)) {
        continue;
      }
-    // Count pushes performed to force a stack limit check occasionally.
-    int pushes = 0;

      // The chronologically first deferred action in the trace
      // is used to infer the action needed to restore a register
@@ -1880,7 +1893,8 @@
          uint32_t differing_bits = (from ^ to);
          // A mask and compare is only perfect if the differing bits form a
          // number like 00011111 with one single block of trailing 1s.
-        if ((differing_bits & (differing_bits + 1)) == 0) {
+        if ((differing_bits & (differing_bits + 1)) == 0 &&
+             from + differing_bits == to) {
            pos->determines_perfectly = true;
          }
          uint32_t common_bits = ~SmearBitsRight(differing_bits);

Added: branches/1.1/test/mjsunit/regexp-captures.js
==============================================================================
--- (empty file)
+++ branches/1.1/test/mjsunit/regexp-captures.js        Tue Jun 23 00:47:04 2009
@@ -0,0 +1,31 @@
+// Copyright 2009 the V8 project authors. All rights reserved.
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//     * Redistributions of source code must retain the above copyright
+//       notice, this list of conditions and the following disclaimer.
+//     * Redistributions in binary form must reproduce the above
+//       copyright notice, this list of conditions and the following
+//       disclaimer in the documentation and/or other materials provided
+//       with the distribution.
+//     * Neither the name of Google Inc. nor the names of its
+//       contributors may be used to endorse or promote products derived
+//       from this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+var re = /^(((N({)?)|(R)|(U)|(V)|(B)|(H)|(n((n)|(r)|(v)|(h))?)|(r(r)?)|(v)| 
(b((n)|(b))?)|(h))|((Y)|(A)|(E)|(o(u)?)|(p(u)?)|(q(u)?)|(s)|(t)|(u)|(w)| 
(x(u)?)|(y)|(z)|(a((T)|(A)|(L))?)|(c)|(e)|(f(u)?)|(g(u)?)|(i)|(j)|(l)| 
(m(u)?)))+/;
+var r = new RegExp(re)
+var str = "Avtnennan gunzvmu pubExnY nEvln vaTxh rmuhguhaTxnY"
+assertTrue(r.test(str));

Added: branches/1.1/test/mjsunit/regress/regress-6-9-regexp.js
==============================================================================
--- (empty file)
+++ branches/1.1/test/mjsunit/regress/regress-6-9-regexp.js     Tue Jun 23  
00:47:04 2009
@@ -0,0 +1,30 @@
+// Copyright 2009 the V8 project authors. All rights reserved.
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//     * Redistributions of source code must retain the above copyright
+//       notice, this list of conditions and the following disclaimer.
+//     * Redistributions in binary form must reproduce the above
+//       copyright notice, this list of conditions and the following
+//       disclaimer in the documentation and/or other materials provided
+//       with the distribution.
+//     * Neither the name of Google Inc. nor the names of its
+//       contributors may be used to endorse or promote products derived
+//       from this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// Check that the perfect mask check isn't overly optimistic.
+
+assertFalse(/[6-9]/.test('2'));

--~--~---------~--~----~------------~-------~--~----~
v8-dev mailing list
[email protected]
http://groups.google.com/group/v8-dev
-~----------~----~----~----~------~----~------~--~---

Reply via email to