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

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

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