| 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 |