Author: [EMAIL PROTECTED]
Date: Wed Dec 3 05:24:34 2008
New Revision: 908
Modified:
branches/bleeding_edge/src/interpreter-irregexp.cc
branches/bleeding_edge/src/jsregexp.cc
branches/bleeding_edge/src/regexp-macro-assembler-ia32.cc
branches/bleeding_edge/test/cctest/test-regexp.cc
Log:
Matching a back-reference must handle unbound start-register (but can
assume that if start register is bound, then end register is bound too).
After matching a back reference, the character position is advanced past
the match
Modified: branches/bleeding_edge/src/interpreter-irregexp.cc
==============================================================================
--- branches/bleeding_edge/src/interpreter-irregexp.cc (original)
+++ branches/bleeding_edge/src/interpreter-irregexp.cc Wed Dec 3 05:24:34
2008
@@ -333,6 +333,10 @@
BYTECODE(CHECK_NOT_BACK_REF) {
int from = registers[pc[1]];
int len = registers[pc[1] + 1] - from;
+ if (from < 0 || len <= 0) {
+ pc += BC_CHECK_NOT_BACK_REF_LENGTH;
+ break;
+ }
if (current + len > subject.length()) {
pc = code_base + Load32(pc + 2);
break;
@@ -353,6 +357,10 @@
BYTECODE(CHECK_NOT_BACK_REF_NO_CASE) {
int from = registers[pc[1]];
int len = registers[pc[1] + 1] - from;
+ if (from < 0 || len <= 0) {
+ pc += BC_CHECK_NOT_BACK_REF_NO_CASE_LENGTH;
+ break;
+ }
if (current + len > subject.length()) {
pc = code_base + Load32(pc + 2);
break;
Modified: branches/bleeding_edge/src/jsregexp.cc
==============================================================================
--- branches/bleeding_edge/src/jsregexp.cc (original)
+++ branches/bleeding_edge/src/jsregexp.cc Wed Dec 3 05:24:34 2008
@@ -1541,10 +1541,6 @@
bool BackReferenceNode::Emit(RegExpCompiler* compiler) {
RegExpMacroAssembler* macro = compiler->macro_assembler();
Bind(macro);
- // Check whether the registers are uninitialized and always
- // succeed if they are.
- macro->IfRegisterLT(start_reg_, 0, on_success()->label());
- macro->IfRegisterLT(end_reg_, 0, on_success()->label());
ASSERT_EQ(start_reg_ + 1, end_reg_);
if (info()->at_end) {
// If we are constrained to match at the end of the input then succeed
Modified: branches/bleeding_edge/src/regexp-macro-assembler-ia32.cc
==============================================================================
--- branches/bleeding_edge/src/regexp-macro-assembler-ia32.cc (original)
+++ branches/bleeding_edge/src/regexp-macro-assembler-ia32.cc Wed Dec 3
05:24:34 2008
@@ -260,20 +260,27 @@
__ mov(eax, register_location(start_reg));
__ mov(ecx, register_location(start_reg + 1));
__ sub(ecx, Operand(eax)); // Length to check.
- __ j(less, on_no_match);
+ BranchOrBacktrack(less, on_no_match);
__ j(equal, &fallthrough);
- // check that there are sufficient characters left in the input
+ // Check that there are sufficient characters left in the input.
__ mov(ebx, edi);
__ add(ebx, Operand(ecx));
- __ j(greater, on_no_match);
- __ mov(ebx, Operand(edi));
- __ push(esi);
+ BranchOrBacktrack(greater, on_no_match);
+
+ __ mov(ebx, edi);
+ __ mov(edx, esi);
__ add(edi, Operand(esi));
__ add(esi, Operand(eax));
__ rep_cmpsb();
- __ pop(esi);
- __ mov(edi, Operand(ebx));
- BranchOrBacktrack(not_equal, on_no_match);
+ __ mov(esi, edx);
+ Label success;
+ __ j(equal, &success);
+ __ mov(edi, ebx);
+ BranchOrBacktrack(no_condition, on_no_match);
+
+ __ bind(&success);
+ __ sub(edi, Operand(esi));
+
__ bind(&fallthrough);
}
@@ -629,7 +636,6 @@
ExternalReference::address_of_stack_guard_limit();
__ cmp(esp, Operand::StaticVariable(stack_guard_limit));
__ j(above, &no_preempt, taken);
-
__ push(edi); // Current position.
__ push(edx); // Current character.
// Restore original edi, esi.
Modified: branches/bleeding_edge/test/cctest/test-regexp.cc
==============================================================================
--- branches/bleeding_edge/test/cctest/test-regexp.cc (original)
+++ branches/bleeding_edge/test/cctest/test-regexp.cc Wed Dec 3 05:24:34
2008
@@ -768,6 +768,56 @@
CHECK(!success);
}
+
+TEST(MacroAssemblerIA32BackReference) {
+ V8::Initialize(NULL);
+
+ // regexp-macro-assembler-ia32 needs a handle scope to allocate
+ // byte-arrays for constants.
+ v8::HandleScope scope;
+
+ RegExpMacroAssemblerIA32 m(RegExpMacroAssemblerIA32::ASCII, 3);
+
+ m.WriteCurrentPositionToRegister(0);
+ m.AdvanceCurrentPosition(2);
+ m.WriteCurrentPositionToRegister(1);
+ Label nomatch;
+ m.CheckNotBackReference(0, &nomatch);
+ m.Fail();
+ m.Bind(&nomatch);
+ m.AdvanceCurrentPosition(2);
+ Label missing_match;
+ m.CheckNotBackReference(0, &missing_match);
+ m.WriteCurrentPositionToRegister(2);
+ m.Succeed();
+ m.Bind(&missing_match);
+ m.Fail();
+
+ Handle<Object> code_object = m.GetCode();
+ Handle<Code> code = Handle<Code>::cast(code_object);
+
+ Handle<String> input = Factory::NewStringFromAscii(CStrVector("fooofo"));
+ Handle<SeqAsciiString> seq_input = Handle<SeqAsciiString>::cast(input);
+ Address start_adr = seq_input->GetCharsAddress();
+ int start_offset = start_adr - reinterpret_cast<Address>(*seq_input);
+ int end_offset = start_offset + seq_input->length();
+
+ int output[3];
+ bool success = RegExpMacroAssemblerIA32::Execute(*code,
+ seq_input.location(),
+ start_offset,
+ end_offset,
+ output,
+ true);
+
+ CHECK(success);
+ CHECK_EQ(0, output[0]);
+ CHECK_EQ(2, output[1]);
+ CHECK_EQ(6, output[2]);
+}
+
+
+
TEST(MacroAssemblerIA32AtStart) {
V8::Initialize(NULL);
--~--~---------~--~----~------------~-------~--~----~
v8-dev mailing list
[email protected]
http://groups.google.com/group/v8-dev
-~----------~----~----~----~------~----~------~--~---