Index: src/regexp/ppc/regexp-macro-assembler-ppc.cc |
diff --git a/src/regexp/ppc/regexp-macro-assembler-ppc.cc b/src/regexp/ppc/regexp-macro-assembler-ppc.cc |
index 03f9741147e81cc7d323ce0f01157b55475fd825..d11b20d81f246b8e71dabfdb10560dc85b86ce1d 100644 |
--- a/src/regexp/ppc/regexp-macro-assembler-ppc.cc |
+++ b/src/regexp/ppc/regexp-macro-assembler-ppc.cc |
@@ -60,7 +60,7 @@ namespace internal { |
* - fp[-32] void* input_string (location of a handle containing the string). |
* - fp[-36] success counter (only for global regexps to count matches). |
* - fp[-40] Offset of location before start of input (effectively character |
- * position -1). Used to initialize capture registers to a |
+ * string start - 1). Used to initialize capture registers to a |
* non-position. |
* - fp[-44] At start (if 1, we are starting at the start of the |
* string, otherwise 0) |
@@ -189,30 +189,18 @@ void RegExpMacroAssemblerPPC::CheckCharacterGT(uc16 limit, Label* on_greater) { |
void RegExpMacroAssemblerPPC::CheckAtStart(Label* on_at_start) { |
- Label not_at_start; |
- // Did we start the match at the start of the string at all? |
- __ LoadP(r3, MemOperand(frame_pointer(), kStartIndex)); |
- __ cmpi(r3, Operand::Zero()); |
- BranchOrBacktrack(ne, ¬_at_start); |
- |
- // If we did, are we still at the start of the input? |
- __ LoadP(r4, MemOperand(frame_pointer(), kInputStart)); |
- __ mr(r0, current_input_offset()); |
- __ add(r3, end_of_input_address(), r0); |
- __ cmp(r4, r3); |
+ __ LoadP(r4, MemOperand(frame_pointer(), kStringStartMinusOne)); |
+ __ addi(r3, current_input_offset(), Operand(-char_size())); |
+ __ cmp(r3, r4); |
BranchOrBacktrack(eq, on_at_start); |
- __ bind(¬_at_start); |
} |
-void RegExpMacroAssemblerPPC::CheckNotAtStart(Label* on_not_at_start) { |
- // Did we start the match at the start of the string at all? |
- __ LoadP(r3, MemOperand(frame_pointer(), kStartIndex)); |
- __ cmpi(r3, Operand::Zero()); |
- BranchOrBacktrack(ne, on_not_at_start); |
- // If we did, are we still at the start of the input? |
- __ LoadP(r4, MemOperand(frame_pointer(), kInputStart)); |
- __ add(r3, end_of_input_address(), current_input_offset()); |
+void RegExpMacroAssemblerPPC::CheckNotAtStart(int cp_offset, |
+ Label* on_not_at_start) { |
+ __ LoadP(r4, MemOperand(frame_pointer(), kStringStartMinusOne)); |
+ __ addi(r3, current_input_offset(), |
+ Operand(-char_size() + cp_offset * char_size())); |
__ cmp(r3, r4); |
BranchOrBacktrack(ne, on_not_at_start); |
} |
@@ -238,20 +226,27 @@ void RegExpMacroAssemblerPPC::CheckGreedyLoop(Label* on_equal) { |
void RegExpMacroAssemblerPPC::CheckNotBackReferenceIgnoreCase( |
- int start_reg, Label* on_no_match) { |
+ int start_reg, bool read_backward, Label* on_no_match) { |
Label fallthrough; |
__ LoadP(r3, register_location(start_reg), r0); // Index of start of capture |
__ LoadP(r4, register_location(start_reg + 1), r0); // Index of end |
__ sub(r4, r4, r3, LeaveOE, SetRC); // Length of capture. |
- // If length is zero, either the capture is empty or it is not participating. |
- // In either case succeed immediately. |
+ // At this point, the capture registers are either both set or both cleared. |
+ // If the capture length is zero, then the capture is either empty or cleared. |
+ // Fall through in both cases. |
__ beq(&fallthrough, cr0); |
// Check that there are enough characters left in the input. |
- __ add(r0, r4, current_input_offset(), LeaveOE, SetRC); |
- // __ cmn(r1, Operand(current_input_offset())); |
- BranchOrBacktrack(gt, on_no_match, cr0); |
+ if (read_backward) { |
+ __ LoadP(r6, MemOperand(frame_pointer(), kStringStartMinusOne)); |
+ __ add(r6, r6, r4); |
+ __ cmp(current_input_offset(), r6); |
+ BranchOrBacktrack(le, on_no_match); |
+ } else { |
+ __ add(r0, r4, current_input_offset(), LeaveOE, SetRC); |
+ BranchOrBacktrack(gt, on_no_match, cr0); |
+ } |
if (mode_ == LATIN1) { |
Label success; |
@@ -262,6 +257,9 @@ void RegExpMacroAssemblerPPC::CheckNotBackReferenceIgnoreCase( |
// r4 - length of capture |
__ add(r3, r3, end_of_input_address()); |
__ add(r5, end_of_input_address(), current_input_offset()); |
+ if (read_backward) { |
+ __ sub(r5, r5, r4); // Offset by length when matching backwards. |
+ } |
__ add(r4, r3, r4); |
// r3 - Address of start of capture. |
@@ -303,6 +301,13 @@ void RegExpMacroAssemblerPPC::CheckNotBackReferenceIgnoreCase( |
__ bind(&success); |
// Compute new value of character position after the matched part. |
__ sub(current_input_offset(), r5, end_of_input_address()); |
+ if (read_backward) { |
+ __ LoadP(r3, register_location(start_reg)); // Index of start of capture |
+ __ LoadP(r4, |
+ register_location(start_reg + 1)); // Index of end of capture |
+ __ add(current_input_offset(), current_input_offset(), r3); |
+ __ sub(current_input_offset(), current_input_offset(), r4); |
+ } |
} else { |
DCHECK(mode_ == UC16); |
int argument_count = 4; |
@@ -326,6 +331,9 @@ void RegExpMacroAssemblerPPC::CheckNotBackReferenceIgnoreCase( |
__ mr(r25, r4); |
// Address of current input position. |
__ add(r4, current_input_offset(), end_of_input_address()); |
+ if (read_backward) { |
+ __ sub(r4, r4, r25); |
+ } |
// Isolate. |
__ mov(r6, Operand(ExternalReference::isolate_address(isolate()))); |
@@ -339,8 +347,13 @@ void RegExpMacroAssemblerPPC::CheckNotBackReferenceIgnoreCase( |
// Check if function returned non-zero for success or zero for failure. |
__ cmpi(r3, Operand::Zero()); |
BranchOrBacktrack(eq, on_no_match); |
- // On success, increment position by length of capture. |
- __ add(current_input_offset(), current_input_offset(), r25); |
+ |
+ // On success, advance position by length of capture. |
+ if (read_backward) { |
+ __ sub(current_input_offset(), current_input_offset(), r25); |
+ } else { |
+ __ add(current_input_offset(), current_input_offset(), r25); |
+ } |
} |
__ bind(&fallthrough); |
@@ -348,6 +361,7 @@ void RegExpMacroAssemblerPPC::CheckNotBackReferenceIgnoreCase( |
void RegExpMacroAssemblerPPC::CheckNotBackReference(int start_reg, |
+ bool read_backward, |
Label* on_no_match) { |
Label fallthrough; |
Label success; |
@@ -356,16 +370,30 @@ void RegExpMacroAssemblerPPC::CheckNotBackReference(int start_reg, |
__ LoadP(r3, register_location(start_reg), r0); |
__ LoadP(r4, register_location(start_reg + 1), r0); |
__ sub(r4, r4, r3, LeaveOE, SetRC); // Length to check. |
- // Succeed on empty capture (including no capture). |
+ |
+ // At this point, the capture registers are either both set or both cleared. |
+ // If the capture length is zero, then the capture is either empty or cleared. |
+ // Fall through in both cases. |
__ beq(&fallthrough, cr0); |
// Check that there are enough characters left in the input. |
- __ add(r0, r4, current_input_offset(), LeaveOE, SetRC); |
- BranchOrBacktrack(gt, on_no_match, cr0); |
+ if (read_backward) { |
+ __ LoadP(r6, MemOperand(frame_pointer(), kStringStartMinusOne)); |
+ __ add(r6, r6, r4); |
+ __ cmp(current_input_offset(), r6); |
+ BranchOrBacktrack(lt, on_no_match); |
+ } else { |
+ __ add(r0, r4, current_input_offset(), LeaveOE, SetRC); |
+ BranchOrBacktrack(gt, on_no_match, cr0); |
+ } |
- // Compute pointers to match string and capture string |
+ // r3 - offset of start of capture |
+ // r4 - length of capture |
__ add(r3, r3, end_of_input_address()); |
__ add(r5, end_of_input_address(), current_input_offset()); |
+ if (read_backward) { |
+ __ sub(r5, r5, r4); // Offset by length when matching backwards. |
+ } |
__ add(r4, r4, r3); |
Label loop; |
@@ -389,6 +417,13 @@ void RegExpMacroAssemblerPPC::CheckNotBackReference(int start_reg, |
// Move current character position to position after match. |
__ sub(current_input_offset(), r5, end_of_input_address()); |
+ if (read_backward) { |
+ __ LoadP(r3, register_location(start_reg)); // Index of start of capture |
+ __ LoadP(r4, register_location(start_reg + 1)); // Index of end of capture |
+ __ add(current_input_offset(), current_input_offset(), r3); |
+ __ sub(current_input_offset(), current_input_offset(), r4); |
+ } |
+ |
__ bind(&fallthrough); |
} |
@@ -639,7 +674,7 @@ Handle<HeapObject> RegExpMacroAssemblerPPC::GetCode(Handle<String> source) { |
__ addi(frame_pointer(), sp, Operand(8 * kPointerSize)); |
__ li(r3, Operand::Zero()); |
__ push(r3); // Make room for success counter and initialize it to 0. |
- __ push(r3); // Make room for "position - 1" constant (value is irrelevant) |
+ __ push(r3); // Make room for "string start - 1" constant. |
// Check if we have space on the stack for registers. |
Label stack_limit_hit; |
Label stack_ok; |
@@ -688,7 +723,7 @@ Handle<HeapObject> RegExpMacroAssemblerPPC::GetCode(Handle<String> source) { |
} |
// Store this value in a local variable, for use when clearing |
// position registers. |
- __ StoreP(r3, MemOperand(frame_pointer(), kInputStartMinusOne)); |
+ __ StoreP(r3, MemOperand(frame_pointer(), kStringStartMinusOne)); |
// Initialize code pointer register |
__ mov(code_pointer(), Operand(masm_->CodeObject())); |
@@ -797,7 +832,7 @@ Handle<HeapObject> RegExpMacroAssemblerPPC::GetCode(Handle<String> source) { |
__ StoreP(r5, MemOperand(frame_pointer(), kRegisterOutput)); |
// Prepare r3 to initialize registers with its value in the next run. |
- __ LoadP(r3, MemOperand(frame_pointer(), kInputStartMinusOne)); |
+ __ LoadP(r3, MemOperand(frame_pointer(), kStringStartMinusOne)); |
if (global_with_zero_length_check()) { |
// Special case for zero-length matches. |
@@ -936,10 +971,13 @@ void RegExpMacroAssemblerPPC::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); |
} |
@@ -1028,7 +1066,7 @@ void RegExpMacroAssemblerPPC::WriteCurrentPositionToRegister(int reg, |
void RegExpMacroAssemblerPPC::ClearRegisters(int reg_from, int reg_to) { |
DCHECK(reg_from <= reg_to); |
- __ LoadP(r3, MemOperand(frame_pointer(), kInputStartMinusOne)); |
+ __ LoadP(r3, MemOperand(frame_pointer(), kStringStartMinusOne)); |
for (int reg = reg_from; reg <= reg_to; reg++) { |
__ StoreP(r3, register_location(reg), r0); |
} |
@@ -1132,8 +1170,15 @@ MemOperand RegExpMacroAssemblerPPC::register_location(int register_index) { |
void RegExpMacroAssemblerPPC::CheckPosition(int cp_offset, |
Label* on_outside_input) { |
- __ Cmpi(current_input_offset(), Operand(-cp_offset * char_size()), r0); |
- BranchOrBacktrack(ge, on_outside_input); |
+ if (cp_offset >= 0) { |
+ __ Cmpi(current_input_offset(), Operand(-cp_offset * char_size()), r0); |
+ BranchOrBacktrack(ge, on_outside_input); |
+ } else { |
+ __ LoadP(r4, MemOperand(frame_pointer(), kStringStartMinusOne)); |
+ __ addi(r3, current_input_offset(), Operand(cp_offset * char_size())); |
+ __ cmp(r3, r4); |
+ BranchOrBacktrack(le, on_outside_input); |
+ } |
} |