| 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, ¬_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(¬_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);
|
| + }
|
| }
|
|
|
|
|
|
|