| 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 388 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 399 uc16 minus, | 399 uc16 minus, |
| 400 uc16 mask, | 400 uc16 mask, |
| 401 Label* on_not_equal) { | 401 Label* on_not_equal) { |
| 402 ASSERT(minus < String::kMaxUC16CharCode); | 402 ASSERT(minus < String::kMaxUC16CharCode); |
| 403 __ lea(eax, Operand(current_character(), -minus)); | 403 __ lea(eax, Operand(current_character(), -minus)); |
| 404 __ and_(eax, mask); | 404 __ and_(eax, mask); |
| 405 __ cmp(eax, c); | 405 __ cmp(eax, c); |
| 406 BranchOrBacktrack(not_equal, on_not_equal); | 406 BranchOrBacktrack(not_equal, on_not_equal); |
| 407 } | 407 } |
| 408 | 408 |
| 409 bool RegExpMacroAssemblerIA32::CheckSpecialCharacterClass(uc16 type, |
| 410 int cp_offset, |
| 411 bool check_offset, |
| 412 Label* on_no_match) { |
| 413 // Range checks (c in min..max) are generally implemented by an unsigned |
| 414 // (c - min) <= (max - min) check |
| 415 switch (type) { |
| 416 case 's': |
| 417 // Match space-characters |
| 418 if (mode_ == ASCII) { |
| 419 // ASCII space characters are '\t'..'\r' and ' '. |
| 420 if (check_offset) { |
| 421 LoadCurrentCharacter(cp_offset, on_no_match); |
| 422 } else { |
| 423 LoadCurrentCharacterUnchecked(cp_offset, 1); |
| 424 } |
| 425 Label success; |
| 426 __ cmp(current_character(), ' '); |
| 427 __ j(equal, &success); |
| 428 // Check range 0x09..0x0d |
| 429 __ sub(Operand(current_character()), Immediate('\t')); |
| 430 __ cmp(current_character(), '\r' - '\t'); |
| 431 BranchOrBacktrack(above_equal, on_no_match); |
| 432 __ bind(&success); |
| 433 return true; |
| 434 } |
| 435 return false; |
| 436 case 'S': |
| 437 // Match non-space characters. |
| 438 if (check_offset) { |
| 439 LoadCurrentCharacter(cp_offset, on_no_match, 1); |
| 440 } else { |
| 441 LoadCurrentCharacterUnchecked(cp_offset, 1); |
| 442 } |
| 443 if (mode_ == ASCII) { |
| 444 // ASCII space characters are '\t'..'\r' and ' '. |
| 445 __ cmp(current_character(), ' '); |
| 446 BranchOrBacktrack(equal, on_no_match); |
| 447 __ sub(Operand(current_character()), Immediate('\t')); |
| 448 __ cmp(current_character(), '\r' - '\t'); |
| 449 BranchOrBacktrack(below, on_no_match); |
| 450 return true; |
| 451 } |
| 452 return false; |
| 453 case 'd': |
| 454 // Match ASCII digits ('0'..'9') |
| 455 if (check_offset) { |
| 456 LoadCurrentCharacter(cp_offset, on_no_match, 1); |
| 457 } else { |
| 458 LoadCurrentCharacterUnchecked(cp_offset, 1); |
| 459 } |
| 460 __ sub(Operand(current_character()), Immediate('0')); |
| 461 __ cmp(current_character(), '9' - '0'); |
| 462 BranchOrBacktrack(greater_equal, on_no_match); |
| 463 return true; |
| 464 case 'D': |
| 465 // Match non ASCII-digits |
| 466 if (check_offset) { |
| 467 LoadCurrentCharacter(cp_offset, on_no_match, 1); |
| 468 } else { |
| 469 LoadCurrentCharacterUnchecked(cp_offset, 1); |
| 470 } |
| 471 __ sub(Operand(current_character()), Immediate('0')); |
| 472 __ cmp(current_character(), '9' - '0'); |
| 473 BranchOrBacktrack(below, on_no_match); |
| 474 return true; |
| 475 case '.': { |
| 476 // Match non-newlines (not 0x0a('\n'), 0x0d('\r'), 0x2028 and 0x2029) |
| 477 if (check_offset) { |
| 478 LoadCurrentCharacter(cp_offset, on_no_match, 1); |
| 479 } else { |
| 480 LoadCurrentCharacterUnchecked(cp_offset, 1); |
| 481 } |
| 482 // Compute hash value so exactly 0x0a and 0x0d become zero. |
| 483 __ sub(Operand(current_character()), Immediate('\n')); |
| 484 __ mov(eax, current_character()); |
| 485 __ and_(current_character(), 0x01); |
| 486 __ shr(eax, 1); |
| 487 __ xor_(current_character(), Operand(eax)); |
| 488 BranchOrBacktrack(equal, on_no_match); |
| 489 if (mode_ == UC16) { |
| 490 // Compare original value to 0x2028 and 0x2029, using the already |
| 491 // computed ((current_char - '\n') >> 1) in eax. |
| 492 __ cmp(eax, (0x2028 - '\n') >> 1); |
| 493 BranchOrBacktrack(equal, on_no_match); |
| 494 } |
| 495 return true; |
| 496 } |
| 497 case '*': |
| 498 // Match any character. |
| 499 if (check_offset) { |
| 500 CheckPosition(cp_offset, on_no_match); |
| 501 } |
| 502 return true; |
| 503 // No custom implementation (yet): w, W, s(UC16), S(UC16). |
| 504 default: |
| 505 return false; |
| 506 } |
| 507 } |
| 409 | 508 |
| 410 void RegExpMacroAssemblerIA32::DispatchHalfNibbleMap( | 509 void RegExpMacroAssemblerIA32::DispatchHalfNibbleMap( |
| 411 uc16 start, | 510 uc16 start, |
| 412 Label* half_nibble_map, | 511 Label* half_nibble_map, |
| 413 const Vector<Label*>& destinations) { | 512 const Vector<Label*>& destinations) { |
| 414 UNIMPLEMENTED(); | 513 UNIMPLEMENTED(); |
| 415 __ mov(eax, current_character()); | 514 __ mov(eax, current_character()); |
| 416 __ sub(Operand(eax), Immediate(start)); | 515 __ sub(Operand(eax), Immediate(start)); |
| 417 | 516 |
| 418 __ mov(ecx, eax); | 517 __ mov(ecx, eax); |
| (...skipping 231 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 650 return kIA32Implementation; | 749 return kIA32Implementation; |
| 651 } | 750 } |
| 652 | 751 |
| 653 | 752 |
| 654 void RegExpMacroAssemblerIA32::LoadCurrentCharacter(int cp_offset, | 753 void RegExpMacroAssemblerIA32::LoadCurrentCharacter(int cp_offset, |
| 655 Label* on_end_of_input, | 754 Label* on_end_of_input, |
| 656 bool check_bounds, | 755 bool check_bounds, |
| 657 int characters) { | 756 int characters) { |
| 658 ASSERT(cp_offset >= 0); | 757 ASSERT(cp_offset >= 0); |
| 659 ASSERT(cp_offset < (1<<30)); // Be sane! (And ensure negation works) | 758 ASSERT(cp_offset < (1<<30)); // Be sane! (And ensure negation works) |
| 660 if (check_bounds) { | 759 CheckPosition(cp_offset + characters - 1, on_end_of_input); |
| 661 __ cmp(edi, -(cp_offset + characters) * char_size()); | |
| 662 BranchOrBacktrack(greater, on_end_of_input); | |
| 663 } | |
| 664 LoadCurrentCharacterUnchecked(cp_offset, characters); | 760 LoadCurrentCharacterUnchecked(cp_offset, characters); |
| 665 } | 761 } |
| 666 | 762 |
| 667 | 763 |
| 668 void RegExpMacroAssemblerIA32::PopCurrentPosition() { | 764 void RegExpMacroAssemblerIA32::PopCurrentPosition() { |
| 669 __ pop(edi); | 765 __ pop(edi); |
| 670 } | 766 } |
| 671 | 767 |
| 672 | 768 |
| 673 void RegExpMacroAssemblerIA32::PopRegister(int register_index) { | 769 void RegExpMacroAssemblerIA32::PopRegister(int register_index) { |
| (...skipping 134 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 808 Register RegExpMacroAssemblerIA32::current_character() { | 904 Register RegExpMacroAssemblerIA32::current_character() { |
| 809 return edx; | 905 return edx; |
| 810 } | 906 } |
| 811 | 907 |
| 812 | 908 |
| 813 size_t RegExpMacroAssemblerIA32::char_size() { | 909 size_t RegExpMacroAssemblerIA32::char_size() { |
| 814 return static_cast<size_t>(mode_); | 910 return static_cast<size_t>(mode_); |
| 815 } | 911 } |
| 816 | 912 |
| 817 | 913 |
| 914 void RegExpMacroAssemblerIA32::CheckPosition(int cp_offset, |
| 915 Label* on_outside_input) { |
| 916 __ cmp(edi, -cp_offset * char_size()); |
| 917 BranchOrBacktrack(greater_equal, on_outside_input); |
| 918 } |
| 919 |
| 920 |
| 818 void RegExpMacroAssemblerIA32::BranchOrBacktrack(Condition condition, | 921 void RegExpMacroAssemblerIA32::BranchOrBacktrack(Condition condition, |
| 819 Label* to) { | 922 Label* to) { |
| 820 if (condition < 0) { // No condition | 923 if (condition < 0) { // No condition |
| 821 if (to == NULL) { | 924 if (to == NULL) { |
| 822 Backtrack(); | 925 Backtrack(); |
| 823 return; | 926 return; |
| 824 } | 927 } |
| 825 __ jmp(to); | 928 __ jmp(to); |
| 826 return; | 929 return; |
| 827 } | 930 } |
| (...skipping 91 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 919 | 1022 |
| 920 | 1023 |
| 921 void RegExpMacroAssemblerIA32::LoadConstantBufferAddress(Register reg, | 1024 void RegExpMacroAssemblerIA32::LoadConstantBufferAddress(Register reg, |
| 922 ArraySlice* buffer) { | 1025 ArraySlice* buffer) { |
| 923 __ mov(reg, buffer->array()); | 1026 __ mov(reg, buffer->array()); |
| 924 __ add(Operand(reg), Immediate(buffer->base_offset())); | 1027 __ add(Operand(reg), Immediate(buffer->base_offset())); |
| 925 } | 1028 } |
| 926 | 1029 |
| 927 #undef __ | 1030 #undef __ |
| 928 }} // namespace v8::internal | 1031 }} // namespace v8::internal |
| OLD | NEW |