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

Side by Side Diff: src/regexp/ia32/regexp-macro-assembler-ia32.cc

Issue 1451373003: Revert of Experimental support for RegExp lookbehind. (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: 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 unified diff | Download patch
« no previous file with comments | « src/regexp/ia32/regexp-macro-assembler-ia32.h ('k') | src/regexp/interpreter-irregexp.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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 35 matching lines...) Expand 10 before | Expand all | Expand 10 after
46 * - start index (character index of start) 46 * - start index (character index of start)
47 * - String* input_string (location of a handle containing the string) 47 * - String* input_string (location of a handle containing the string)
48 * --- frame alignment (if applicable) --- 48 * --- frame alignment (if applicable) ---
49 * - return address 49 * - return address
50 * ebp-> - old ebp 50 * ebp-> - old ebp
51 * - backup of caller esi 51 * - backup of caller esi
52 * - backup of caller edi 52 * - backup of caller edi
53 * - backup of caller ebx 53 * - backup of caller ebx
54 * - success counter (only for global regexps to count matches). 54 * - success counter (only for global regexps to count matches).
55 * - Offset of location before start of input (effectively character 55 * - Offset of location before start of input (effectively character
56 * string start - 1). Used to initialize capture registers to a 56 * position -1). Used to initialize capture registers to a non-position.
57 * non-position.
58 * - register 0 ebp[-4] (only positions must be stored in the first 57 * - register 0 ebp[-4] (only positions must be stored in the first
59 * - register 1 ebp[-8] num_saved_registers_ registers) 58 * - register 1 ebp[-8] num_saved_registers_ registers)
60 * - ... 59 * - ...
61 * 60 *
62 * The first num_saved_registers_ registers are initialized to point to 61 * The first num_saved_registers_ registers are initialized to point to
63 * "character -1" in the string (i.e., char_size() bytes before the first 62 * "character -1" in the string (i.e., char_size() bytes before the first
64 * character of the string). The remaining registers starts out as garbage. 63 * character of the string). The remaining registers starts out as garbage.
65 * 64 *
66 * The data up to the return address must be placed there by the calling 65 * The data up to the return address must be placed there by the calling
67 * code, by calling the code entry as cast to a function with the signature: 66 * code, by calling the code entry as cast to a function with the signature:
(...skipping 82 matching lines...) Expand 10 before | Expand all | Expand 10 after
150 } 149 }
151 150
152 151
153 void RegExpMacroAssemblerIA32::CheckCharacterGT(uc16 limit, Label* on_greater) { 152 void RegExpMacroAssemblerIA32::CheckCharacterGT(uc16 limit, Label* on_greater) {
154 __ cmp(current_character(), limit); 153 __ cmp(current_character(), limit);
155 BranchOrBacktrack(greater, on_greater); 154 BranchOrBacktrack(greater, on_greater);
156 } 155 }
157 156
158 157
159 void RegExpMacroAssemblerIA32::CheckAtStart(Label* on_at_start) { 158 void RegExpMacroAssemblerIA32::CheckAtStart(Label* on_at_start) {
160 __ lea(eax, Operand(edi, -char_size())); 159 Label not_at_start;
161 __ cmp(eax, Operand(ebp, kStringStartMinusOne)); 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, &not_at_start);
163 // If we did, are we still at the start of the input?
164 __ lea(eax, Operand(esi, edi, times_1, 0));
165 __ cmp(eax, Operand(ebp, kInputStart));
162 BranchOrBacktrack(equal, on_at_start); 166 BranchOrBacktrack(equal, on_at_start);
167 __ bind(&not_at_start);
163 } 168 }
164 169
165 170
166 void RegExpMacroAssemblerIA32::CheckNotAtStart(int cp_offset, 171 void RegExpMacroAssemblerIA32::CheckNotAtStart(Label* on_not_at_start) {
167 Label* on_not_at_start) { 172 // Did we start the match at the start of the string at all?
168 __ lea(eax, Operand(edi, -char_size() + cp_offset * char_size())); 173 __ cmp(Operand(ebp, kStartIndex), Immediate(0));
169 __ cmp(eax, Operand(ebp, kStringStartMinusOne)); 174 BranchOrBacktrack(not_equal, on_not_at_start);
175 // If we did, are we still at the start of the input?
176 __ lea(eax, Operand(esi, edi, times_1, 0));
177 __ cmp(eax, Operand(ebp, kInputStart));
170 BranchOrBacktrack(not_equal, on_not_at_start); 178 BranchOrBacktrack(not_equal, on_not_at_start);
171 } 179 }
172 180
173 181
174 void RegExpMacroAssemblerIA32::CheckCharacterLT(uc16 limit, Label* on_less) { 182 void RegExpMacroAssemblerIA32::CheckCharacterLT(uc16 limit, Label* on_less) {
175 __ cmp(current_character(), limit); 183 __ cmp(current_character(), limit);
176 BranchOrBacktrack(less, on_less); 184 BranchOrBacktrack(less, on_less);
177 } 185 }
178 186
179 187
180 void RegExpMacroAssemblerIA32::CheckGreedyLoop(Label* on_equal) { 188 void RegExpMacroAssemblerIA32::CheckGreedyLoop(Label* on_equal) {
181 Label fallthrough; 189 Label fallthrough;
182 __ cmp(edi, Operand(backtrack_stackpointer(), 0)); 190 __ cmp(edi, Operand(backtrack_stackpointer(), 0));
183 __ j(not_equal, &fallthrough); 191 __ j(not_equal, &fallthrough);
184 __ add(backtrack_stackpointer(), Immediate(kPointerSize)); // Pop. 192 __ add(backtrack_stackpointer(), Immediate(kPointerSize)); // Pop.
185 BranchOrBacktrack(no_condition, on_equal); 193 BranchOrBacktrack(no_condition, on_equal);
186 __ bind(&fallthrough); 194 __ bind(&fallthrough);
187 } 195 }
188 196
189 197
190 void RegExpMacroAssemblerIA32::CheckNotBackReferenceIgnoreCase( 198 void RegExpMacroAssemblerIA32::CheckNotBackReferenceIgnoreCase(
191 int start_reg, bool read_backward, Label* on_no_match) { 199 int start_reg,
200 Label* on_no_match) {
192 Label fallthrough; 201 Label fallthrough;
193 __ mov(edx, register_location(start_reg)); // Index of start of capture 202 __ mov(edx, register_location(start_reg)); // Index of start of capture
194 __ mov(ebx, register_location(start_reg + 1)); // Index of end of capture 203 __ mov(ebx, register_location(start_reg + 1)); // Index of end of capture
195 __ sub(ebx, edx); // Length of capture. 204 __ sub(ebx, edx); // Length of capture.
196 205
197 // At this point, the capture registers are either both set or both cleared. 206 // The length of a capture should not be negative. This can only happen
198 // If the capture length is zero, then the capture is either empty or cleared. 207 // if the end of the capture is unrecorded, or at a point earlier than
199 // Fall through in both cases. 208 // the start of the capture.
209 BranchOrBacktrack(less, on_no_match);
210
211 // If length is zero, either the capture is empty or it is completely
212 // uncaptured. In either case succeed immediately.
200 __ j(equal, &fallthrough); 213 __ j(equal, &fallthrough);
201 214
202 // Check that there are sufficient characters left in the input. 215 // Check that there are sufficient characters left in the input.
203 if (read_backward) { 216 __ mov(eax, edi);
204 __ mov(eax, Operand(ebp, kStringStartMinusOne)); 217 __ add(eax, ebx);
205 __ add(eax, ebx); 218 BranchOrBacktrack(greater, on_no_match);
206 __ cmp(edi, eax);
207 BranchOrBacktrack(less_equal, on_no_match);
208 } else {
209 __ mov(eax, edi);
210 __ add(eax, ebx);
211 BranchOrBacktrack(greater, on_no_match);
212 }
213 219
214 if (mode_ == LATIN1) { 220 if (mode_ == LATIN1) {
215 Label success; 221 Label success;
216 Label fail; 222 Label fail;
217 Label loop_increment; 223 Label loop_increment;
218 // Save register contents to make the registers available below. 224 // Save register contents to make the registers available below.
219 __ push(edi); 225 __ push(edi);
220 __ push(backtrack_stackpointer()); 226 __ push(backtrack_stackpointer());
221 // After this, the eax, ecx, and edi registers are available. 227 // After this, the eax, ecx, and edi registers are available.
222 228
223 __ add(edx, esi); // Start of capture 229 __ add(edx, esi); // Start of capture
224 __ add(edi, esi); // Start of text to match against capture. 230 __ add(edi, esi); // Start of text to match against capture.
225 if (read_backward) {
226 __ sub(edi, ebx); // Offset by length when matching backwards.
227 }
228 __ add(ebx, edi); // End of text to match against capture. 231 __ add(ebx, edi); // End of text to match against capture.
229 232
230 Label loop; 233 Label loop;
231 __ bind(&loop); 234 __ bind(&loop);
232 __ movzx_b(eax, Operand(edi, 0)); 235 __ movzx_b(eax, Operand(edi, 0));
233 __ cmpb_al(Operand(edx, 0)); 236 __ cmpb_al(Operand(edx, 0));
234 __ j(equal, &loop_increment); 237 __ j(equal, &loop_increment);
235 238
236 // Mismatch, try case-insensitive match (converting letters to lower-case). 239 // Mismatch, try case-insensitive match (converting letters to lower-case).
237 __ or_(eax, 0x20); // Convert match character to lower-case. 240 __ or_(eax, 0x20); // Convert match character to lower-case.
(...skipping 30 matching lines...) Expand all
268 __ pop(edi); 271 __ pop(edi);
269 BranchOrBacktrack(no_condition, on_no_match); 272 BranchOrBacktrack(no_condition, on_no_match);
270 273
271 __ bind(&success); 274 __ bind(&success);
272 // Restore original value before continuing. 275 // Restore original value before continuing.
273 __ pop(backtrack_stackpointer()); 276 __ pop(backtrack_stackpointer());
274 // Drop original value of character position. 277 // Drop original value of character position.
275 __ add(esp, Immediate(kPointerSize)); 278 __ add(esp, Immediate(kPointerSize));
276 // Compute new value of character position after the matched part. 279 // Compute new value of character position after the matched part.
277 __ sub(edi, esi); 280 __ sub(edi, esi);
278 if (read_backward) {
279 // Subtract match length if we matched backward.
280 __ add(edi, register_location(start_reg));
281 __ sub(edi, register_location(start_reg + 1));
282 }
283 } else { 281 } else {
284 DCHECK(mode_ == UC16); 282 DCHECK(mode_ == UC16);
285 // Save registers before calling C function. 283 // Save registers before calling C function.
286 __ push(esi); 284 __ push(esi);
287 __ push(edi); 285 __ push(edi);
288 __ push(backtrack_stackpointer()); 286 __ push(backtrack_stackpointer());
289 __ push(ebx); 287 __ push(ebx);
290 288
291 static const int argument_count = 4; 289 static const int argument_count = 4;
292 __ PrepareCallCFunction(argument_count, ecx); 290 __ PrepareCallCFunction(argument_count, ecx);
293 // Put arguments into allocated stack area, last argument highest on stack. 291 // Put arguments into allocated stack area, last argument highest on stack.
294 // Parameters are 292 // Parameters are
295 // Address byte_offset1 - Address captured substring's start. 293 // Address byte_offset1 - Address captured substring's start.
296 // Address byte_offset2 - Address of current character position. 294 // Address byte_offset2 - Address of current character position.
297 // size_t byte_length - length of capture in bytes(!) 295 // size_t byte_length - length of capture in bytes(!)
298 // Isolate* isolate 296 // Isolate* isolate
299 297
300 // Set isolate. 298 // Set isolate.
301 __ mov(Operand(esp, 3 * kPointerSize), 299 __ mov(Operand(esp, 3 * kPointerSize),
302 Immediate(ExternalReference::isolate_address(isolate()))); 300 Immediate(ExternalReference::isolate_address(isolate())));
303 // Set byte_length. 301 // Set byte_length.
304 __ mov(Operand(esp, 2 * kPointerSize), ebx); 302 __ mov(Operand(esp, 2 * kPointerSize), ebx);
305 // Set byte_offset2. 303 // Set byte_offset2.
306 // Found by adding negative string-end offset of current position (edi) 304 // Found by adding negative string-end offset of current position (edi)
307 // to end of string. 305 // to end of string.
308 __ add(edi, esi); 306 __ add(edi, esi);
309 if (read_backward) {
310 __ sub(edi, ebx); // Offset by length when matching backwards.
311 }
312 __ mov(Operand(esp, 1 * kPointerSize), edi); 307 __ mov(Operand(esp, 1 * kPointerSize), edi);
313 // Set byte_offset1. 308 // Set byte_offset1.
314 // Start of capture, where edx already holds string-end negative offset. 309 // Start of capture, where edx already holds string-end negative offset.
315 __ add(edx, esi); 310 __ add(edx, esi);
316 __ mov(Operand(esp, 0 * kPointerSize), edx); 311 __ mov(Operand(esp, 0 * kPointerSize), edx);
317 312
318 { 313 {
319 AllowExternalCallThatCantCauseGC scope(masm_); 314 AllowExternalCallThatCantCauseGC scope(masm_);
320 ExternalReference compare = 315 ExternalReference compare =
321 ExternalReference::re_case_insensitive_compare_uc16(isolate()); 316 ExternalReference::re_case_insensitive_compare_uc16(isolate());
322 __ CallCFunction(compare, argument_count); 317 __ CallCFunction(compare, argument_count);
323 } 318 }
324 // Pop original values before reacting on result value. 319 // Pop original values before reacting on result value.
325 __ pop(ebx); 320 __ pop(ebx);
326 __ pop(backtrack_stackpointer()); 321 __ pop(backtrack_stackpointer());
327 __ pop(edi); 322 __ pop(edi);
328 __ pop(esi); 323 __ pop(esi);
329 324
330 // Check if function returned non-zero for success or zero for failure. 325 // Check if function returned non-zero for success or zero for failure.
331 __ or_(eax, eax); 326 __ or_(eax, eax);
332 BranchOrBacktrack(zero, on_no_match); 327 BranchOrBacktrack(zero, on_no_match);
333 // On success, advance position by length of capture. 328 // On success, increment position by length of capture.
334 if (read_backward) { 329 __ add(edi, ebx);
335 __ sub(edi, ebx);
336 } else {
337 __ add(edi, ebx);
338 }
339 } 330 }
340 __ bind(&fallthrough); 331 __ bind(&fallthrough);
341 } 332 }
342 333
343 334
344 void RegExpMacroAssemblerIA32::CheckNotBackReference(int start_reg, 335 void RegExpMacroAssemblerIA32::CheckNotBackReference(
345 bool read_backward, 336 int start_reg,
346 Label* on_no_match) { 337 Label* on_no_match) {
347 Label fallthrough; 338 Label fallthrough;
348 Label success; 339 Label success;
349 Label fail; 340 Label fail;
350 341
351 // Find length of back-referenced capture. 342 // Find length of back-referenced capture.
352 __ mov(edx, register_location(start_reg)); 343 __ mov(edx, register_location(start_reg));
353 __ mov(eax, register_location(start_reg + 1)); 344 __ mov(eax, register_location(start_reg + 1));
354 __ sub(eax, edx); // Length to check. 345 __ sub(eax, edx); // Length to check.
355 346 // Fail on partial or illegal capture (start of capture after end of capture).
356 // At this point, the capture registers are either both set or both cleared. 347 BranchOrBacktrack(less, on_no_match);
357 // If the capture length is zero, then the capture is either empty or cleared. 348 // Succeed on empty capture (including no capture)
358 // Fall through in both cases.
359 __ j(equal, &fallthrough); 349 __ j(equal, &fallthrough);
360 350
361 // Check that there are sufficient characters left in the input. 351 // Check that there are sufficient characters left in the input.
362 if (read_backward) { 352 __ mov(ebx, edi);
363 __ mov(ebx, Operand(ebp, kStringStartMinusOne)); 353 __ add(ebx, eax);
364 __ add(ebx, eax); 354 BranchOrBacktrack(greater, on_no_match);
365 __ cmp(edi, ebx);
366 BranchOrBacktrack(less_equal, on_no_match);
367 } else {
368 __ mov(ebx, edi);
369 __ add(ebx, eax);
370 BranchOrBacktrack(greater, on_no_match);
371 }
372 355
373 // Save register to make it available below. 356 // Save register to make it available below.
374 __ push(backtrack_stackpointer()); 357 __ push(backtrack_stackpointer());
375 358
376 // Compute pointers to match string and capture string 359 // Compute pointers to match string and capture string
360 __ lea(ebx, Operand(esi, edi, times_1, 0)); // Start of match.
377 __ add(edx, esi); // Start of capture. 361 __ add(edx, esi); // Start of capture.
378 __ lea(ebx, Operand(esi, edi, times_1, 0)); // Start of match.
379 if (read_backward) {
380 __ sub(ebx, eax); // Offset by length when matching backwards.
381 }
382 __ lea(ecx, Operand(eax, ebx, times_1, 0)); // End of match 362 __ lea(ecx, Operand(eax, ebx, times_1, 0)); // End of match
383 363
384 Label loop; 364 Label loop;
385 __ bind(&loop); 365 __ bind(&loop);
386 if (mode_ == LATIN1) { 366 if (mode_ == LATIN1) {
387 __ movzx_b(eax, Operand(edx, 0)); 367 __ movzx_b(eax, Operand(edx, 0));
388 __ cmpb_al(Operand(ebx, 0)); 368 __ cmpb_al(Operand(ebx, 0));
389 } else { 369 } else {
390 DCHECK(mode_ == UC16); 370 DCHECK(mode_ == UC16);
391 __ movzx_w(eax, Operand(edx, 0)); 371 __ movzx_w(eax, Operand(edx, 0));
(...skipping 10 matching lines...) Expand all
402 382
403 __ bind(&fail); 383 __ bind(&fail);
404 // Restore backtrack stackpointer. 384 // Restore backtrack stackpointer.
405 __ pop(backtrack_stackpointer()); 385 __ pop(backtrack_stackpointer());
406 BranchOrBacktrack(no_condition, on_no_match); 386 BranchOrBacktrack(no_condition, on_no_match);
407 387
408 __ bind(&success); 388 __ bind(&success);
409 // Move current character position to position after match. 389 // Move current character position to position after match.
410 __ mov(edi, ecx); 390 __ mov(edi, ecx);
411 __ sub(edi, esi); 391 __ sub(edi, esi);
412 if (read_backward) {
413 // Subtract match length if we matched backward.
414 __ add(edi, register_location(start_reg));
415 __ sub(edi, register_location(start_reg + 1));
416 }
417 // Restore backtrack stackpointer. 392 // Restore backtrack stackpointer.
418 __ pop(backtrack_stackpointer()); 393 __ pop(backtrack_stackpointer());
419 394
420 __ bind(&fallthrough); 395 __ bind(&fallthrough);
421 } 396 }
422 397
423 398
424 void RegExpMacroAssemblerIA32::CheckNotCharacter(uint32_t c, 399 void RegExpMacroAssemblerIA32::CheckNotCharacter(uint32_t c,
425 Label* on_not_equal) { 400 Label* on_not_equal) {
426 __ cmp(current_character(), c); 401 __ cmp(current_character(), c);
(...skipping 225 matching lines...) Expand 10 before | Expand all | Expand 10 after
652 627
653 // Actually emit code to start a new stack frame. 628 // Actually emit code to start a new stack frame.
654 __ push(ebp); 629 __ push(ebp);
655 __ mov(ebp, esp); 630 __ mov(ebp, esp);
656 // Save callee-save registers. Order here should correspond to order of 631 // Save callee-save registers. Order here should correspond to order of
657 // kBackup_ebx etc. 632 // kBackup_ebx etc.
658 __ push(esi); 633 __ push(esi);
659 __ push(edi); 634 __ push(edi);
660 __ push(ebx); // Callee-save on MacOS. 635 __ push(ebx); // Callee-save on MacOS.
661 __ push(Immediate(0)); // Number of successful matches in a global regexp. 636 __ push(Immediate(0)); // Number of successful matches in a global regexp.
662 __ push(Immediate(0)); // Make room for "string start - 1" constant. 637 __ push(Immediate(0)); // Make room for "input start - 1" constant.
663 638
664 // Check if we have space on the stack for registers. 639 // Check if we have space on the stack for registers.
665 Label stack_limit_hit; 640 Label stack_limit_hit;
666 Label stack_ok; 641 Label stack_ok;
667 642
668 ExternalReference stack_limit = 643 ExternalReference stack_limit =
669 ExternalReference::address_of_stack_limit(isolate()); 644 ExternalReference::address_of_stack_limit(isolate());
670 __ mov(ecx, esp); 645 __ mov(ecx, esp);
671 __ sub(ecx, Operand::StaticVariable(stack_limit)); 646 __ sub(ecx, Operand::StaticVariable(stack_limit));
672 // Handle it if the stack pointer is already below the stack limit. 647 // Handle it if the stack pointer is already below the stack limit.
(...skipping 29 matching lines...) Expand all
702 // Set eax to address of char before start of the string. 677 // Set eax to address of char before start of the string.
703 // (effectively string position -1). 678 // (effectively string position -1).
704 __ neg(ebx); 679 __ neg(ebx);
705 if (mode_ == UC16) { 680 if (mode_ == UC16) {
706 __ lea(eax, Operand(edi, ebx, times_2, -char_size())); 681 __ lea(eax, Operand(edi, ebx, times_2, -char_size()));
707 } else { 682 } else {
708 __ lea(eax, Operand(edi, ebx, times_1, -char_size())); 683 __ lea(eax, Operand(edi, ebx, times_1, -char_size()));
709 } 684 }
710 // Store this value in a local variable, for use when clearing 685 // Store this value in a local variable, for use when clearing
711 // position registers. 686 // position registers.
712 __ mov(Operand(ebp, kStringStartMinusOne), eax); 687 __ mov(Operand(ebp, kInputStartMinusOne), eax);
713 688
714 #if V8_OS_WIN 689 #if V8_OS_WIN
715 // Ensure that we write to each stack page, in order. Skipping a page 690 // Ensure that we write to each stack page, in order. Skipping a page
716 // on Windows can cause segmentation faults. Assuming page size is 4k. 691 // on Windows can cause segmentation faults. Assuming page size is 4k.
717 const int kPageSize = 4096; 692 const int kPageSize = 4096;
718 const int kRegistersPerPage = kPageSize / kPointerSize; 693 const int kRegistersPerPage = kPageSize / kPointerSize;
719 for (int i = num_saved_registers_ + kRegistersPerPage - 1; 694 for (int i = num_saved_registers_ + kRegistersPerPage - 1;
720 i < num_registers_; 695 i < num_registers_;
721 i += kRegistersPerPage) { 696 i += kRegistersPerPage) {
722 __ mov(register_location(i), eax); // One write every page. 697 __ mov(register_location(i), eax); // One write every page.
(...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after
785 // Convert to index from start of string, not end. 760 // Convert to index from start of string, not end.
786 __ add(eax, ecx); 761 __ add(eax, ecx);
787 if (mode_ == UC16) { 762 if (mode_ == UC16) {
788 __ sar(eax, 1); // Convert byte index to character index. 763 __ sar(eax, 1); // Convert byte index to character index.
789 } 764 }
790 __ mov(Operand(ebx, i * kPointerSize), eax); 765 __ mov(Operand(ebx, i * kPointerSize), eax);
791 } 766 }
792 } 767 }
793 768
794 if (global()) { 769 if (global()) {
795 // Restart matching if the regular expression is flagged as global. 770 // Restart matching if the regular expression is flagged as global.
796 // Increment success counter. 771 // Increment success counter.
797 __ inc(Operand(ebp, kSuccessfulCaptures)); 772 __ inc(Operand(ebp, kSuccessfulCaptures));
798 // Capture results have been stored, so the number of remaining global 773 // Capture results have been stored, so the number of remaining global
799 // output registers is reduced by the number of stored captures. 774 // output registers is reduced by the number of stored captures.
800 __ mov(ecx, Operand(ebp, kNumOutputRegisters)); 775 __ mov(ecx, Operand(ebp, kNumOutputRegisters));
801 __ sub(ecx, Immediate(num_saved_registers_)); 776 __ sub(ecx, Immediate(num_saved_registers_));
802 // Check whether we have enough room for another set of capture results. 777 // Check whether we have enough room for another set of capture results.
803 __ cmp(ecx, Immediate(num_saved_registers_)); 778 __ cmp(ecx, Immediate(num_saved_registers_));
804 __ j(less, &exit_label_); 779 __ j(less, &exit_label_);
805 780
806 __ mov(Operand(ebp, kNumOutputRegisters), ecx); 781 __ mov(Operand(ebp, kNumOutputRegisters), ecx);
807 // Advance the location for output. 782 // Advance the location for output.
808 __ add(Operand(ebp, kRegisterOutput), 783 __ add(Operand(ebp, kRegisterOutput),
809 Immediate(num_saved_registers_ * kPointerSize)); 784 Immediate(num_saved_registers_ * kPointerSize));
810 785
811 // Prepare eax to initialize registers with its value in the next run. 786 // Prepare eax to initialize registers with its value in the next run.
812 __ mov(eax, Operand(ebp, kStringStartMinusOne)); 787 __ mov(eax, Operand(ebp, kInputStartMinusOne));
813 788
814 if (global_with_zero_length_check()) { 789 if (global_with_zero_length_check()) {
815 // Special case for zero-length matches. 790 // Special case for zero-length matches.
816 // edx: capture start index 791 // edx: capture start index
817 __ cmp(edi, edx); 792 __ cmp(edi, edx);
818 // Not a zero-length match, restart. 793 // Not a zero-length match, restart.
819 __ j(not_equal, &load_char_start_regexp); 794 __ j(not_equal, &load_char_start_regexp);
820 // edi (offset from the end) is zero if we already reached the end. 795 // edi (offset from the end) is zero if we already reached the end.
821 __ test(edi, edi); 796 __ test(edi, edi);
822 __ j(zero, &exit_label_, Label::kNear); 797 __ j(zero, &exit_label_, Label::kNear);
(...skipping 139 matching lines...) Expand 10 before | Expand all | Expand 10 after
962 RegExpMacroAssembler::IrregexpImplementation 937 RegExpMacroAssembler::IrregexpImplementation
963 RegExpMacroAssemblerIA32::Implementation() { 938 RegExpMacroAssemblerIA32::Implementation() {
964 return kIA32Implementation; 939 return kIA32Implementation;
965 } 940 }
966 941
967 942
968 void RegExpMacroAssemblerIA32::LoadCurrentCharacter(int cp_offset, 943 void RegExpMacroAssemblerIA32::LoadCurrentCharacter(int cp_offset,
969 Label* on_end_of_input, 944 Label* on_end_of_input,
970 bool check_bounds, 945 bool check_bounds,
971 int characters) { 946 int characters) {
947 DCHECK(cp_offset >= -1); // ^ and \b can look behind one character.
972 DCHECK(cp_offset < (1<<30)); // Be sane! (And ensure negation works) 948 DCHECK(cp_offset < (1<<30)); // Be sane! (And ensure negation works)
973 if (check_bounds) { 949 if (check_bounds) {
974 if (cp_offset >= 0) { 950 CheckPosition(cp_offset + characters - 1, on_end_of_input);
975 CheckPosition(cp_offset + characters - 1, on_end_of_input);
976 } else {
977 CheckPosition(cp_offset, on_end_of_input);
978 }
979 } 951 }
980 LoadCurrentCharacterUnchecked(cp_offset, characters); 952 LoadCurrentCharacterUnchecked(cp_offset, characters);
981 } 953 }
982 954
983 955
984 void RegExpMacroAssemblerIA32::PopCurrentPosition() { 956 void RegExpMacroAssemblerIA32::PopCurrentPosition() {
985 Pop(edi); 957 Pop(edi);
986 } 958 }
987 959
988 960
(...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after
1052 __ mov(register_location(reg), edi); 1024 __ mov(register_location(reg), edi);
1053 } else { 1025 } else {
1054 __ lea(eax, Operand(edi, cp_offset * char_size())); 1026 __ lea(eax, Operand(edi, cp_offset * char_size()));
1055 __ mov(register_location(reg), eax); 1027 __ mov(register_location(reg), eax);
1056 } 1028 }
1057 } 1029 }
1058 1030
1059 1031
1060 void RegExpMacroAssemblerIA32::ClearRegisters(int reg_from, int reg_to) { 1032 void RegExpMacroAssemblerIA32::ClearRegisters(int reg_from, int reg_to) {
1061 DCHECK(reg_from <= reg_to); 1033 DCHECK(reg_from <= reg_to);
1062 __ mov(eax, Operand(ebp, kStringStartMinusOne)); 1034 __ mov(eax, Operand(ebp, kInputStartMinusOne));
1063 for (int reg = reg_from; reg <= reg_to; reg++) { 1035 for (int reg = reg_from; reg <= reg_to; reg++) {
1064 __ mov(register_location(reg), eax); 1036 __ mov(register_location(reg), eax);
1065 } 1037 }
1066 } 1038 }
1067 1039
1068 1040
1069 void RegExpMacroAssemblerIA32::WriteStackPointerToRegister(int reg) { 1041 void RegExpMacroAssemblerIA32::WriteStackPointerToRegister(int reg) {
1070 __ mov(eax, backtrack_stackpointer()); 1042 __ mov(eax, backtrack_stackpointer());
1071 __ sub(eax, Operand(ebp, kStackHighEnd)); 1043 __ sub(eax, Operand(ebp, kStackHighEnd));
1072 __ mov(register_location(reg), eax); 1044 __ mov(register_location(reg), eax);
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after
1121 DCHECK(register_index < (1<<30)); 1093 DCHECK(register_index < (1<<30));
1122 if (num_registers_ <= register_index) { 1094 if (num_registers_ <= register_index) {
1123 num_registers_ = register_index + 1; 1095 num_registers_ = register_index + 1;
1124 } 1096 }
1125 return Operand(ebp, kRegisterZero - register_index * kPointerSize); 1097 return Operand(ebp, kRegisterZero - register_index * kPointerSize);
1126 } 1098 }
1127 1099
1128 1100
1129 void RegExpMacroAssemblerIA32::CheckPosition(int cp_offset, 1101 void RegExpMacroAssemblerIA32::CheckPosition(int cp_offset,
1130 Label* on_outside_input) { 1102 Label* on_outside_input) {
1131 if (cp_offset >= 0) { 1103 __ cmp(edi, -cp_offset * char_size());
1132 __ cmp(edi, -cp_offset * char_size()); 1104 BranchOrBacktrack(greater_equal, on_outside_input);
1133 BranchOrBacktrack(greater_equal, on_outside_input);
1134 } else {
1135 __ lea(eax, Operand(edi, cp_offset * char_size()));
1136 __ cmp(eax, Operand(ebp, kStringStartMinusOne));
1137 BranchOrBacktrack(less_equal, on_outside_input);
1138 }
1139 } 1105 }
1140 1106
1141 1107
1142 void RegExpMacroAssemblerIA32::BranchOrBacktrack(Condition condition, 1108 void RegExpMacroAssemblerIA32::BranchOrBacktrack(Condition condition,
1143 Label* to) { 1109 Label* to) {
1144 if (condition < 0) { // No condition 1110 if (condition < 0) { // No condition
1145 if (to == NULL) { 1111 if (to == NULL) {
1146 Backtrack(); 1112 Backtrack();
1147 return; 1113 return;
1148 } 1114 }
(...skipping 104 matching lines...) Expand 10 before | Expand all | Expand 10 after
1253 1219
1254 1220
1255 #undef __ 1221 #undef __
1256 1222
1257 #endif // V8_INTERPRETED_REGEXP 1223 #endif // V8_INTERPRETED_REGEXP
1258 1224
1259 } // namespace internal 1225 } // namespace internal
1260 } // namespace v8 1226 } // namespace v8
1261 1227
1262 #endif // V8_TARGET_ARCH_IA32 1228 #endif // V8_TARGET_ARCH_IA32
OLDNEW
« no previous file with comments | « src/regexp/ia32/regexp-macro-assembler-ia32.h ('k') | src/regexp/interpreter-irregexp.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698