| OLD | NEW |
| 1 // Copyright 2008-2009 the V8 project authors. All rights reserved. | 1 // Copyright 2008-2009 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 453 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 464 Label* on_not_equal) { | 464 Label* on_not_equal) { |
| 465 ASSERT(minus < String::kMaxUC16CharCode); | 465 ASSERT(minus < String::kMaxUC16CharCode); |
| 466 __ lea(eax, Operand(current_character(), -minus)); | 466 __ lea(eax, Operand(current_character(), -minus)); |
| 467 __ and_(eax, mask); | 467 __ and_(eax, mask); |
| 468 __ cmp(eax, c); | 468 __ cmp(eax, c); |
| 469 BranchOrBacktrack(not_equal, on_not_equal); | 469 BranchOrBacktrack(not_equal, on_not_equal); |
| 470 } | 470 } |
| 471 | 471 |
| 472 | 472 |
| 473 bool RegExpMacroAssemblerIA32::CheckSpecialCharacterClass(uc16 type, | 473 bool RegExpMacroAssemblerIA32::CheckSpecialCharacterClass(uc16 type, |
| 474 int cp_offset, | |
| 475 bool check_offset, | |
| 476 Label* on_no_match) { | 474 Label* on_no_match) { |
| 477 // Range checks (c in min..max) are generally implemented by an unsigned | 475 // Range checks (c in min..max) are generally implemented by an unsigned |
| 478 // (c - min) <= (max - min) check | 476 // (c - min) <= (max - min) check |
| 479 switch (type) { | 477 switch (type) { |
| 480 case 's': | 478 case 's': |
| 481 // Match space-characters | 479 // Match space-characters |
| 482 if (mode_ == ASCII) { | 480 if (mode_ == ASCII) { |
| 483 // ASCII space characters are '\t'..'\r' and ' '. | 481 // ASCII space characters are '\t'..'\r' and ' '. |
| 484 if (check_offset) { | |
| 485 LoadCurrentCharacter(cp_offset, on_no_match); | |
| 486 } else { | |
| 487 LoadCurrentCharacterUnchecked(cp_offset, 1); | |
| 488 } | |
| 489 Label success; | 482 Label success; |
| 490 __ cmp(current_character(), ' '); | 483 __ cmp(current_character(), ' '); |
| 491 __ j(equal, &success); | 484 __ j(equal, &success); |
| 492 // Check range 0x09..0x0d | 485 // Check range 0x09..0x0d |
| 493 __ sub(Operand(current_character()), Immediate('\t')); | 486 __ lea(eax, Operand(current_character(), -'\t')); |
| 494 __ cmp(current_character(), '\r' - '\t'); | 487 __ cmp(eax, '\r' - '\t'); |
| 495 BranchOrBacktrack(above, on_no_match); | 488 BranchOrBacktrack(above, on_no_match); |
| 496 __ bind(&success); | 489 __ bind(&success); |
| 497 return true; | 490 return true; |
| 498 } | 491 } |
| 499 return false; | 492 return false; |
| 500 case 'S': | 493 case 'S': |
| 501 // Match non-space characters. | 494 // Match non-space characters. |
| 502 if (check_offset) { | |
| 503 LoadCurrentCharacter(cp_offset, on_no_match, 1); | |
| 504 } else { | |
| 505 LoadCurrentCharacterUnchecked(cp_offset, 1); | |
| 506 } | |
| 507 if (mode_ == ASCII) { | 495 if (mode_ == ASCII) { |
| 508 // ASCII space characters are '\t'..'\r' and ' '. | 496 // ASCII space characters are '\t'..'\r' and ' '. |
| 509 __ cmp(current_character(), ' '); | 497 __ cmp(current_character(), ' '); |
| 510 BranchOrBacktrack(equal, on_no_match); | 498 BranchOrBacktrack(equal, on_no_match); |
| 511 __ sub(Operand(current_character()), Immediate('\t')); | 499 __ lea(eax, Operand(current_character(), -'\t')); |
| 512 __ cmp(current_character(), '\r' - '\t'); | 500 __ cmp(eax, '\r' - '\t'); |
| 513 BranchOrBacktrack(below_equal, on_no_match); | 501 BranchOrBacktrack(below_equal, on_no_match); |
| 514 return true; | 502 return true; |
| 515 } | 503 } |
| 516 return false; | 504 return false; |
| 517 case 'd': | 505 case 'd': |
| 518 // Match ASCII digits ('0'..'9') | 506 // Match ASCII digits ('0'..'9') |
| 519 if (check_offset) { | 507 __ lea(eax, Operand(current_character(), -'0')); |
| 520 LoadCurrentCharacter(cp_offset, on_no_match, 1); | 508 __ cmp(eax, '9' - '0'); |
| 521 } else { | |
| 522 LoadCurrentCharacterUnchecked(cp_offset, 1); | |
| 523 } | |
| 524 __ sub(Operand(current_character()), Immediate('0')); | |
| 525 __ cmp(current_character(), '9' - '0'); | |
| 526 BranchOrBacktrack(above, on_no_match); | 509 BranchOrBacktrack(above, on_no_match); |
| 527 return true; | 510 return true; |
| 528 case 'D': | 511 case 'D': |
| 529 // Match non ASCII-digits | 512 // Match non ASCII-digits |
| 530 if (check_offset) { | 513 __ lea(eax, Operand(current_character(), -'0')); |
| 531 LoadCurrentCharacter(cp_offset, on_no_match, 1); | 514 __ cmp(eax, '9' - '0'); |
| 532 } else { | |
| 533 LoadCurrentCharacterUnchecked(cp_offset, 1); | |
| 534 } | |
| 535 __ sub(Operand(current_character()), Immediate('0')); | |
| 536 __ cmp(current_character(), '9' - '0'); | |
| 537 BranchOrBacktrack(below_equal, on_no_match); | 515 BranchOrBacktrack(below_equal, on_no_match); |
| 538 return true; | 516 return true; |
| 539 case '.': { | 517 case '.': { |
| 540 // Match non-newlines (not 0x0a('\n'), 0x0d('\r'), 0x2028 and 0x2029) | 518 // Match non-newlines (not 0x0a('\n'), 0x0d('\r'), 0x2028 and 0x2029) |
| 541 if (check_offset) { | 519 __ mov(Operand(eax), current_character()); |
| 542 LoadCurrentCharacter(cp_offset, on_no_match, 1); | 520 __ xor_(Operand(eax), Immediate(0x01)); |
| 543 } else { | |
| 544 LoadCurrentCharacterUnchecked(cp_offset, 1); | |
| 545 } | |
| 546 __ xor_(Operand(current_character()), Immediate(0x01)); | |
| 547 // See if current character is '\n'^1 or '\r'^1, i.e., 0x0b or 0x0c | 521 // See if current character is '\n'^1 or '\r'^1, i.e., 0x0b or 0x0c |
| 548 __ sub(Operand(current_character()), Immediate(0x0b)); | 522 __ sub(Operand(eax), Immediate(0x0b)); |
| 549 __ cmp(current_character(), 0x0c - 0x0b); | 523 __ cmp(eax, 0x0c - 0x0b); |
| 550 BranchOrBacktrack(below_equal, on_no_match); | 524 BranchOrBacktrack(below_equal, on_no_match); |
| 551 if (mode_ == UC16) { | 525 if (mode_ == UC16) { |
| 552 // Compare original value to 0x2028 and 0x2029, using the already | 526 // Compare original value to 0x2028 and 0x2029, using the already |
| 553 // computed (current_char ^ 0x01 - 0x0b). I.e., check for | 527 // computed (current_char ^ 0x01 - 0x0b). I.e., check for |
| 554 // 0x201d (0x2028 - 0x0b) or 0x201e. | 528 // 0x201d (0x2028 - 0x0b) or 0x201e. |
| 555 __ sub(Operand(current_character()), Immediate(0x2028 - 0x0b)); | 529 __ sub(Operand(eax), Immediate(0x2028 - 0x0b)); |
| 556 __ cmp(current_character(), 1); | 530 __ cmp(eax, 0x2029 - 0x2028); |
| 557 BranchOrBacktrack(below_equal, on_no_match); | 531 BranchOrBacktrack(below_equal, on_no_match); |
| 558 } | 532 } |
| 559 return true; | 533 return true; |
| 560 } | 534 } |
| 535 case 'w': { |
| 536 Label done, check_digits; |
| 537 __ cmp(Operand(current_character()), Immediate('9')); |
| 538 __ j(less_equal, &check_digits); |
| 539 __ cmp(Operand(current_character()), Immediate('_')); |
| 540 __ j(equal, &done); |
| 541 // Convert to lower case if letter. |
| 542 __ mov(Operand(eax), current_character()); |
| 543 __ or_(eax, 0x20); |
| 544 // check current character in range ['a'..'z'], nondestructively. |
| 545 __ sub(Operand(eax), Immediate('a')); |
| 546 __ cmp(Operand(eax), Immediate('z' - 'a')); |
| 547 BranchOrBacktrack(above, on_no_match); |
| 548 __ jmp(&done); |
| 549 __ bind(&check_digits); |
| 550 // Check current character in range ['0'..'9']. |
| 551 __ cmp(Operand(current_character()), Immediate('0')); |
| 552 BranchOrBacktrack(below, on_no_match); |
| 553 __ bind(&done); |
| 554 |
| 555 return true; |
| 556 } |
| 557 case 'W': { |
| 558 Label done, check_digits; |
| 559 __ cmp(Operand(current_character()), Immediate('9')); |
| 560 __ j(less_equal, &check_digits); |
| 561 __ cmp(Operand(current_character()), Immediate('_')); |
| 562 BranchOrBacktrack(equal, on_no_match); |
| 563 // Convert to lower case if letter. |
| 564 __ mov(Operand(eax), current_character()); |
| 565 __ or_(eax, 0x20); |
| 566 // check current character in range ['a'..'z'], nondestructively. |
| 567 __ sub(Operand(eax), Immediate('a')); |
| 568 __ cmp(Operand(eax), Immediate('z' - 'a')); |
| 569 BranchOrBacktrack(below_equal, on_no_match); |
| 570 __ jmp(&done); |
| 571 __ bind(&check_digits); |
| 572 // Check current character in range ['0'..'9']. |
| 573 __ cmp(Operand(current_character()), Immediate('0')); |
| 574 BranchOrBacktrack(above_equal, on_no_match); |
| 575 __ bind(&done); |
| 576 return true; |
| 577 } |
| 578 // Non-standard classes (with no syntactic shorthand) used internally. |
| 561 case '*': | 579 case '*': |
| 562 // Match any character. | 580 // Match any character. |
| 563 if (check_offset) { | 581 return true; |
| 564 CheckPosition(cp_offset, on_no_match); | 582 case 'n': { |
| 583 // Match newlines (0x0a('\n'), 0x0d('\r'), 0x2028 or 0x2029). |
| 584 // The opposite of '.'. |
| 585 __ mov(Operand(eax), current_character()); |
| 586 __ xor_(Operand(eax), Immediate(0x01)); |
| 587 // See if current character is '\n'^1 or '\r'^1, i.e., 0x0b or 0x0c |
| 588 __ sub(Operand(eax), Immediate(0x0b)); |
| 589 __ cmp(eax, 0x0c - 0x0b); |
| 590 if (mode_ == ASCII) { |
| 591 BranchOrBacktrack(above, on_no_match); |
| 592 } else { |
| 593 Label done; |
| 594 BranchOrBacktrack(below_equal, &done); |
| 595 ASSERT_EQ(UC16, mode_); |
| 596 // Compare original value to 0x2028 and 0x2029, using the already |
| 597 // computed (current_char ^ 0x01 - 0x0b). I.e., check for |
| 598 // 0x201d (0x2028 - 0x0b) or 0x201e. |
| 599 __ sub(Operand(eax), Immediate(0x2028 - 0x0b)); |
| 600 __ cmp(eax, 1); |
| 601 BranchOrBacktrack(above, on_no_match); |
| 602 __ bind(&done); |
| 565 } | 603 } |
| 566 return true; | 604 return true; |
| 567 // No custom implementation (yet): w, W, s(UC16), S(UC16). | 605 } |
| 606 // No custom implementation (yet): s(UC16), S(UC16). |
| 568 default: | 607 default: |
| 569 return false; | 608 return false; |
| 570 } | 609 } |
| 571 } | 610 } |
| 572 | 611 |
| 573 | 612 |
| 574 void RegExpMacroAssemblerIA32::Fail() { | 613 void RegExpMacroAssemblerIA32::Fail() { |
| 575 ASSERT(FAILURE == 0); // Return value for failure is zero. | 614 ASSERT(FAILURE == 0); // Return value for failure is zero. |
| 576 __ xor_(eax, Operand(eax)); // zero eax. | 615 __ xor_(eax, Operand(eax)); // zero eax. |
| 577 __ jmp(&exit_label_); | 616 __ jmp(&exit_label_); |
| (...skipping 581 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1159 } | 1198 } |
| 1160 } | 1199 } |
| 1161 } | 1200 } |
| 1162 | 1201 |
| 1163 | 1202 |
| 1164 #undef __ | 1203 #undef __ |
| 1165 | 1204 |
| 1166 #endif // V8_NATIVE_REGEXP | 1205 #endif // V8_NATIVE_REGEXP |
| 1167 | 1206 |
| 1168 }} // namespace v8::internal | 1207 }} // namespace v8::internal |
| OLD | NEW |