Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(507)

Unified Diff: src/regexp/arm/regexp-macro-assembler-arm.cc

Issue 1418963009: Experimental support for RegExp lookbehind. (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: mips64 port Created 5 years, 1 month ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « src/regexp/arm/regexp-macro-assembler-arm.h ('k') | src/regexp/arm64/regexp-macro-assembler-arm64.h » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: src/regexp/arm/regexp-macro-assembler-arm.cc
diff --git a/src/regexp/arm/regexp-macro-assembler-arm.cc b/src/regexp/arm/regexp-macro-assembler-arm.cc
index d296d90e7dffecf9e8ba7b9fef78d694c9848c23..422a4eec9c645eb1f943559228bc0f7ccff9ec71 100644
--- a/src/regexp/arm/regexp-macro-assembler-arm.cc
+++ b/src/regexp/arm/regexp-macro-assembler-arm.cc
@@ -176,29 +176,26 @@ void RegExpMacroAssemblerARM::CheckCharacterGT(uc16 limit, Label* on_greater) {
void RegExpMacroAssemblerARM::CheckAtStart(Label* on_at_start) {
- Label not_at_start;
- // Did we start the match at the start of the string at all?
- __ ldr(r0, MemOperand(frame_pointer(), kStartIndex));
- __ cmp(r0, Operand::Zero());
- BranchOrBacktrack(ne, &not_at_start);
-
- // If we did, are we still at the start of the input?
+ __ add(r0, end_of_input_address(), current_input_offset());
+ __ ldr(r1, MemOperand(frame_pointer(), kStartIndex));
+ for (int i = 0; i < char_size(); i++) {
+ __ add(r0, r0, r1);
+ }
__ ldr(r1, MemOperand(frame_pointer(), kInputStart));
- __ add(r0, end_of_input_address(), Operand(current_input_offset()));
__ cmp(r0, r1);
BranchOrBacktrack(eq, on_at_start);
- __ bind(&not_at_start);
}
-void RegExpMacroAssemblerARM::CheckNotAtStart(Label* on_not_at_start) {
- // Did we start the match at the start of the string at all?
- __ ldr(r0, MemOperand(frame_pointer(), kStartIndex));
- __ cmp(r0, Operand::Zero());
- BranchOrBacktrack(ne, on_not_at_start);
- // If we did, are we still at the start of the input?
+void RegExpMacroAssemblerARM::CheckNotAtStart(int cp_offset,
+ Label* on_not_at_start) {
+ __ add(r0, end_of_input_address(), current_input_offset());
+ __ add(r0, r0, Operand(cp_offset * char_size()));
+ __ ldr(r1, MemOperand(frame_pointer(), kStartIndex));
+ for (int i = 0; i < char_size(); i++) {
+ __ add(r0, r0, r1);
+ }
__ ldr(r1, MemOperand(frame_pointer(), kInputStart));
- __ add(r0, end_of_input_address(), Operand(current_input_offset()));
__ cmp(r0, r1);
BranchOrBacktrack(ne, on_not_at_start);
}
@@ -220,20 +217,31 @@ void RegExpMacroAssemblerARM::CheckGreedyLoop(Label* on_equal) {
void RegExpMacroAssemblerARM::CheckNotBackReferenceIgnoreCase(
- int start_reg,
- Label* on_no_match) {
+ int start_reg, bool read_backward, Label* on_no_match) {
Label fallthrough;
__ ldr(r0, register_location(start_reg)); // Index of start of capture
__ ldr(r1, register_location(start_reg + 1)); // Index of end of capture
__ sub(r1, r1, r0, SetCC); // Length of capture.
- // If length is zero, either the capture is empty or it is not participating.
- // In either case succeed immediately.
- __ b(eq, &fallthrough);
+ // The length of the capture can only be negative if the end of the
+ // capture is not yet recorded. If the length is zero, the capture is
+ // either empty or uncaptured. In either of those cases, succeed.
+ __ b(le, &fallthrough);
// Check that there are enough characters left in the input.
- __ cmn(r1, Operand(current_input_offset()));
- BranchOrBacktrack(gt, on_no_match);
+ if (read_backward) {
+ __ add(r2, end_of_input_address(), current_input_offset());
+ __ ldr(r3, MemOperand(frame_pointer(), kStartIndex));
+ for (int i = 0; i < char_size(); i++) {
+ __ add(r2, r2, r3);
+ }
+ __ ldr(r3, MemOperand(frame_pointer(), kInputStart));
+ __ cmp(r2, r3);
+ BranchOrBacktrack(lt, on_no_match);
+ } else {
+ __ cmn(r1, Operand(current_input_offset()));
+ BranchOrBacktrack(gt, on_no_match);
+ }
if (mode_ == LATIN1) {
Label success;
@@ -242,9 +250,12 @@ void RegExpMacroAssemblerARM::CheckNotBackReferenceIgnoreCase(
// r0 - offset of start of capture
// r1 - length of capture
- __ add(r0, r0, Operand(end_of_input_address()));
- __ add(r2, end_of_input_address(), Operand(current_input_offset()));
- __ add(r1, r0, Operand(r1));
+ __ add(r0, r0, end_of_input_address());
+ __ add(r2, end_of_input_address(), current_input_offset());
+ if (read_backward) {
+ __ sub(r2, r2, r1); // Offset by length when matching backwards.
+ }
+ __ add(r1, r0, r1);
// r0 - Address of start of capture.
// r1 - Address of end of capture
@@ -283,6 +294,12 @@ void RegExpMacroAssemblerARM::CheckNotBackReferenceIgnoreCase(
__ bind(&success);
// Compute new value of character position after the matched part.
__ sub(current_input_offset(), r2, end_of_input_address());
+ if (read_backward) {
+ __ ldr(r0, register_location(start_reg)); // Index of start of capture
+ __ ldr(r1, register_location(start_reg + 1)); // Index of end of capture
+ __ add(current_input_offset(), current_input_offset(), r0);
+ __ sub(current_input_offset(), current_input_offset(), r1);
+ }
} else {
DCHECK(mode_ == UC16);
int argument_count = 4;
@@ -305,7 +322,10 @@ void RegExpMacroAssemblerARM::CheckNotBackReferenceIgnoreCase(
// Save length in callee-save register for use on return.
__ mov(r4, Operand(r1));
// Address of current input position.
- __ add(r1, current_input_offset(), Operand(end_of_input_address()));
+ __ add(r1, current_input_offset(), end_of_input_address());
+ if (read_backward) {
+ __ sub(r1, r1, r4);
+ }
// Isolate.
__ mov(r3, Operand(ExternalReference::isolate_address(isolate())));
@@ -319,17 +339,22 @@ void RegExpMacroAssemblerARM::CheckNotBackReferenceIgnoreCase(
// Check if function returned non-zero for success or zero for failure.
__ cmp(r0, Operand::Zero());
BranchOrBacktrack(eq, on_no_match);
- // On success, increment position by length of capture.
- __ add(current_input_offset(), current_input_offset(), Operand(r4));
+
+ // On success, advance position by length of capture.
+ if (read_backward) {
+ __ sub(current_input_offset(), current_input_offset(), r4);
+ } else {
+ __ add(current_input_offset(), current_input_offset(), r4);
+ }
}
__ bind(&fallthrough);
}
-void RegExpMacroAssemblerARM::CheckNotBackReference(
- int start_reg,
- Label* on_no_match) {
+void RegExpMacroAssemblerARM::CheckNotBackReference(int start_reg,
+ bool read_backward,
+ Label* on_no_match) {
Label fallthrough;
Label success;
@@ -337,17 +362,35 @@ void RegExpMacroAssemblerARM::CheckNotBackReference(
__ ldr(r0, register_location(start_reg));
__ ldr(r1, register_location(start_reg + 1));
__ sub(r1, r1, r0, SetCC); // Length to check.
- // Succeed on empty capture (including no capture).
- __ b(eq, &fallthrough);
+
+ // The length of the capture can only be negative if the end of the
+ // capture is not yet recorded. If the length is zero, the capture is
+ // either empty or uncaptured. In either of those cases, succeed.
+ __ b(le, &fallthrough);
// Check that there are enough characters left in the input.
- __ cmn(r1, Operand(current_input_offset()));
- BranchOrBacktrack(gt, on_no_match);
+ if (read_backward) {
+ __ add(r2, end_of_input_address(), current_input_offset());
+ __ ldr(r3, MemOperand(frame_pointer(), kStartIndex));
+ for (int i = 0; i < char_size(); i++) {
+ __ add(r2, r2, r3);
+ }
+ __ ldr(r3, MemOperand(frame_pointer(), kInputStart));
+ __ cmp(r2, r3);
+ BranchOrBacktrack(lt, on_no_match);
+ } else {
+ __ cmn(r1, Operand(current_input_offset()));
+ BranchOrBacktrack(gt, on_no_match);
+ }
- // Compute pointers to match string and capture string
- __ add(r0, r0, Operand(end_of_input_address()));
- __ add(r2, end_of_input_address(), Operand(current_input_offset()));
- __ add(r1, r1, Operand(r0));
+ // r0 - offset of start of capture
+ // r1 - length of capture
+ __ add(r0, r0, end_of_input_address());
+ __ add(r2, end_of_input_address(), current_input_offset());
+ if (read_backward) {
+ __ sub(r2, r2, r1); // Offset by length when matching backwards.
+ }
+ __ add(r1, r0, r1);
Label loop;
__ bind(&loop);
@@ -366,6 +409,13 @@ void RegExpMacroAssemblerARM::CheckNotBackReference(
// Move current character position to position after match.
__ sub(current_input_offset(), r2, end_of_input_address());
+ if (read_backward) {
+ __ ldr(r0, register_location(start_reg)); // Index of start of capture
+ __ ldr(r1, register_location(start_reg + 1)); // Index of end of capture
+ __ add(current_input_offset(), current_input_offset(), r0);
+ __ sub(current_input_offset(), current_input_offset(), r1);
+ }
+
__ bind(&fallthrough);
}
@@ -892,10 +942,13 @@ void RegExpMacroAssemblerARM::LoadCurrentCharacter(int cp_offset,
Label* on_end_of_input,
bool check_bounds,
int characters) {
- DCHECK(cp_offset >= -1); // ^ and \b can look behind one character.
DCHECK(cp_offset < (1<<30)); // Be sane! (And ensure negation works)
if (check_bounds) {
- CheckPosition(cp_offset + characters - 1, on_end_of_input);
+ if (cp_offset >= 0) {
+ CheckPosition(cp_offset + characters - 1, on_end_of_input);
+ } else {
+ CheckPosition(cp_offset, on_end_of_input);
+ }
}
LoadCurrentCharacterUnchecked(cp_offset, characters);
}
@@ -1069,8 +1122,20 @@ MemOperand RegExpMacroAssemblerARM::register_location(int register_index) {
void RegExpMacroAssemblerARM::CheckPosition(int cp_offset,
Label* on_outside_input) {
- __ cmp(current_input_offset(), Operand(-cp_offset * char_size()));
- BranchOrBacktrack(ge, on_outside_input);
+ if (cp_offset >= 0) {
+ __ cmp(current_input_offset(), Operand(-cp_offset * char_size()));
+ BranchOrBacktrack(ge, on_outside_input);
+ } else {
+ __ add(r0, end_of_input_address(), current_input_offset());
+ __ add(r0, r0, Operand(cp_offset * char_size()));
+ __ ldr(r1, MemOperand(frame_pointer(), kStartIndex));
+ for (int i = 0; i < char_size(); i++) {
+ __ add(r0, r0, r1);
+ }
+ __ ldr(r1, MemOperand(frame_pointer(), kInputStart));
+ __ cmp(r0, r1);
+ BranchOrBacktrack(lt, on_outside_input);
+ }
}
« no previous file with comments | « src/regexp/arm/regexp-macro-assembler-arm.h ('k') | src/regexp/arm64/regexp-macro-assembler-arm64.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698