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 |