OLD | NEW |
1 // Copyright 2012 the V8 project authors. All rights reserved. | 1 // Copyright 2012 the V8 project authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #if V8_TARGET_ARCH_IA32 | 5 #if V8_TARGET_ARCH_IA32 |
6 | 6 |
7 #include "src/regexp/ia32/regexp-macro-assembler-ia32.h" | 7 #include "src/regexp/ia32/regexp-macro-assembler-ia32.h" |
8 | 8 |
9 #include "src/log.h" | 9 #include "src/log.h" |
10 #include "src/macro-assembler.h" | 10 #include "src/macro-assembler.h" |
(...skipping 138 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
149 } | 149 } |
150 | 150 |
151 | 151 |
152 void RegExpMacroAssemblerIA32::CheckCharacterGT(uc16 limit, Label* on_greater) { | 152 void RegExpMacroAssemblerIA32::CheckCharacterGT(uc16 limit, Label* on_greater) { |
153 __ cmp(current_character(), limit); | 153 __ cmp(current_character(), limit); |
154 BranchOrBacktrack(greater, on_greater); | 154 BranchOrBacktrack(greater, on_greater); |
155 } | 155 } |
156 | 156 |
157 | 157 |
158 void RegExpMacroAssemblerIA32::CheckAtStart(Label* on_at_start) { | 158 void RegExpMacroAssemblerIA32::CheckAtStart(Label* on_at_start) { |
159 Label not_at_start; | |
160 // Did we start the match at the start of the string at all? | |
161 __ cmp(Operand(ebp, kStartIndex), Immediate(0)); | |
162 BranchOrBacktrack(not_equal, ¬_at_start); | |
163 // If we did, are we still at the start of the input? | |
164 __ lea(eax, Operand(esi, edi, times_1, 0)); | 159 __ lea(eax, Operand(esi, edi, times_1, 0)); |
| 160 for (int i = 0; i < char_size(); i++) { |
| 161 __ add(eax, Operand(ebp, kStartIndex)); |
| 162 } |
165 __ cmp(eax, Operand(ebp, kInputStart)); | 163 __ cmp(eax, Operand(ebp, kInputStart)); |
166 BranchOrBacktrack(equal, on_at_start); | 164 BranchOrBacktrack(equal, on_at_start); |
167 __ bind(¬_at_start); | |
168 } | 165 } |
169 | 166 |
170 | 167 |
171 void RegExpMacroAssemblerIA32::CheckNotAtStart(Label* on_not_at_start) { | 168 void RegExpMacroAssemblerIA32::CheckNotAtStart(int cp_offset, |
172 // Did we start the match at the start of the string at all? | 169 Label* on_not_at_start) { |
173 __ cmp(Operand(ebp, kStartIndex), Immediate(0)); | 170 __ lea(eax, Operand(esi, edi, times_1, cp_offset * char_size())); |
174 BranchOrBacktrack(not_equal, on_not_at_start); | 171 for (int i = 0; i < char_size(); i++) { |
175 // If we did, are we still at the start of the input? | 172 __ add(eax, Operand(ebp, kStartIndex)); |
176 __ lea(eax, Operand(esi, edi, times_1, 0)); | 173 } |
177 __ cmp(eax, Operand(ebp, kInputStart)); | 174 __ cmp(eax, Operand(ebp, kInputStart)); |
178 BranchOrBacktrack(not_equal, on_not_at_start); | 175 BranchOrBacktrack(not_equal, on_not_at_start); |
179 } | 176 } |
180 | 177 |
181 | 178 |
182 void RegExpMacroAssemblerIA32::CheckCharacterLT(uc16 limit, Label* on_less) { | 179 void RegExpMacroAssemblerIA32::CheckCharacterLT(uc16 limit, Label* on_less) { |
183 __ cmp(current_character(), limit); | 180 __ cmp(current_character(), limit); |
184 BranchOrBacktrack(less, on_less); | 181 BranchOrBacktrack(less, on_less); |
185 } | 182 } |
186 | 183 |
187 | 184 |
188 void RegExpMacroAssemblerIA32::CheckGreedyLoop(Label* on_equal) { | 185 void RegExpMacroAssemblerIA32::CheckGreedyLoop(Label* on_equal) { |
189 Label fallthrough; | 186 Label fallthrough; |
190 __ cmp(edi, Operand(backtrack_stackpointer(), 0)); | 187 __ cmp(edi, Operand(backtrack_stackpointer(), 0)); |
191 __ j(not_equal, &fallthrough); | 188 __ j(not_equal, &fallthrough); |
192 __ add(backtrack_stackpointer(), Immediate(kPointerSize)); // Pop. | 189 __ add(backtrack_stackpointer(), Immediate(kPointerSize)); // Pop. |
193 BranchOrBacktrack(no_condition, on_equal); | 190 BranchOrBacktrack(no_condition, on_equal); |
194 __ bind(&fallthrough); | 191 __ bind(&fallthrough); |
195 } | 192 } |
196 | 193 |
197 | 194 |
198 void RegExpMacroAssemblerIA32::CheckNotBackReferenceIgnoreCase( | 195 void RegExpMacroAssemblerIA32::CheckNotBackReferenceIgnoreCase( |
199 int start_reg, | 196 int start_reg, |
| 197 bool read_backward, |
200 Label* on_no_match) { | 198 Label* on_no_match) { |
201 Label fallthrough; | 199 Label fallthrough; |
202 __ mov(edx, register_location(start_reg)); // Index of start of capture | 200 __ mov(edx, register_location(start_reg)); // Index of start of capture |
203 __ mov(ebx, register_location(start_reg + 1)); // Index of end of capture | 201 __ mov(ebx, register_location(start_reg + 1)); // Index of end of capture |
204 __ sub(ebx, edx); // Length of capture. | 202 __ sub(ebx, edx); // Length of capture. |
205 | 203 |
206 // The length of a capture should not be negative. This can only happen | 204 // The length of the capture can only be negative if the end of the |
207 // if the end of the capture is unrecorded, or at a point earlier than | 205 // capture is not yet recorded. If the length is zero, the capture is |
208 // the start of the capture. | 206 // either empty or uncaptured. In either of those cases, succeed. |
209 BranchOrBacktrack(less, on_no_match); | 207 __ j(less_equal, &fallthrough); |
210 | |
211 // If length is zero, either the capture is empty or it is completely | |
212 // uncaptured. In either case succeed immediately. | |
213 __ j(equal, &fallthrough); | |
214 | 208 |
215 // Check that there are sufficient characters left in the input. | 209 // Check that there are sufficient characters left in the input. |
216 __ mov(eax, edi); | 210 if (read_backward) { |
217 __ add(eax, ebx); | 211 __ lea(eax, Operand(esi, edi, times_1, 0)); |
218 BranchOrBacktrack(greater, on_no_match); | 212 __ sub(eax, ebx); |
| 213 for (int i = 0; i < char_size(); i++) { |
| 214 __ add(eax, Operand(ebp, kStartIndex)); |
| 215 } |
| 216 __ cmp(eax, Operand(ebp, kInputStart)); |
| 217 BranchOrBacktrack(less, on_no_match); |
| 218 } else { |
| 219 __ mov(eax, edi); |
| 220 __ add(eax, ebx); |
| 221 BranchOrBacktrack(greater, on_no_match); |
| 222 } |
219 | 223 |
220 if (mode_ == LATIN1) { | 224 if (mode_ == LATIN1) { |
221 Label success; | 225 Label success; |
222 Label fail; | 226 Label fail; |
223 Label loop_increment; | 227 Label loop_increment; |
224 // Save register contents to make the registers available below. | 228 // Save register contents to make the registers available below. |
225 __ push(edi); | 229 __ push(edi); |
226 __ push(backtrack_stackpointer()); | 230 __ push(backtrack_stackpointer()); |
227 // After this, the eax, ecx, and edi registers are available. | 231 // After this, the eax, ecx, and edi registers are available. |
228 | 232 |
229 __ add(edx, esi); // Start of capture | 233 __ add(edx, esi); // Start of capture |
230 __ add(edi, esi); // Start of text to match against capture. | 234 __ add(edi, esi); // Start of text to match against capture. |
| 235 if (read_backward) { |
| 236 __ sub(edi, ebx); // Offset by length when matching backwards. |
| 237 } |
231 __ add(ebx, edi); // End of text to match against capture. | 238 __ add(ebx, edi); // End of text to match against capture. |
232 | 239 |
233 Label loop; | 240 Label loop; |
234 __ bind(&loop); | 241 __ bind(&loop); |
235 __ movzx_b(eax, Operand(edi, 0)); | 242 __ movzx_b(eax, Operand(edi, 0)); |
236 __ cmpb_al(Operand(edx, 0)); | 243 __ cmpb_al(Operand(edx, 0)); |
237 __ j(equal, &loop_increment); | 244 __ j(equal, &loop_increment); |
238 | 245 |
239 // Mismatch, try case-insensitive match (converting letters to lower-case). | 246 // Mismatch, try case-insensitive match (converting letters to lower-case). |
240 __ or_(eax, 0x20); // Convert match character to lower-case. | 247 __ or_(eax, 0x20); // Convert match character to lower-case. |
(...skipping 30 matching lines...) Expand all Loading... |
271 __ pop(edi); | 278 __ pop(edi); |
272 BranchOrBacktrack(no_condition, on_no_match); | 279 BranchOrBacktrack(no_condition, on_no_match); |
273 | 280 |
274 __ bind(&success); | 281 __ bind(&success); |
275 // Restore original value before continuing. | 282 // Restore original value before continuing. |
276 __ pop(backtrack_stackpointer()); | 283 __ pop(backtrack_stackpointer()); |
277 // Drop original value of character position. | 284 // Drop original value of character position. |
278 __ add(esp, Immediate(kPointerSize)); | 285 __ add(esp, Immediate(kPointerSize)); |
279 // Compute new value of character position after the matched part. | 286 // Compute new value of character position after the matched part. |
280 __ sub(edi, esi); | 287 __ sub(edi, esi); |
| 288 if (read_backward) { |
| 289 // Subtract match length if we matched backward. |
| 290 __ add(edi, register_location(start_reg)); |
| 291 __ sub(edi, register_location(start_reg + 1)); |
| 292 } |
281 } else { | 293 } else { |
282 DCHECK(mode_ == UC16); | 294 DCHECK(mode_ == UC16); |
283 // Save registers before calling C function. | 295 // Save registers before calling C function. |
284 __ push(esi); | 296 __ push(esi); |
285 __ push(edi); | 297 __ push(edi); |
286 __ push(backtrack_stackpointer()); | 298 __ push(backtrack_stackpointer()); |
287 __ push(ebx); | 299 __ push(ebx); |
288 | 300 |
289 static const int argument_count = 4; | 301 static const int argument_count = 4; |
290 __ PrepareCallCFunction(argument_count, ecx); | 302 __ PrepareCallCFunction(argument_count, ecx); |
291 // Put arguments into allocated stack area, last argument highest on stack. | 303 // Put arguments into allocated stack area, last argument highest on stack. |
292 // Parameters are | 304 // Parameters are |
293 // Address byte_offset1 - Address captured substring's start. | 305 // Address byte_offset1 - Address captured substring's start. |
294 // Address byte_offset2 - Address of current character position. | 306 // Address byte_offset2 - Address of current character position. |
295 // size_t byte_length - length of capture in bytes(!) | 307 // size_t byte_length - length of capture in bytes(!) |
296 // Isolate* isolate | 308 // Isolate* isolate |
297 | 309 |
298 // Set isolate. | 310 // Set isolate. |
299 __ mov(Operand(esp, 3 * kPointerSize), | 311 __ mov(Operand(esp, 3 * kPointerSize), |
300 Immediate(ExternalReference::isolate_address(isolate()))); | 312 Immediate(ExternalReference::isolate_address(isolate()))); |
301 // Set byte_length. | 313 // Set byte_length. |
302 __ mov(Operand(esp, 2 * kPointerSize), ebx); | 314 __ mov(Operand(esp, 2 * kPointerSize), ebx); |
303 // Set byte_offset2. | 315 // Set byte_offset2. |
304 // Found by adding negative string-end offset of current position (edi) | 316 // Found by adding negative string-end offset of current position (edi) |
305 // to end of string. | 317 // to end of string. |
306 __ add(edi, esi); | 318 __ add(edi, esi); |
| 319 if (read_backward) { |
| 320 __ sub(edi, ebx); // Offset by length when matching backwards. |
| 321 } |
307 __ mov(Operand(esp, 1 * kPointerSize), edi); | 322 __ mov(Operand(esp, 1 * kPointerSize), edi); |
308 // Set byte_offset1. | 323 // Set byte_offset1. |
309 // Start of capture, where edx already holds string-end negative offset. | 324 // Start of capture, where edx already holds string-end negative offset. |
310 __ add(edx, esi); | 325 __ add(edx, esi); |
311 __ mov(Operand(esp, 0 * kPointerSize), edx); | 326 __ mov(Operand(esp, 0 * kPointerSize), edx); |
312 | 327 |
313 { | 328 { |
314 AllowExternalCallThatCantCauseGC scope(masm_); | 329 AllowExternalCallThatCantCauseGC scope(masm_); |
315 ExternalReference compare = | 330 ExternalReference compare = |
316 ExternalReference::re_case_insensitive_compare_uc16(isolate()); | 331 ExternalReference::re_case_insensitive_compare_uc16(isolate()); |
317 __ CallCFunction(compare, argument_count); | 332 __ CallCFunction(compare, argument_count); |
318 } | 333 } |
319 // Pop original values before reacting on result value. | 334 // Pop original values before reacting on result value. |
320 __ pop(ebx); | 335 __ pop(ebx); |
321 __ pop(backtrack_stackpointer()); | 336 __ pop(backtrack_stackpointer()); |
322 __ pop(edi); | 337 __ pop(edi); |
323 __ pop(esi); | 338 __ pop(esi); |
324 | 339 |
325 // Check if function returned non-zero for success or zero for failure. | 340 // Check if function returned non-zero for success or zero for failure. |
326 __ or_(eax, eax); | 341 __ or_(eax, eax); |
327 BranchOrBacktrack(zero, on_no_match); | 342 BranchOrBacktrack(zero, on_no_match); |
328 // On success, increment position by length of capture. | 343 // On success, advance position by length of capture. |
329 __ add(edi, ebx); | 344 if (read_backward) { |
| 345 __ sub(edi, ebx); |
| 346 } else { |
| 347 __ add(edi, ebx); |
| 348 } |
330 } | 349 } |
331 __ bind(&fallthrough); | 350 __ bind(&fallthrough); |
332 } | 351 } |
333 | 352 |
334 | 353 |
335 void RegExpMacroAssemblerIA32::CheckNotBackReference( | 354 void RegExpMacroAssemblerIA32::CheckNotBackReference( |
336 int start_reg, | 355 int start_reg, |
| 356 bool read_backward, |
337 Label* on_no_match) { | 357 Label* on_no_match) { |
338 Label fallthrough; | 358 Label fallthrough; |
339 Label success; | 359 Label success; |
340 Label fail; | 360 Label fail; |
341 | 361 |
342 // Find length of back-referenced capture. | 362 // Find length of back-referenced capture. |
343 __ mov(edx, register_location(start_reg)); | 363 __ mov(edx, register_location(start_reg)); |
344 __ mov(eax, register_location(start_reg + 1)); | 364 __ mov(eax, register_location(start_reg + 1)); |
345 __ sub(eax, edx); // Length to check. | 365 __ sub(eax, edx); // Length to check. |
346 // Fail on partial or illegal capture (start of capture after end of capture). | 366 // The length of the capture can only be negative if the end of the |
347 BranchOrBacktrack(less, on_no_match); | 367 // capture is not yet recorded. If the length is zero, the capture is |
348 // Succeed on empty capture (including no capture) | 368 // either empty or uncaptured. In either of those cases, succeed. |
349 __ j(equal, &fallthrough); | 369 __ j(less_equal, &fallthrough); |
350 | 370 |
351 // Check that there are sufficient characters left in the input. | 371 // Check that there are sufficient characters left in the input. |
352 __ mov(ebx, edi); | 372 if (read_backward) { |
353 __ add(ebx, eax); | 373 __ lea(ebx, Operand(esi, edi, times_1, 0)); |
354 BranchOrBacktrack(greater, on_no_match); | 374 __ sub(ebx, eax); |
| 375 for (int i = 0; i < char_size(); i++) { |
| 376 __ add(ebx, Operand(ebp, kStartIndex)); |
| 377 } |
| 378 __ cmp(ebx, Operand(ebp, kInputStart)); |
| 379 BranchOrBacktrack(less, on_no_match); |
| 380 } else { |
| 381 __ mov(ebx, edi); |
| 382 __ add(ebx, eax); |
| 383 BranchOrBacktrack(greater, on_no_match); |
| 384 } |
355 | 385 |
356 // Save register to make it available below. | 386 // Save register to make it available below. |
357 __ push(backtrack_stackpointer()); | 387 __ push(backtrack_stackpointer()); |
358 | 388 |
359 // Compute pointers to match string and capture string | 389 // Compute pointers to match string and capture string |
| 390 __ add(edx, esi); // Start of capture. |
360 __ lea(ebx, Operand(esi, edi, times_1, 0)); // Start of match. | 391 __ lea(ebx, Operand(esi, edi, times_1, 0)); // Start of match. |
361 __ add(edx, esi); // Start of capture. | 392 if (read_backward) { |
| 393 __ sub(ebx, eax); // Offset by length when matching backwards. |
| 394 } |
362 __ lea(ecx, Operand(eax, ebx, times_1, 0)); // End of match | 395 __ lea(ecx, Operand(eax, ebx, times_1, 0)); // End of match |
363 | 396 |
364 Label loop; | 397 Label loop; |
365 __ bind(&loop); | 398 __ bind(&loop); |
366 if (mode_ == LATIN1) { | 399 if (mode_ == LATIN1) { |
367 __ movzx_b(eax, Operand(edx, 0)); | 400 __ movzx_b(eax, Operand(edx, 0)); |
368 __ cmpb_al(Operand(ebx, 0)); | 401 __ cmpb_al(Operand(ebx, 0)); |
369 } else { | 402 } else { |
370 DCHECK(mode_ == UC16); | 403 DCHECK(mode_ == UC16); |
371 __ movzx_w(eax, Operand(edx, 0)); | 404 __ movzx_w(eax, Operand(edx, 0)); |
(...skipping 10 matching lines...) Expand all Loading... |
382 | 415 |
383 __ bind(&fail); | 416 __ bind(&fail); |
384 // Restore backtrack stackpointer. | 417 // Restore backtrack stackpointer. |
385 __ pop(backtrack_stackpointer()); | 418 __ pop(backtrack_stackpointer()); |
386 BranchOrBacktrack(no_condition, on_no_match); | 419 BranchOrBacktrack(no_condition, on_no_match); |
387 | 420 |
388 __ bind(&success); | 421 __ bind(&success); |
389 // Move current character position to position after match. | 422 // Move current character position to position after match. |
390 __ mov(edi, ecx); | 423 __ mov(edi, ecx); |
391 __ sub(edi, esi); | 424 __ sub(edi, esi); |
| 425 if (read_backward) { |
| 426 // Subtract match length if we matched backward. |
| 427 __ add(edi, register_location(start_reg)); |
| 428 __ sub(edi, register_location(start_reg + 1)); |
| 429 } |
392 // Restore backtrack stackpointer. | 430 // Restore backtrack stackpointer. |
393 __ pop(backtrack_stackpointer()); | 431 __ pop(backtrack_stackpointer()); |
394 | 432 |
395 __ bind(&fallthrough); | 433 __ bind(&fallthrough); |
396 } | 434 } |
397 | 435 |
398 | 436 |
399 void RegExpMacroAssemblerIA32::CheckNotCharacter(uint32_t c, | 437 void RegExpMacroAssemblerIA32::CheckNotCharacter(uint32_t c, |
400 Label* on_not_equal) { | 438 Label* on_not_equal) { |
401 __ cmp(current_character(), c); | 439 __ cmp(current_character(), c); |
(...skipping 358 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
760 // Convert to index from start of string, not end. | 798 // Convert to index from start of string, not end. |
761 __ add(eax, ecx); | 799 __ add(eax, ecx); |
762 if (mode_ == UC16) { | 800 if (mode_ == UC16) { |
763 __ sar(eax, 1); // Convert byte index to character index. | 801 __ sar(eax, 1); // Convert byte index to character index. |
764 } | 802 } |
765 __ mov(Operand(ebx, i * kPointerSize), eax); | 803 __ mov(Operand(ebx, i * kPointerSize), eax); |
766 } | 804 } |
767 } | 805 } |
768 | 806 |
769 if (global()) { | 807 if (global()) { |
770 // Restart matching if the regular expression is flagged as global. | 808 // Restart matching if the regular expression is flagged as global. |
771 // Increment success counter. | 809 // Increment success counter. |
772 __ inc(Operand(ebp, kSuccessfulCaptures)); | 810 __ inc(Operand(ebp, kSuccessfulCaptures)); |
773 // Capture results have been stored, so the number of remaining global | 811 // Capture results have been stored, so the number of remaining global |
774 // output registers is reduced by the number of stored captures. | 812 // output registers is reduced by the number of stored captures. |
775 __ mov(ecx, Operand(ebp, kNumOutputRegisters)); | 813 __ mov(ecx, Operand(ebp, kNumOutputRegisters)); |
776 __ sub(ecx, Immediate(num_saved_registers_)); | 814 __ sub(ecx, Immediate(num_saved_registers_)); |
777 // Check whether we have enough room for another set of capture results. | 815 // Check whether we have enough room for another set of capture results. |
778 __ cmp(ecx, Immediate(num_saved_registers_)); | 816 __ cmp(ecx, Immediate(num_saved_registers_)); |
779 __ j(less, &exit_label_); | 817 __ j(less, &exit_label_); |
780 | 818 |
(...skipping 156 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
937 RegExpMacroAssembler::IrregexpImplementation | 975 RegExpMacroAssembler::IrregexpImplementation |
938 RegExpMacroAssemblerIA32::Implementation() { | 976 RegExpMacroAssemblerIA32::Implementation() { |
939 return kIA32Implementation; | 977 return kIA32Implementation; |
940 } | 978 } |
941 | 979 |
942 | 980 |
943 void RegExpMacroAssemblerIA32::LoadCurrentCharacter(int cp_offset, | 981 void RegExpMacroAssemblerIA32::LoadCurrentCharacter(int cp_offset, |
944 Label* on_end_of_input, | 982 Label* on_end_of_input, |
945 bool check_bounds, | 983 bool check_bounds, |
946 int characters) { | 984 int characters) { |
947 DCHECK(cp_offset >= -1); // ^ and \b can look behind one character. | |
948 DCHECK(cp_offset < (1<<30)); // Be sane! (And ensure negation works) | 985 DCHECK(cp_offset < (1<<30)); // Be sane! (And ensure negation works) |
949 if (check_bounds) { | 986 if (check_bounds) { |
950 CheckPosition(cp_offset + characters - 1, on_end_of_input); | 987 if (cp_offset >= 0) { |
| 988 CheckPosition(cp_offset + characters - 1, on_end_of_input); |
| 989 } else { |
| 990 CheckPosition(cp_offset, on_end_of_input); |
| 991 } |
951 } | 992 } |
952 LoadCurrentCharacterUnchecked(cp_offset, characters); | 993 LoadCurrentCharacterUnchecked(cp_offset, characters); |
953 } | 994 } |
954 | 995 |
955 | 996 |
956 void RegExpMacroAssemblerIA32::PopCurrentPosition() { | 997 void RegExpMacroAssemblerIA32::PopCurrentPosition() { |
957 Pop(edi); | 998 Pop(edi); |
958 } | 999 } |
959 | 1000 |
960 | 1001 |
(...skipping 132 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1093 DCHECK(register_index < (1<<30)); | 1134 DCHECK(register_index < (1<<30)); |
1094 if (num_registers_ <= register_index) { | 1135 if (num_registers_ <= register_index) { |
1095 num_registers_ = register_index + 1; | 1136 num_registers_ = register_index + 1; |
1096 } | 1137 } |
1097 return Operand(ebp, kRegisterZero - register_index * kPointerSize); | 1138 return Operand(ebp, kRegisterZero - register_index * kPointerSize); |
1098 } | 1139 } |
1099 | 1140 |
1100 | 1141 |
1101 void RegExpMacroAssemblerIA32::CheckPosition(int cp_offset, | 1142 void RegExpMacroAssemblerIA32::CheckPosition(int cp_offset, |
1102 Label* on_outside_input) { | 1143 Label* on_outside_input) { |
1103 __ cmp(edi, -cp_offset * char_size()); | 1144 if (cp_offset >= 0) { |
1104 BranchOrBacktrack(greater_equal, on_outside_input); | 1145 __ cmp(edi, -cp_offset * char_size()); |
| 1146 BranchOrBacktrack(greater_equal, on_outside_input); |
| 1147 } else { |
| 1148 __ lea(eax, Operand(esi, edi, times_1, cp_offset * char_size())); |
| 1149 for (int i = 0; i < char_size(); i++) { |
| 1150 __ add(eax, Operand(ebp, kStartIndex)); |
| 1151 } |
| 1152 __ cmp(eax, Operand(ebp, kInputStart)); |
| 1153 BranchOrBacktrack(less, on_outside_input); |
| 1154 } |
1105 } | 1155 } |
1106 | 1156 |
1107 | 1157 |
1108 void RegExpMacroAssemblerIA32::BranchOrBacktrack(Condition condition, | 1158 void RegExpMacroAssemblerIA32::BranchOrBacktrack(Condition condition, |
1109 Label* to) { | 1159 Label* to) { |
1110 if (condition < 0) { // No condition | 1160 if (condition < 0) { // No condition |
1111 if (to == NULL) { | 1161 if (to == NULL) { |
1112 Backtrack(); | 1162 Backtrack(); |
1113 return; | 1163 return; |
1114 } | 1164 } |
(...skipping 104 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1219 | 1269 |
1220 | 1270 |
1221 #undef __ | 1271 #undef __ |
1222 | 1272 |
1223 #endif // V8_INTERPRETED_REGEXP | 1273 #endif // V8_INTERPRETED_REGEXP |
1224 | 1274 |
1225 } // namespace internal | 1275 } // namespace internal |
1226 } // namespace v8 | 1276 } // namespace v8 |
1227 | 1277 |
1228 #endif // V8_TARGET_ARCH_IA32 | 1278 #endif // V8_TARGET_ARCH_IA32 |
OLD | NEW |