OLD | NEW |
1 // Copyright 2008 the V8 project authors. All rights reserved. | 1 // Copyright 2008 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 |
(...skipping 166 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
177 | 177 |
178 | 178 |
179 void RegExpMacroAssemblerIA32::CheckCharacterLT(uc16 limit, Label* on_less) { | 179 void RegExpMacroAssemblerIA32::CheckCharacterLT(uc16 limit, Label* on_less) { |
180 __ cmp(current_character(), limit); | 180 __ cmp(current_character(), limit); |
181 BranchOrBacktrack(less, on_less); | 181 BranchOrBacktrack(less, on_less); |
182 } | 182 } |
183 | 183 |
184 | 184 |
185 void RegExpMacroAssemblerIA32::CheckCharacters(Vector<const uc16> str, | 185 void RegExpMacroAssemblerIA32::CheckCharacters(Vector<const uc16> str, |
186 int cp_offset, | 186 int cp_offset, |
187 Label* on_failure) { | 187 Label* on_failure, |
| 188 bool check_end_of_string) { |
188 int byte_length = str.length() * char_size(); | 189 int byte_length = str.length() * char_size(); |
189 int byte_offset = cp_offset * char_size(); | 190 int byte_offset = cp_offset * char_size(); |
190 __ cmp(Operand(edi), Immediate(-(byte_offset + byte_length))); | 191 if (check_end_of_string) { |
191 BranchOrBacktrack(greater, on_failure); | 192 __ cmp(Operand(edi), Immediate(-(byte_offset + byte_length))); |
| 193 BranchOrBacktrack(greater, on_failure); |
| 194 } |
192 | 195 |
193 if (str.length() <= kMaxInlineStringTests) { | 196 if (str.length() <= kMaxInlineStringTests) { |
194 for (int i = 0; i < str.length(); i++) { | 197 for (int i = 0; i < str.length(); i++) { |
195 if (mode_ == ASCII) { | 198 if (mode_ == ASCII) { |
196 __ cmpb(Operand(esi, edi, times_1, byte_offset + i), | 199 __ cmpb(Operand(esi, edi, times_1, byte_offset + i), |
197 static_cast<int8_t>(str[i])); | 200 static_cast<int8_t>(str[i])); |
198 } else { | 201 } else { |
199 ASSERT(mode_ == UC16); | 202 ASSERT(mode_ == UC16); |
200 __ cmpw(Operand(esi, edi, times_1, byte_offset + i * sizeof(uc16)), | 203 __ cmpw(Operand(esi, edi, times_1, byte_offset + i * sizeof(uc16)), |
201 Immediate(str[i])); | 204 Immediate(str[i])); |
(...skipping 24 matching lines...) Expand all Loading... |
226 } else { | 229 } else { |
227 ASSERT(char_size() == 2); | 230 ASSERT(char_size() == 2); |
228 __ rep_cmpsw(); | 231 __ rep_cmpsw(); |
229 } | 232 } |
230 __ mov(esi, ebx); | 233 __ mov(esi, ebx); |
231 __ mov(edi, eax); | 234 __ mov(edi, eax); |
232 BranchOrBacktrack(not_equal, on_failure); | 235 BranchOrBacktrack(not_equal, on_failure); |
233 } | 236 } |
234 | 237 |
235 | 238 |
236 void RegExpMacroAssemblerIA32::CheckCurrentPosition(int register_index, | 239 void RegExpMacroAssemblerIA32::CheckGreedyLoop(Label* on_equal) { |
237 Label* on_equal) { | 240 Label fallthrough; |
238 __ cmp(edi, register_location(register_index)); | 241 __ cmp(edi, Operand(esp, 0)); |
239 BranchOrBacktrack(equal, on_equal); | 242 __ j(not_equal, &fallthrough); |
| 243 __ add(Operand(esp), Immediate(4)); // Pop. |
| 244 BranchOrBacktrack(no_condition, on_equal); |
| 245 __ bind(&fallthrough); |
240 } | 246 } |
241 | 247 |
242 | 248 |
243 void RegExpMacroAssemblerIA32::CheckNotBackReferenceIgnoreCase( | 249 void RegExpMacroAssemblerIA32::CheckNotBackReferenceIgnoreCase( |
244 int start_reg, | 250 int start_reg, |
245 Label* on_no_match) { | 251 Label* on_no_match) { |
246 Label fallthrough; | 252 Label fallthrough; |
247 __ mov(eax, register_location(start_reg)); | 253 __ mov(eax, register_location(start_reg)); |
248 __ mov(ecx, register_location(start_reg + 1)); | 254 __ mov(ecx, register_location(start_reg + 1)); |
249 __ sub(ecx, Operand(eax)); // Length to check. | 255 __ sub(ecx, Operand(eax)); // Length to check. |
(...skipping 225 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
475 UNIMPLEMENTED(); // Has no use. | 481 UNIMPLEMENTED(); // Has no use. |
476 } | 482 } |
477 | 483 |
478 | 484 |
479 void RegExpMacroAssemblerIA32::Fail() { | 485 void RegExpMacroAssemblerIA32::Fail() { |
480 __ xor_(eax, Operand(eax)); // zero eax. | 486 __ xor_(eax, Operand(eax)); // zero eax. |
481 __ jmp(&exit_label_); | 487 __ jmp(&exit_label_); |
482 } | 488 } |
483 | 489 |
484 | 490 |
485 Handle<Object> RegExpMacroAssemblerIA32::GetCode() { | 491 Handle<Object> RegExpMacroAssemblerIA32::GetCode(Handle<String> source) { |
486 // Finalize code - write the entry point code now we know how many | 492 // Finalize code - write the entry point code now we know how many |
487 // registers we need. | 493 // registers we need. |
488 | 494 |
489 // Entry code: | 495 // Entry code: |
490 __ bind(&entry_label_); | 496 __ bind(&entry_label_); |
491 // Save callee-save registers. Order here should correspond to order of | 497 // Save callee-save registers. Order here should correspond to order of |
492 // kBackup_ebx etc. | 498 // kBackup_ebx etc. |
493 __ push(esi); | 499 __ push(esi); |
494 __ push(edi); | 500 __ push(edi); |
495 __ push(ebx); // Callee-save on MacOS. | 501 __ push(ebx); // Callee-save on MacOS. |
(...skipping 18 matching lines...) Expand all Loading... |
514 Label init_loop; | 520 Label init_loop; |
515 __ bind(&init_loop); | 521 __ bind(&init_loop); |
516 __ mov(Operand(ebp, ecx, times_4, +0), eax); | 522 __ mov(Operand(ebp, ecx, times_4, +0), eax); |
517 __ inc(ecx); | 523 __ inc(ecx); |
518 __ j(not_equal, &init_loop); | 524 __ j(not_equal, &init_loop); |
519 } | 525 } |
520 // Load previous char as initial value of current-character. | 526 // Load previous char as initial value of current-character. |
521 Label at_start; | 527 Label at_start; |
522 __ cmp(Operand(ebp, kAtStart), Immediate(0)); | 528 __ cmp(Operand(ebp, kAtStart), Immediate(0)); |
523 __ j(not_equal, &at_start); | 529 __ j(not_equal, &at_start); |
524 LoadCurrentCharToRegister(-1); // Load previous char. | 530 LoadCurrentCharacterUnchecked(-1); // Load previous char. |
525 __ jmp(&start_label_); | 531 __ jmp(&start_label_); |
526 __ bind(&at_start); | 532 __ bind(&at_start); |
527 __ mov(current_character(), '\n'); | 533 __ mov(current_character(), '\n'); |
528 __ jmp(&start_label_); | 534 __ jmp(&start_label_); |
529 | 535 |
530 | 536 |
531 // Exit code: | 537 // Exit code: |
532 // Success | 538 // Success |
533 __ bind(&success_label_); | 539 __ bind(&success_label_); |
534 if (num_saved_registers_ > 0) { | 540 if (num_saved_registers_ > 0) { |
(...skipping 20 matching lines...) Expand all Loading... |
555 __ pop(edi); | 561 __ pop(edi); |
556 __ pop(esi); | 562 __ pop(esi); |
557 __ ret(0); | 563 __ ret(0); |
558 | 564 |
559 CodeDesc code_desc; | 565 CodeDesc code_desc; |
560 masm_->GetCode(&code_desc); | 566 masm_->GetCode(&code_desc); |
561 Handle<Code> code = Factory::NewCode(code_desc, | 567 Handle<Code> code = Factory::NewCode(code_desc, |
562 NULL, | 568 NULL, |
563 Code::ComputeFlags(Code::REGEXP), | 569 Code::ComputeFlags(Code::REGEXP), |
564 self_); | 570 self_); |
565 LOG(CodeCreateEvent("RegExp", *code, "(Compiled RegExp)")); | 571 LOG(CodeCreateEvent("RegExp", *code, *(source->ToCString()))); |
566 return Handle<Object>::cast(code); | 572 return Handle<Object>::cast(code); |
567 } | 573 } |
568 | 574 |
569 | 575 |
570 void RegExpMacroAssemblerIA32::GoTo(Label* to) { | 576 void RegExpMacroAssemblerIA32::GoTo(Label* to) { |
571 __ jmp(to); | 577 __ jmp(to); |
572 } | 578 } |
573 | 579 |
574 | 580 |
575 void RegExpMacroAssemblerIA32::IfRegisterGE(int reg, | 581 void RegExpMacroAssemblerIA32::IfRegisterGE(int reg, |
(...skipping 17 matching lines...) Expand all Loading... |
593 return kIA32Implementation; | 599 return kIA32Implementation; |
594 } | 600 } |
595 | 601 |
596 | 602 |
597 void RegExpMacroAssemblerIA32::LoadCurrentCharacter(int cp_offset, | 603 void RegExpMacroAssemblerIA32::LoadCurrentCharacter(int cp_offset, |
598 Label* on_end_of_input) { | 604 Label* on_end_of_input) { |
599 ASSERT(cp_offset >= 0); | 605 ASSERT(cp_offset >= 0); |
600 ASSERT(cp_offset < (1<<30)); // Be sane! (And ensure negation works) | 606 ASSERT(cp_offset < (1<<30)); // Be sane! (And ensure negation works) |
601 __ cmp(edi, -cp_offset * char_size()); | 607 __ cmp(edi, -cp_offset * char_size()); |
602 BranchOrBacktrack(greater_equal, on_end_of_input); | 608 BranchOrBacktrack(greater_equal, on_end_of_input); |
603 LoadCurrentCharToRegister(cp_offset); | 609 LoadCurrentCharacterUnchecked(cp_offset); |
604 } | 610 } |
605 | 611 |
606 | 612 |
607 void RegExpMacroAssemblerIA32::PopCurrentPosition() { | 613 void RegExpMacroAssemblerIA32::PopCurrentPosition() { |
608 __ pop(edi); | 614 __ pop(edi); |
609 } | 615 } |
610 | 616 |
611 | 617 |
612 void RegExpMacroAssemblerIA32::PopRegister(int register_index) { | 618 void RegExpMacroAssemblerIA32::PopRegister(int register_index) { |
613 __ pop(register_location(register_index)); | 619 __ pop(register_location(register_index)); |
(...skipping 30 matching lines...) Expand all Loading... |
644 ASSERT(register_index >= num_saved_registers_); // Reserved for positions! | 650 ASSERT(register_index >= num_saved_registers_); // Reserved for positions! |
645 __ mov(register_location(register_index), Immediate(to)); | 651 __ mov(register_location(register_index), Immediate(to)); |
646 } | 652 } |
647 | 653 |
648 | 654 |
649 void RegExpMacroAssemblerIA32::Succeed() { | 655 void RegExpMacroAssemblerIA32::Succeed() { |
650 __ jmp(&success_label_); | 656 __ jmp(&success_label_); |
651 } | 657 } |
652 | 658 |
653 | 659 |
654 void RegExpMacroAssemblerIA32::WriteCurrentPositionToRegister(int reg) { | 660 void RegExpMacroAssemblerIA32::WriteCurrentPositionToRegister(int reg, |
655 __ mov(register_location(reg), edi); | 661 int cp_offset) { |
| 662 if (cp_offset == 0) { |
| 663 __ mov(register_location(reg), edi); |
| 664 } else { |
| 665 __ lea(eax, Operand(edi, cp_offset)); |
| 666 __ mov(register_location(reg), eax); |
| 667 } |
656 } | 668 } |
657 | 669 |
| 670 |
658 void RegExpMacroAssemblerIA32::WriteStackPointerToRegister(int reg) { | 671 void RegExpMacroAssemblerIA32::WriteStackPointerToRegister(int reg) { |
659 __ mov(register_location(reg), esp); | 672 __ mov(register_location(reg), esp); |
660 } | 673 } |
661 | 674 |
662 | 675 |
663 // Private methods: | 676 // Private methods: |
664 | 677 |
665 | 678 |
666 static unibrow::Mapping<unibrow::Ecma262Canonicalize> canonicalize; | 679 static unibrow::Mapping<unibrow::Ecma262Canonicalize> canonicalize; |
667 | 680 |
(...skipping 95 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
763 __ pop(edi); | 776 __ pop(edi); |
764 __ mov(esi, Operand(ebp, kInputBuffer)); | 777 __ mov(esi, Operand(ebp, kInputBuffer)); |
765 __ mov(esi, Operand(esi, 0)); | 778 __ mov(esi, Operand(esi, 0)); |
766 __ add(esi, Operand(ebp, kInputEndOffset)); | 779 __ add(esi, Operand(ebp, kInputEndOffset)); |
767 | 780 |
768 __ bind(&no_preempt); | 781 __ bind(&no_preempt); |
769 } | 782 } |
770 } | 783 } |
771 | 784 |
772 | 785 |
773 void RegExpMacroAssemblerIA32::LoadCurrentCharToRegister(int cp_offset) { | 786 void RegExpMacroAssemblerIA32::LoadCurrentCharacterUnchecked(int cp_offset) { |
774 if (mode_ == ASCII) { | 787 if (mode_ == ASCII) { |
775 __ movzx_b(current_character(), Operand(esi, edi, times_1, cp_offset)); | 788 __ movzx_b(current_character(), Operand(esi, edi, times_1, cp_offset)); |
776 return; | 789 return; |
777 } | 790 } |
778 ASSERT(mode_ == UC16); | 791 ASSERT(mode_ == UC16); |
779 __ movzx_w(current_character(), | 792 __ movzx_w(current_character(), |
780 Operand(esi, edi, times_1, cp_offset * sizeof(uc16))); | 793 Operand(esi, edi, times_1, cp_offset * sizeof(uc16))); |
781 } | 794 } |
782 | 795 |
783 | 796 |
784 void RegExpMacroAssemblerIA32::LoadConstantBufferAddress(Register reg, | 797 void RegExpMacroAssemblerIA32::LoadConstantBufferAddress(Register reg, |
785 ArraySlice* buffer) { | 798 ArraySlice* buffer) { |
786 __ mov(reg, buffer->array()); | 799 __ mov(reg, buffer->array()); |
787 __ add(Operand(reg), Immediate(buffer->base_offset())); | 800 __ add(Operand(reg), Immediate(buffer->base_offset())); |
788 } | 801 } |
789 | 802 |
790 #undef __ | 803 #undef __ |
791 }} // namespace v8::internal | 804 }} // namespace v8::internal |
OLD | NEW |