OLD | NEW |
1 // Copyright 2012 the V8 project authors. All rights reserved. | 1 // Copyright 2011 the V8 project authors. All rights reserved. |
2 // Redistribution and use in source and binary forms, with or without | 2 // Redistribution and use in source and binary forms, with or without |
3 // modification, are permitted provided that the following conditions are | 3 // modification, are permitted provided that the following conditions are |
4 // met: | 4 // met: |
5 // | 5 // |
6 // * Redistributions of source code must retain the above copyright | 6 // * Redistributions of source code must retain the above copyright |
7 // notice, this list of conditions and the following disclaimer. | 7 // notice, this list of conditions and the following disclaimer. |
8 // * Redistributions in binary form must reproduce the above | 8 // * Redistributions in binary form must reproduce the above |
9 // copyright notice, this list of conditions and the following | 9 // copyright notice, this list of conditions and the following |
10 // disclaimer in the documentation and/or other materials provided | 10 // disclaimer in the documentation and/or other materials provided |
11 // with the distribution. | 11 // with the distribution. |
(...skipping 268 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
280 } | 280 } |
281 } | 281 } |
282 BranchOrBacktrack(not_equal, on_failure); | 282 BranchOrBacktrack(not_equal, on_failure); |
283 } | 283 } |
284 } | 284 } |
285 | 285 |
286 | 286 |
287 void RegExpMacroAssemblerIA32::CheckGreedyLoop(Label* on_equal) { | 287 void RegExpMacroAssemblerIA32::CheckGreedyLoop(Label* on_equal) { |
288 Label fallthrough; | 288 Label fallthrough; |
289 __ cmp(edi, Operand(backtrack_stackpointer(), 0)); | 289 __ cmp(edi, Operand(backtrack_stackpointer(), 0)); |
290 __ j(not_equal, &fallthrough, Label::kNear); | 290 __ j(not_equal, &fallthrough); |
291 __ add(backtrack_stackpointer(), Immediate(kPointerSize)); // Pop. | 291 __ add(backtrack_stackpointer(), Immediate(kPointerSize)); // Pop. |
292 BranchOrBacktrack(no_condition, on_equal); | 292 BranchOrBacktrack(no_condition, on_equal); |
293 __ bind(&fallthrough); | 293 __ bind(&fallthrough); |
294 } | 294 } |
295 | 295 |
296 | 296 |
297 void RegExpMacroAssemblerIA32::CheckNotBackReferenceIgnoreCase( | 297 void RegExpMacroAssemblerIA32::CheckNotBackReferenceIgnoreCase( |
298 int start_reg, | 298 int start_reg, |
299 Label* on_no_match) { | 299 Label* on_no_match) { |
300 Label fallthrough; | 300 Label fallthrough; |
(...skipping 20 matching lines...) Expand all Loading... |
321 // After this, the eax, ecx, and edi registers are available. | 321 // After this, the eax, ecx, and edi registers are available. |
322 | 322 |
323 __ add(edx, esi); // Start of capture | 323 __ add(edx, esi); // Start of capture |
324 __ add(edi, esi); // Start of text to match against capture. | 324 __ add(edi, esi); // Start of text to match against capture. |
325 __ add(ebx, edi); // End of text to match against capture. | 325 __ add(ebx, edi); // End of text to match against capture. |
326 | 326 |
327 Label loop; | 327 Label loop; |
328 __ bind(&loop); | 328 __ bind(&loop); |
329 __ movzx_b(eax, Operand(edi, 0)); | 329 __ movzx_b(eax, Operand(edi, 0)); |
330 __ cmpb_al(Operand(edx, 0)); | 330 __ cmpb_al(Operand(edx, 0)); |
331 __ j(equal, &loop_increment, Label::kNear); | 331 __ j(equal, &loop_increment); |
332 | 332 |
333 // Mismatch, try case-insensitive match (converting letters to lower-case). | 333 // Mismatch, try case-insensitive match (converting letters to lower-case). |
334 __ or_(eax, 0x20); // Convert match character to lower-case. | 334 __ or_(eax, 0x20); // Convert match character to lower-case. |
335 __ lea(ecx, Operand(eax, -'a')); | 335 __ lea(ecx, Operand(eax, -'a')); |
336 __ cmp(ecx, static_cast<int32_t>('z' - 'a')); // Is eax a lowercase letter? | 336 __ cmp(ecx, static_cast<int32_t>('z' - 'a')); // Is eax a lowercase letter? |
337 __ j(above, &fail, Label::kNear); | 337 __ j(above, &fail); |
338 // Also convert capture character. | 338 // Also convert capture character. |
339 __ movzx_b(ecx, Operand(edx, 0)); | 339 __ movzx_b(ecx, Operand(edx, 0)); |
340 __ or_(ecx, 0x20); | 340 __ or_(ecx, 0x20); |
341 | 341 |
342 __ cmp(eax, ecx); | 342 __ cmp(eax, ecx); |
343 __ j(not_equal, &fail, Label::kNear); | 343 __ j(not_equal, &fail); |
344 | 344 |
345 __ bind(&loop_increment); | 345 __ bind(&loop_increment); |
346 // Increment pointers into match and capture strings. | 346 // Increment pointers into match and capture strings. |
347 __ add(edx, Immediate(1)); | 347 __ add(edx, Immediate(1)); |
348 __ add(edi, Immediate(1)); | 348 __ add(edi, Immediate(1)); |
349 // Compare to end of match, and loop if not done. | 349 // Compare to end of match, and loop if not done. |
350 __ cmp(edi, ebx); | 350 __ cmp(edi, ebx); |
351 __ j(below, &loop); | 351 __ j(below, &loop); |
352 __ jmp(&success, Label::kNear); | 352 __ jmp(&success); |
353 | 353 |
354 __ bind(&fail); | 354 __ bind(&fail); |
355 // Restore original values before failing. | 355 // Restore original values before failing. |
356 __ pop(backtrack_stackpointer()); | 356 __ pop(backtrack_stackpointer()); |
357 __ pop(edi); | 357 __ pop(edi); |
358 BranchOrBacktrack(no_condition, on_no_match); | 358 BranchOrBacktrack(no_condition, on_no_match); |
359 | 359 |
360 __ bind(&success); | 360 __ bind(&success); |
361 // Restore original value before continuing. | 361 // Restore original value before continuing. |
362 __ pop(backtrack_stackpointer()); | 362 __ pop(backtrack_stackpointer()); |
(...skipping 87 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
450 Label loop; | 450 Label loop; |
451 __ bind(&loop); | 451 __ bind(&loop); |
452 if (mode_ == ASCII) { | 452 if (mode_ == ASCII) { |
453 __ movzx_b(eax, Operand(edx, 0)); | 453 __ movzx_b(eax, Operand(edx, 0)); |
454 __ cmpb_al(Operand(ebx, 0)); | 454 __ cmpb_al(Operand(ebx, 0)); |
455 } else { | 455 } else { |
456 ASSERT(mode_ == UC16); | 456 ASSERT(mode_ == UC16); |
457 __ movzx_w(eax, Operand(edx, 0)); | 457 __ movzx_w(eax, Operand(edx, 0)); |
458 __ cmpw_ax(Operand(ebx, 0)); | 458 __ cmpw_ax(Operand(ebx, 0)); |
459 } | 459 } |
460 __ j(not_equal, &fail, Label::kNear); | 460 __ j(not_equal, &fail); |
461 // Increment pointers into capture and match string. | 461 // Increment pointers into capture and match string. |
462 __ add(edx, Immediate(char_size())); | 462 __ add(edx, Immediate(char_size())); |
463 __ add(ebx, Immediate(char_size())); | 463 __ add(ebx, Immediate(char_size())); |
464 // Check if we have reached end of match area. | 464 // Check if we have reached end of match area. |
465 __ cmp(ebx, ecx); | 465 __ cmp(ebx, ecx); |
466 __ j(below, &loop); | 466 __ j(below, &loop); |
467 __ jmp(&success, Label::kNear); | 467 __ jmp(&success); |
468 | 468 |
469 __ bind(&fail); | 469 __ bind(&fail); |
470 // Restore backtrack stackpointer. | 470 // Restore backtrack stackpointer. |
471 __ pop(backtrack_stackpointer()); | 471 __ pop(backtrack_stackpointer()); |
472 BranchOrBacktrack(no_condition, on_no_match); | 472 BranchOrBacktrack(no_condition, on_no_match); |
473 | 473 |
474 __ bind(&success); | 474 __ bind(&success); |
475 // Move current character position to position after match. | 475 // Move current character position to position after match. |
476 __ mov(edi, ecx); | 476 __ mov(edi, ecx); |
477 __ sub(edi, esi); | 477 __ sub(edi, esi); |
(...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
535 Label* on_no_match) { | 535 Label* on_no_match) { |
536 // Range checks (c in min..max) are generally implemented by an unsigned | 536 // Range checks (c in min..max) are generally implemented by an unsigned |
537 // (c - min) <= (max - min) check | 537 // (c - min) <= (max - min) check |
538 switch (type) { | 538 switch (type) { |
539 case 's': | 539 case 's': |
540 // Match space-characters | 540 // Match space-characters |
541 if (mode_ == ASCII) { | 541 if (mode_ == ASCII) { |
542 // ASCII space characters are '\t'..'\r' and ' '. | 542 // ASCII space characters are '\t'..'\r' and ' '. |
543 Label success; | 543 Label success; |
544 __ cmp(current_character(), ' '); | 544 __ cmp(current_character(), ' '); |
545 __ j(equal, &success, Label::kNear); | 545 __ j(equal, &success); |
546 // Check range 0x09..0x0d | 546 // Check range 0x09..0x0d |
547 __ lea(eax, Operand(current_character(), -'\t')); | 547 __ lea(eax, Operand(current_character(), -'\t')); |
548 __ cmp(eax, '\r' - '\t'); | 548 __ cmp(eax, '\r' - '\t'); |
549 BranchOrBacktrack(above, on_no_match); | 549 BranchOrBacktrack(above, on_no_match); |
550 __ bind(&success); | 550 __ bind(&success); |
551 return true; | 551 return true; |
552 } | 552 } |
553 return false; | 553 return false; |
554 case 'S': | 554 case 'S': |
555 // Match non-space characters. | 555 // Match non-space characters. |
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
604 __ test_b(current_character(), | 604 __ test_b(current_character(), |
605 Operand::StaticArray(current_character(), times_1, word_map)); | 605 Operand::StaticArray(current_character(), times_1, word_map)); |
606 BranchOrBacktrack(zero, on_no_match); | 606 BranchOrBacktrack(zero, on_no_match); |
607 return true; | 607 return true; |
608 } | 608 } |
609 case 'W': { | 609 case 'W': { |
610 Label done; | 610 Label done; |
611 if (mode_ != ASCII) { | 611 if (mode_ != ASCII) { |
612 // Table is 128 entries, so all ASCII characters can be tested. | 612 // Table is 128 entries, so all ASCII characters can be tested. |
613 __ cmp(current_character(), Immediate('z')); | 613 __ cmp(current_character(), Immediate('z')); |
614 __ j(above, &done, Label::kNear); | 614 __ j(above, &done); |
615 } | 615 } |
616 ASSERT_EQ(0, word_character_map[0]); // Character '\0' is not a word char. | 616 ASSERT_EQ(0, word_character_map[0]); // Character '\0' is not a word char. |
617 ExternalReference word_map = ExternalReference::re_word_character_map(); | 617 ExternalReference word_map = ExternalReference::re_word_character_map(); |
618 __ test_b(current_character(), | 618 __ test_b(current_character(), |
619 Operand::StaticArray(current_character(), times_1, word_map)); | 619 Operand::StaticArray(current_character(), times_1, word_map)); |
620 BranchOrBacktrack(not_zero, on_no_match); | 620 BranchOrBacktrack(not_zero, on_no_match); |
621 if (mode_ != ASCII) { | 621 if (mode_ != ASCII) { |
622 __ bind(&done); | 622 __ bind(&done); |
623 } | 623 } |
624 return true; | 624 return true; |
(...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
688 | 688 |
689 // Check if we have space on the stack for registers. | 689 // Check if we have space on the stack for registers. |
690 Label stack_limit_hit; | 690 Label stack_limit_hit; |
691 Label stack_ok; | 691 Label stack_ok; |
692 | 692 |
693 ExternalReference stack_limit = | 693 ExternalReference stack_limit = |
694 ExternalReference::address_of_stack_limit(masm_->isolate()); | 694 ExternalReference::address_of_stack_limit(masm_->isolate()); |
695 __ mov(ecx, esp); | 695 __ mov(ecx, esp); |
696 __ sub(ecx, Operand::StaticVariable(stack_limit)); | 696 __ sub(ecx, Operand::StaticVariable(stack_limit)); |
697 // Handle it if the stack pointer is already below the stack limit. | 697 // Handle it if the stack pointer is already below the stack limit. |
698 __ j(below_equal, &stack_limit_hit, Label::kNear); | 698 __ j(below_equal, &stack_limit_hit); |
699 // Check if there is room for the variable number of registers above | 699 // Check if there is room for the variable number of registers above |
700 // the stack limit. | 700 // the stack limit. |
701 __ cmp(ecx, num_registers_ * kPointerSize); | 701 __ cmp(ecx, num_registers_ * kPointerSize); |
702 __ j(above_equal, &stack_ok, Label::kNear); | 702 __ j(above_equal, &stack_ok); |
703 // Exit with OutOfMemory exception. There is not enough space on the stack | 703 // Exit with OutOfMemory exception. There is not enough space on the stack |
704 // for our working registers. | 704 // for our working registers. |
705 __ mov(eax, EXCEPTION); | 705 __ mov(eax, EXCEPTION); |
706 __ jmp(&exit_label_); | 706 __ jmp(&exit_label_); |
707 | 707 |
708 __ bind(&stack_limit_hit); | 708 __ bind(&stack_limit_hit); |
709 CallCheckStackGuardState(ebx); | 709 CallCheckStackGuardState(ebx); |
710 __ or_(eax, eax); | 710 __ or_(eax, eax); |
711 // If returned value is non-zero, we exit with the returned value as result. | 711 // If returned value is non-zero, we exit with the returned value as result. |
712 __ j(not_zero, &exit_label_); | 712 __ j(not_zero, &exit_label_); |
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
757 i += kRegistersPerPage) { | 757 i += kRegistersPerPage) { |
758 __ mov(register_location(i), eax); // One write every page. | 758 __ mov(register_location(i), eax); // One write every page. |
759 } | 759 } |
760 | 760 |
761 | 761 |
762 // Initialize backtrack stack pointer. | 762 // Initialize backtrack stack pointer. |
763 __ mov(backtrack_stackpointer(), Operand(ebp, kStackHighEnd)); | 763 __ mov(backtrack_stackpointer(), Operand(ebp, kStackHighEnd)); |
764 // Load previous char as initial value of current-character. | 764 // Load previous char as initial value of current-character. |
765 Label at_start; | 765 Label at_start; |
766 __ cmp(Operand(ebp, kStartIndex), Immediate(0)); | 766 __ cmp(Operand(ebp, kStartIndex), Immediate(0)); |
767 __ j(equal, &at_start, Label::kNear); | 767 __ j(equal, &at_start); |
768 LoadCurrentCharacterUnchecked(-1, 1); // Load previous char. | 768 LoadCurrentCharacterUnchecked(-1, 1); // Load previous char. |
769 __ jmp(&start_label_); | 769 __ jmp(&start_label_); |
770 __ bind(&at_start); | 770 __ bind(&at_start); |
771 __ mov(current_character(), '\n'); | 771 __ mov(current_character(), '\n'); |
772 __ jmp(&start_label_); | 772 __ jmp(&start_label_); |
773 | 773 |
774 | 774 |
775 // Exit code: | 775 // Exit code: |
776 if (success_label_.is_linked()) { | 776 if (success_label_.is_linked()) { |
777 // Save captures when successful. | 777 // Save captures when successful. |
(...skipping 450 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1228 __ add(backtrack_stackpointer(), Immediate(kPointerSize)); | 1228 __ add(backtrack_stackpointer(), Immediate(kPointerSize)); |
1229 } | 1229 } |
1230 | 1230 |
1231 | 1231 |
1232 void RegExpMacroAssemblerIA32::CheckPreemption() { | 1232 void RegExpMacroAssemblerIA32::CheckPreemption() { |
1233 // Check for preemption. | 1233 // Check for preemption. |
1234 Label no_preempt; | 1234 Label no_preempt; |
1235 ExternalReference stack_limit = | 1235 ExternalReference stack_limit = |
1236 ExternalReference::address_of_stack_limit(masm_->isolate()); | 1236 ExternalReference::address_of_stack_limit(masm_->isolate()); |
1237 __ cmp(esp, Operand::StaticVariable(stack_limit)); | 1237 __ cmp(esp, Operand::StaticVariable(stack_limit)); |
1238 __ j(above, &no_preempt, Label::kNear); | 1238 __ j(above, &no_preempt); |
1239 | 1239 |
1240 SafeCall(&check_preempt_label_); | 1240 SafeCall(&check_preempt_label_); |
1241 | 1241 |
1242 __ bind(&no_preempt); | 1242 __ bind(&no_preempt); |
1243 } | 1243 } |
1244 | 1244 |
1245 | 1245 |
1246 void RegExpMacroAssemblerIA32::CheckStackLimit() { | 1246 void RegExpMacroAssemblerIA32::CheckStackLimit() { |
1247 Label no_stack_overflow; | 1247 Label no_stack_overflow; |
1248 ExternalReference stack_limit = | 1248 ExternalReference stack_limit = |
1249 ExternalReference::address_of_regexp_stack_limit(masm_->isolate()); | 1249 ExternalReference::address_of_regexp_stack_limit(masm_->isolate()); |
1250 __ cmp(backtrack_stackpointer(), Operand::StaticVariable(stack_limit)); | 1250 __ cmp(backtrack_stackpointer(), Operand::StaticVariable(stack_limit)); |
1251 __ j(above, &no_stack_overflow, Label::kNear); | 1251 __ j(above, &no_stack_overflow); |
1252 | 1252 |
1253 SafeCall(&stack_overflow_label_); | 1253 SafeCall(&stack_overflow_label_); |
1254 | 1254 |
1255 __ bind(&no_stack_overflow); | 1255 __ bind(&no_stack_overflow); |
1256 } | 1256 } |
1257 | 1257 |
1258 | 1258 |
1259 void RegExpMacroAssemblerIA32::LoadCurrentCharacterUnchecked(int cp_offset, | 1259 void RegExpMacroAssemblerIA32::LoadCurrentCharacterUnchecked(int cp_offset, |
1260 int characters) { | 1260 int characters) { |
1261 if (mode_ == ASCII) { | 1261 if (mode_ == ASCII) { |
(...skipping 19 matching lines...) Expand all Loading... |
1281 } | 1281 } |
1282 | 1282 |
1283 | 1283 |
1284 #undef __ | 1284 #undef __ |
1285 | 1285 |
1286 #endif // V8_INTERPRETED_REGEXP | 1286 #endif // V8_INTERPRETED_REGEXP |
1287 | 1287 |
1288 }} // namespace v8::internal | 1288 }} // namespace v8::internal |
1289 | 1289 |
1290 #endif // V8_TARGET_ARCH_IA32 | 1290 #endif // V8_TARGET_ARCH_IA32 |
OLD | NEW |