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
-~----------~----~----~----~------~----~------~--~---