Index: src/regexp/arm64/regexp-macro-assembler-arm64.cc |
diff --git a/src/regexp/arm64/regexp-macro-assembler-arm64.cc b/src/regexp/arm64/regexp-macro-assembler-arm64.cc |
index 7a4c3acca6ebf29faaca064189b0a45090f84829..d440879e26f87f00c74dcbf8e8ea0e4a52440fd7 100644 |
--- a/src/regexp/arm64/regexp-macro-assembler-arm64.cc |
+++ b/src/regexp/arm64/regexp-macro-assembler-arm64.cc |
@@ -210,17 +210,23 @@ |
void RegExpMacroAssemblerARM64::CheckAtStart(Label* on_at_start) { |
- __ Add(w10, current_input_offset(), Operand(-char_size())); |
- __ Cmp(w10, string_start_minus_one()); |
+ Label not_at_start; |
+ // Did we start the match at the start of the input string? |
+ CompareAndBranchOrBacktrack(start_offset(), 0, ne, ¬_at_start); |
+ // If we did, are we still at the start of the input string? |
+ __ Add(x10, input_end(), Operand(current_input_offset(), SXTW)); |
+ __ Cmp(x10, input_start()); |
BranchOrBacktrack(eq, on_at_start); |
-} |
- |
- |
-void RegExpMacroAssemblerARM64::CheckNotAtStart(int cp_offset, |
- Label* on_not_at_start) { |
- __ Add(w10, current_input_offset(), |
- Operand(-char_size() + cp_offset * char_size())); |
- __ Cmp(w10, string_start_minus_one()); |
+ __ Bind(¬_at_start); |
+} |
+ |
+ |
+void RegExpMacroAssemblerARM64::CheckNotAtStart(Label* on_not_at_start) { |
+ // Did we start the match at the start of the input string? |
+ CompareAndBranchOrBacktrack(start_offset(), 0, ne, on_not_at_start); |
+ // If we did, are we still at the start of the input string? |
+ __ Add(x10, input_end(), Operand(current_input_offset(), SXTW)); |
+ __ Cmp(x10, input_start()); |
BranchOrBacktrack(ne, on_not_at_start); |
} |
@@ -271,9 +277,9 @@ |
BranchOrBacktrack(eq, on_equal); |
} |
- |
void RegExpMacroAssemblerARM64::CheckNotBackReferenceIgnoreCase( |
- int start_reg, bool read_backward, Label* on_no_match) { |
+ int start_reg, |
+ Label* on_no_match) { |
Label fallthrough; |
Register capture_start_offset = w10; |
@@ -291,21 +297,12 @@ |
__ Ldp(w11, capture_start_offset, capture_location(start_reg, x10)); |
} |
__ Sub(capture_length, w11, capture_start_offset); // Length to check. |
- |
- // 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. |
- __ CompareAndBranch(capture_length, Operand(0), eq, &fallthrough); |
+ // Succeed on empty capture (including no capture). |
+ __ Cbz(capture_length, &fallthrough); |
// Check that there are enough characters left in the input. |
- if (read_backward) { |
- __ Add(w12, string_start_minus_one(), capture_length); |
- __ Cmp(current_input_offset(), w12); |
- BranchOrBacktrack(le, on_no_match); |
- } else { |
- __ Cmn(capture_length, current_input_offset()); |
- BranchOrBacktrack(gt, on_no_match); |
- } |
+ __ Cmn(capture_length, current_input_offset()); |
+ BranchOrBacktrack(gt, on_no_match); |
if (mode_ == LATIN1) { |
Label success; |
@@ -325,11 +322,6 @@ |
__ Add(current_position_address, |
input_end(), |
Operand(current_input_offset(), SXTW)); |
- if (read_backward) { |
- // Offset by length when matching backwards. |
- __ Sub(current_position_address, current_position_address, |
- Operand(capture_length, SXTW)); |
- } |
Label loop; |
__ Bind(&loop); |
@@ -369,10 +361,6 @@ |
// The current input offset should be <= 0, and fit in a W register. |
__ Check(le, kOffsetOutOfRange); |
} |
- if (read_backward) { |
- __ Sub(current_input_offset(), current_input_offset(), |
- Operand(capture_length, SXTW)); |
- } |
} else { |
DCHECK(mode_ == UC16); |
int argument_count = 4; |
@@ -395,9 +383,6 @@ |
__ Mov(w2, capture_length); |
// Address of current input position. |
__ Add(x1, input_end(), Operand(current_input_offset(), SXTW)); |
- if (read_backward) { |
- __ Sub(x1, x1, Operand(capture_length, SXTW)); |
- } |
// Isolate. |
__ Mov(x3, ExternalReference::isolate_address(isolate())); |
@@ -415,20 +400,16 @@ |
__ PopCPURegList(cached_registers); |
BranchOrBacktrack(eq, on_no_match); |
- // On success, advance position by length of capture. |
- if (read_backward) { |
- __ Sub(current_input_offset(), current_input_offset(), capture_length); |
- } else { |
- __ Add(current_input_offset(), current_input_offset(), capture_length); |
- } |
+ // On success, increment position by length of capture. |
+ __ Add(current_input_offset(), current_input_offset(), capture_length); |
} |
__ Bind(&fallthrough); |
} |
-void RegExpMacroAssemblerARM64::CheckNotBackReference(int start_reg, |
- bool read_backward, |
- Label* on_no_match) { |
+void RegExpMacroAssemblerARM64::CheckNotBackReference( |
+ int start_reg, |
+ Label* on_no_match) { |
Label fallthrough; |
Register capture_start_address = x12; |
@@ -445,21 +426,12 @@ |
__ Ldp(w11, w10, capture_location(start_reg, x10)); |
} |
__ Sub(capture_length, w11, w10); // Length to check. |
- |
- // 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. |
- __ CompareAndBranch(capture_length, Operand(0), eq, &fallthrough); |
+ // Succeed on empty capture (including no capture). |
+ __ Cbz(capture_length, &fallthrough); |
// Check that there are enough characters left in the input. |
- if (read_backward) { |
- __ Add(w12, string_start_minus_one(), capture_length); |
- __ Cmp(current_input_offset(), w12); |
- BranchOrBacktrack(le, on_no_match); |
- } else { |
- __ Cmn(capture_length, current_input_offset()); |
- BranchOrBacktrack(gt, on_no_match); |
- } |
+ __ Cmn(capture_length, current_input_offset()); |
+ BranchOrBacktrack(gt, on_no_match); |
// Compute pointers to match string and capture string |
__ Add(capture_start_address, input_end(), Operand(w10, SXTW)); |
@@ -469,11 +441,6 @@ |
__ Add(current_position_address, |
input_end(), |
Operand(current_input_offset(), SXTW)); |
- if (read_backward) { |
- // Offset by length when matching backwards. |
- __ Sub(current_position_address, current_position_address, |
- Operand(capture_length, SXTW)); |
- } |
Label loop; |
__ Bind(&loop); |
@@ -492,11 +459,6 @@ |
// Move current character position to position after match. |
__ Sub(current_input_offset().X(), current_position_address, input_end()); |
- if (read_backward) { |
- __ Sub(current_input_offset(), current_input_offset(), |
- Operand(capture_length, SXTW)); |
- } |
- |
if (masm_->emit_debug_code()) { |
__ Cmp(current_input_offset().X(), Operand(current_input_offset(), SXTW)); |
__ Ccmp(current_input_offset(), 0, NoFlag, eq); |
@@ -796,13 +758,14 @@ |
// The non-position value is used as a clearing value for the |
// capture registers, it corresponds to the position of the first character |
// minus one. |
- __ Sub(string_start_minus_one(), current_input_offset(), char_size()); |
- __ Sub(string_start_minus_one(), string_start_minus_one(), |
+ __ Sub(non_position_value(), current_input_offset(), char_size()); |
+ __ Sub(non_position_value(), non_position_value(), |
Operand(start_offset(), LSL, (mode_ == UC16) ? 1 : 0)); |
// We can store this value twice in an X register for initializing |
// on-stack registers later. |
- __ Orr(twice_non_position_value(), string_start_minus_one().X(), |
- Operand(string_start_minus_one().X(), LSL, kWRegSizeInBits)); |
+ __ Orr(twice_non_position_value(), |
+ non_position_value().X(), |
+ Operand(non_position_value().X(), LSL, kWRegSizeInBits)); |
// Initialize code pointer register. |
__ Mov(code_pointer(), Operand(masm_->CodeObject())); |
@@ -1118,14 +1081,11 @@ |
int characters) { |
// TODO(pielan): Make sure long strings are caught before this, and not |
// just asserted in debug mode. |
+ DCHECK(cp_offset >= -1); // ^ and \b can look behind one character. |
// Be sane! (And ensure that an int32_t can be used to index the string) |
DCHECK(cp_offset < (1<<30)); |
if (check_bounds) { |
- if (cp_offset >= 0) { |
- CheckPosition(cp_offset + characters - 1, on_end_of_input); |
- } else { |
- CheckPosition(cp_offset, on_end_of_input); |
- } |
+ CheckPosition(cp_offset + characters - 1, on_end_of_input); |
} |
LoadCurrentCharacterUnchecked(cp_offset, characters); |
} |
@@ -1250,7 +1210,7 @@ |
// If the first capture register is cached in a hardware register but not |
// aligned on a 64-bit one, we need to clear the first one specifically. |
if ((reg_from < kNumCachedRegisters) && ((reg_from % 2) != 0)) { |
- StoreRegister(reg_from, string_start_minus_one()); |
+ StoreRegister(reg_from, non_position_value()); |
num_registers--; |
reg_from++; |
} |
@@ -1264,7 +1224,7 @@ |
} |
if ((num_registers % 2) == 1) { |
- StoreRegister(reg_from, string_start_minus_one()); |
+ StoreRegister(reg_from, non_position_value()); |
num_registers--; |
reg_from++; |
} |
@@ -1341,14 +1301,10 @@ |
void RegExpMacroAssemblerARM64::CheckPosition(int cp_offset, |
Label* on_outside_input) { |
- if (cp_offset >= 0) { |
- CompareAndBranchOrBacktrack(current_input_offset(), |
- -cp_offset * char_size(), ge, on_outside_input); |
- } else { |
- __ Add(w12, current_input_offset(), Operand(cp_offset * char_size())); |
- __ Cmp(w12, string_start_minus_one()); |
- BranchOrBacktrack(le, on_outside_input); |
- } |
+ CompareAndBranchOrBacktrack(current_input_offset(), |
+ -cp_offset * char_size(), |
+ ge, |
+ on_outside_input); |
} |