| OLD | NEW |
| 1 // Copyright 2006-2008 the V8 project authors. All rights reserved. | 1 // Copyright 2006-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 702 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 713 CHECK_EQ(84, captures[4]); | 713 CHECK_EQ(84, captures[4]); |
| 714 | 714 |
| 715 Handle<String> f2 = | 715 Handle<String> f2 = |
| 716 Factory::NewStringFromAscii(CStrVector("barfoo")); | 716 Factory::NewStringFromAscii(CStrVector("barfoo")); |
| 717 Handle<String> f2_16 = RegExpImpl::StringToTwoByte(f2); | 717 Handle<String> f2_16 = RegExpImpl::StringToTwoByte(f2); |
| 718 CHECK(!IrregexpInterpreter::Match(array, f2_16, captures, 0)); | 718 CHECK(!IrregexpInterpreter::Match(array, f2_16, captures, 0)); |
| 719 CHECK_EQ(42, captures[0]); | 719 CHECK_EQ(42, captures[0]); |
| 720 } | 720 } |
| 721 | 721 |
| 722 | 722 |
| 723 IA32TEST(MacroAssemblerIA32Success) { |
| 724 typedef bool (*AsciiTest) ( |
| 725 SeqAsciiString** base, int start_index, int end_index, int* captures); |
| 726 |
| 727 V8::Initialize(NULL); |
| 728 |
| 729 // regexp-macro-assembler-ia32 needs a handle scope to allocate |
| 730 // byte-arrays for constants. |
| 731 v8::HandleScope scope; |
| 732 |
| 733 RegExpMacroAssemblerIA32 m(RegExpMacroAssemblerIA32::ASCII, 4, false); |
| 734 |
| 735 m.Succeed(); |
| 736 |
| 737 Handle<Object> code_object = m.GetCode(); |
| 738 Handle<Code> code = Handle<Code>::cast(code_object); |
| 739 AsciiTest test = FUNCTION_CAST<AsciiTest>(code->entry()); |
| 740 |
| 741 int captures[4] = {42, 37, 87, 117}; |
| 742 Handle<String> input = Factory::NewStringFromAscii(CStrVector("foofoo")); |
| 743 Handle<SeqAsciiString> seq_input = Handle<SeqAsciiString>::cast(input); |
| 744 Address start_adr = seq_input->GetCharsAddress(); |
| 745 int start_offset = start_adr - reinterpret_cast<Address>(*seq_input); |
| 746 int end_offset = start_offset + seq_input->length(); |
| 747 |
| 748 bool success = |
| 749 test(seq_input.location(), start_offset, end_offset, captures); |
| 750 |
| 751 CHECK(success); |
| 752 CHECK_EQ(-1, captures[0]); |
| 753 CHECK_EQ(-1, captures[1]); |
| 754 CHECK_EQ(-1, captures[2]); |
| 755 CHECK_EQ(-1, captures[3]); |
| 756 } |
| 757 |
| 758 |
| 759 IA32TEST(MacroAssemblerIA32Simple) { |
| 760 typedef bool (*AsciiTest) ( |
| 761 SeqAsciiString** base, int start_index, int end_index, int* captures); |
| 762 |
| 763 V8::Initialize(NULL); |
| 764 |
| 765 // regexp-macro-assembler-ia32 needs a handle scope to allocate |
| 766 // byte-arrays for constants. |
| 767 v8::HandleScope scope; |
| 768 |
| 769 RegExpMacroAssemblerIA32 m(RegExpMacroAssemblerIA32::ASCII, 4, false); |
| 770 |
| 771 uc16 foo_chars[3] = {'f', 'o', 'o'}; |
| 772 Vector<const uc16> foo(foo_chars, 3); |
| 773 |
| 774 Label fail; |
| 775 m.CheckCharacters(foo, 0, &fail); |
| 776 m.WriteCurrentPositionToRegister(0); |
| 777 m.AdvanceCurrentPosition(3); |
| 778 m.WriteCurrentPositionToRegister(1); |
| 779 m.Succeed(); |
| 780 m.Bind(&fail); |
| 781 m.Fail(); |
| 782 |
| 783 Handle<Object> code_object = m.GetCode(); |
| 784 Handle<Code> code = Handle<Code>::cast(code_object); |
| 785 AsciiTest test = FUNCTION_CAST<AsciiTest>(code->entry()); |
| 786 |
| 787 int captures[4] = {42, 37, 87, 117}; |
| 788 Handle<String> input = Factory::NewStringFromAscii(CStrVector("foofoo")); |
| 789 Handle<SeqAsciiString> seq_input = Handle<SeqAsciiString>::cast(input); |
| 790 Address start_adr = seq_input->GetCharsAddress(); |
| 791 int start_offset = start_adr - reinterpret_cast<Address>(*seq_input); |
| 792 int end_offset = start_offset + seq_input->length(); |
| 793 |
| 794 bool success = |
| 795 test(seq_input.location(), start_offset, end_offset, captures); |
| 796 |
| 797 CHECK(success); |
| 798 CHECK_EQ(0, captures[0]); |
| 799 CHECK_EQ(3, captures[1]); |
| 800 CHECK_EQ(-1, captures[2]); |
| 801 CHECK_EQ(-1, captures[3]); |
| 802 |
| 803 input = Factory::NewStringFromAscii(CStrVector("barbarbar")); |
| 804 seq_input = Handle<SeqAsciiString>::cast(input); |
| 805 start_adr = seq_input->GetCharsAddress(); |
| 806 start_offset = start_adr - reinterpret_cast<Address>(*seq_input); |
| 807 end_offset = start_offset + seq_input->length(); |
| 808 |
| 809 success = test(seq_input.location(), start_offset, end_offset, captures); |
| 810 |
| 811 CHECK(!success); |
| 812 } |
| 813 |
| 814 |
| 815 IA32TEST(MacroAssemblerIA32Backtrack) { |
| 816 typedef bool (*AsciiTest) ( |
| 817 SeqAsciiString** base, int start_index, int end_index, int* captures); |
| 818 |
| 819 V8::Initialize(NULL); |
| 820 |
| 821 // regexp-macro-assembler-ia32 needs a handle scope to allocate |
| 822 // byte-arrays for constants. |
| 823 v8::HandleScope scope; |
| 824 |
| 825 RegExpMacroAssemblerIA32 m(RegExpMacroAssemblerIA32::ASCII, 0, false); |
| 826 |
| 827 uc16 foo_chars[3] = {'f', 'o', 'o'}; |
| 828 Vector<const uc16> foo(foo_chars, 3); |
| 829 |
| 830 Label fail; |
| 831 Label backtrack; |
| 832 m.LoadCurrentCharacter(10, &fail); |
| 833 m.Succeed(); |
| 834 m.Bind(&fail); |
| 835 m.PushBacktrack(&backtrack); |
| 836 m.LoadCurrentCharacter(10, NULL); |
| 837 m.Succeed(); |
| 838 m.Bind(&backtrack); |
| 839 m.Fail(); |
| 840 |
| 841 Handle<Object> code_object = m.GetCode(); |
| 842 Handle<Code> code = Handle<Code>::cast(code_object); |
| 843 AsciiTest test = FUNCTION_CAST<AsciiTest>(code->entry()); |
| 844 |
| 845 Handle<String> input = Factory::NewStringFromAscii(CStrVector("foofoo")); |
| 846 Handle<SeqAsciiString> seq_input = Handle<SeqAsciiString>::cast(input); |
| 847 Address start_adr = seq_input->GetCharsAddress(); |
| 848 int start_offset = start_adr - reinterpret_cast<Address>(*seq_input); |
| 849 int end_offset = start_offset + seq_input->length(); |
| 850 |
| 851 bool success = |
| 852 test(seq_input.location(), start_offset, end_offset, NULL); |
| 853 |
| 854 CHECK(!success); |
| 855 } |
| 856 |
| 857 |
| 858 IA32TEST(MacroAssemblerIA32Registers) { |
| 859 typedef bool (*AsciiTest) ( |
| 860 SeqAsciiString** base, int start_index, int end_index, int* captures); |
| 861 |
| 862 V8::Initialize(NULL); |
| 863 |
| 864 // regexp-macro-assembler-ia32 needs a handle scope to allocate |
| 865 // byte-arrays for constants. |
| 866 v8::HandleScope scope; |
| 867 |
| 868 RegExpMacroAssemblerIA32 m(RegExpMacroAssemblerIA32::ASCII, 5, false); |
| 869 |
| 870 uc16 foo_chars[3] = {'f', 'o', 'o'}; |
| 871 Vector<const uc16> foo(foo_chars, 3); |
| 872 |
| 873 enum registers { out1, out2, out3, out4, out5, sp, loop_cnt }; |
| 874 Label fail; |
| 875 Label backtrack; |
| 876 m.WriteCurrentPositionToRegister(out1); // Output: [0] |
| 877 m.PushRegister(out1); |
| 878 m.PushBacktrack(&backtrack); |
| 879 m.WriteStackPointerToRegister(sp); |
| 880 // Fill stack and registers |
| 881 m.AdvanceCurrentPosition(2); |
| 882 m.WriteCurrentPositionToRegister(out1); |
| 883 m.PushRegister(out1); |
| 884 m.PushBacktrack(&fail); |
| 885 // Drop backtrack stack frames. |
| 886 m.ReadStackPointerFromRegister(sp); |
| 887 // And take the first backtrack (to &backtrack) |
| 888 m.Backtrack(); |
| 889 |
| 890 m.PushCurrentPosition(); |
| 891 m.AdvanceCurrentPosition(2); |
| 892 m.PopCurrentPosition(); |
| 893 |
| 894 m.Bind(&backtrack); |
| 895 m.PopRegister(out1); |
| 896 m.ReadCurrentPositionFromRegister(out1); |
| 897 m.AdvanceCurrentPosition(3); |
| 898 m.WriteCurrentPositionToRegister(out2); // [0,3] |
| 899 |
| 900 Label loop; |
| 901 m.SetRegister(loop_cnt, 0); // loop counter |
| 902 m.Bind(&loop); |
| 903 m.AdvanceRegister(loop_cnt, 1); |
| 904 m.AdvanceCurrentPosition(1); |
| 905 m.IfRegisterLT(loop_cnt, 3, &loop); |
| 906 m.WriteCurrentPositionToRegister(out3); // [0,3,6] |
| 907 |
| 908 Label loop2; |
| 909 m.SetRegister(loop_cnt, 2); // loop counter |
| 910 m.Bind(&loop2); |
| 911 m.AdvanceRegister(loop_cnt, -1); |
| 912 m.AdvanceCurrentPosition(1); |
| 913 m.IfRegisterGE(loop_cnt, 0, &loop2); |
| 914 m.WriteCurrentPositionToRegister(out4); // [0,3,6,9] |
| 915 |
| 916 Label loop3; |
| 917 Label exit_loop3; |
| 918 m.ReadCurrentPositionFromRegister(out3); |
| 919 m.Bind(&loop3); |
| 920 m.AdvanceCurrentPosition(1); |
| 921 m.CheckCurrentPosition(out4, &exit_loop3); |
| 922 m.GoTo(&loop3); |
| 923 m.Bind(&exit_loop3); |
| 924 m.WriteCurrentPositionToRegister(out5); // [0,3,6,9,9] |
| 925 |
| 926 m.Succeed(); |
| 927 |
| 928 m.Bind(&fail); |
| 929 m.Fail(); |
| 930 |
| 931 Handle<Object> code_object = m.GetCode(); |
| 932 Handle<Code> code = Handle<Code>::cast(code_object); |
| 933 AsciiTest test = FUNCTION_CAST<AsciiTest>(code->entry()); |
| 934 |
| 935 // String long enough for test (content doesn't matter). |
| 936 Handle<String> input = |
| 937 Factory::NewStringFromAscii(CStrVector("foofoofoofoofoo")); |
| 938 Handle<SeqAsciiString> seq_input = Handle<SeqAsciiString>::cast(input); |
| 939 Address start_adr = seq_input->GetCharsAddress(); |
| 940 int start_offset = start_adr - reinterpret_cast<Address>(*seq_input); |
| 941 int end_offset = start_offset + seq_input->length(); |
| 942 |
| 943 int output[5]; |
| 944 bool success = |
| 945 test(seq_input.location(), start_offset, end_offset, output); |
| 946 |
| 947 CHECK(success); |
| 948 CHECK_EQ(0, output[0]); |
| 949 CHECK_EQ(3, output[1]); |
| 950 CHECK_EQ(6, output[2]); |
| 951 CHECK_EQ(9, output[3]); |
| 952 CHECK_EQ(9, output[4]); |
| 953 } |
| 954 |
| 955 |
| 723 TEST(AddInverseToTable) { | 956 TEST(AddInverseToTable) { |
| 724 static const int kLimit = 1000; | 957 static const int kLimit = 1000; |
| 725 static const int kRangeCount = 16; | 958 static const int kRangeCount = 16; |
| 726 for (int t = 0; t < 10; t++) { | 959 for (int t = 0; t < 10; t++) { |
| 727 ZoneScope zone_scope(DELETE_ON_EXIT); | 960 ZoneScope zone_scope(DELETE_ON_EXIT); |
| 728 ZoneList<CharacterRange>* ranges = | 961 ZoneList<CharacterRange>* ranges = |
| 729 new ZoneList<CharacterRange>(kRangeCount); | 962 new ZoneList<CharacterRange>(kRangeCount); |
| 730 for (int i = 0; i < kRangeCount; i++) { | 963 for (int i = 0; i < kRangeCount; i++) { |
| 731 int from = PseudoRandom(t + 87, i + 25) % kLimit; | 964 int from = PseudoRandom(t + 87, i + 25) % kLimit; |
| 732 int to = from + (PseudoRandom(i + 87, t + 25) % (kLimit / 20)); | 965 int to = from + (PseudoRandom(i + 87, t + 25) % (kLimit / 20)); |
| (...skipping 180 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 913 // whole block at a time. | 1146 // whole block at a time. |
| 914 TestSimpleRangeCaseIndependence(CharacterRange('A', 'k'), | 1147 TestSimpleRangeCaseIndependence(CharacterRange('A', 'k'), |
| 915 CharacterRange('a', 'z')); | 1148 CharacterRange('a', 'z')); |
| 916 } | 1149 } |
| 917 | 1150 |
| 918 | 1151 |
| 919 TEST(Graph) { | 1152 TEST(Graph) { |
| 920 V8::Initialize(NULL); | 1153 V8::Initialize(NULL); |
| 921 Execute("(x)?\\1y", "", true); | 1154 Execute("(x)?\\1y", "", true); |
| 922 } | 1155 } |
| OLD | NEW |