OLD | NEW |
1 // Copyright 2012 the V8 project authors. All rights reserved. | 1 // Copyright 2012 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 696 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
707 HEAP->CollectAllAvailableGarbage(); | 707 HEAP->CollectAllAvailableGarbage(); |
708 CHECK_EQ(0, TestAsciiResourceWithDisposeControl::dispose_count); | 708 CHECK_EQ(0, TestAsciiResourceWithDisposeControl::dispose_count); |
709 } | 709 } |
710 i::Isolate::Current()->compilation_cache()->Clear(); | 710 i::Isolate::Current()->compilation_cache()->Clear(); |
711 HEAP->CollectAllAvailableGarbage(); | 711 HEAP->CollectAllAvailableGarbage(); |
712 CHECK_EQ(1, TestAsciiResourceWithDisposeControl::dispose_calls); | 712 CHECK_EQ(1, TestAsciiResourceWithDisposeControl::dispose_calls); |
713 CHECK_EQ(1, TestAsciiResourceWithDisposeControl::dispose_count); | 713 CHECK_EQ(1, TestAsciiResourceWithDisposeControl::dispose_count); |
714 } | 714 } |
715 | 715 |
716 | 716 |
717 static void TestNewLatin1String(int encoding1, int encoding2) { | |
718 const char* chars1 = "ASCII 123"; | |
719 const char* chars1js = "'ASCII 123'"; | |
720 int str1_len = static_cast<int>(strlen(chars1)); | |
721 const char* chars2 = "Non-ASCII \xAB\xCD\xEF"; | |
722 const char* chars2js = "'Non-ASCII \\u00ab\\u00cd\\u00ef'"; | |
723 int str2_len = static_cast<int>(strlen(chars2)); | |
724 | |
725 Local<String> str1 = String::New(chars1, str1_len, encoding1); | |
726 Local<String> str2 = String::New(chars2, str2_len, encoding2); | |
727 Local<String> str1_compare = CompileRun(chars1js)->ToString(); | |
728 Local<String> str2_compare = CompileRun(chars2js)->ToString(); | |
729 | |
730 if (encoding1 & String::NOT_ASCII_HINT) { | |
731 CHECK(v8::Utils::OpenHandle(*str1)->IsSeqTwoByteString()); | |
732 } else { | |
733 CHECK(v8::Utils::OpenHandle(*str1)->IsSeqAsciiString()); | |
734 } | |
735 CHECK(v8::Utils::OpenHandle(*str1_compare)->IsSeqAsciiString()); | |
736 CHECK(v8::Utils::OpenHandle(*str2)->IsSeqTwoByteString()); | |
737 CHECK(v8::Utils::OpenHandle(*str2_compare)->IsSeqTwoByteString()); | |
738 | |
739 CHECK(str1_compare->Equals(str1)); | |
740 CHECK(str2_compare->Equals(str2)); | |
741 } | |
742 | |
743 | |
744 TEST(CreateLatin1String) { | |
745 v8::HandleScope scope; | |
746 LocalContext env; | |
747 | |
748 int latin1 = String::LATIN1_ENCODING; | |
749 int l_noascii = String::LATIN1_ENCODING | String::NOT_ASCII_HINT; | |
750 int l_ascii = String::LATIN1_ENCODING | String::ASCII_HINT; | |
751 | |
752 TestNewLatin1String(latin1, latin1); | |
753 TestNewLatin1String(l_ascii, latin1); | |
754 TestNewLatin1String(l_noascii, l_noascii); | |
755 } | |
756 | |
757 | |
758 TEST(ExternalStringEncoding) { | |
759 v8::HandleScope scope; | |
760 LocalContext env; | |
761 int counter = 0; | |
762 | |
763 { HandleScope scope; | |
764 uint16_t* two_byte_ascii = AsciiToTwoByteString("two byte ascii"); | |
765 uint16_t* two_byte = AsciiToTwoByteString("two byte non-ascii \x99"); | |
766 char* ascii = i::StrDup("ascii"); | |
767 | |
768 TestResource* two_byte_resource = new TestResource(two_byte, &counter); | |
769 TestResource* two_byte_ascii_resource = | |
770 new TestResource(two_byte_ascii, &counter); | |
771 TestAsciiResource* ascii_resource = | |
772 new TestAsciiResource(ascii, &counter); | |
773 | |
774 Local<String> two_byte_external = String::NewExternal(two_byte_resource); | |
775 Local<String> two_byte_ascii_external = | |
776 String::NewExternal(two_byte_ascii_resource); | |
777 Local<String> ascii_external = String::NewExternal(ascii_resource); | |
778 Local<String> not_external = v8_str("not external"); | |
779 | |
780 CHECK_EQ(String::UTF_16_ENCODING | String::NOT_ASCII_HINT, | |
781 two_byte_external->GetExternalStringEncoding()); | |
782 CHECK_EQ(String::UTF_16_ENCODING | String::ASCII_HINT, | |
783 two_byte_ascii_external->GetExternalStringEncoding()); | |
784 CHECK_EQ(String::LATIN1_ENCODING | String::ASCII_HINT, | |
785 ascii_external->GetExternalStringEncoding()); | |
786 CHECK_EQ(String::INVALID_ENCODING, | |
787 not_external->GetExternalStringEncoding()); | |
788 | |
789 CHECK_EQ(two_byte_resource, two_byte_external->GetExternalStringResource()); | |
790 CHECK_EQ(two_byte_ascii_resource, | |
791 two_byte_ascii_external->GetExternalStringResourceBase()); | |
792 CHECK_EQ(ascii_resource, ascii_external->GetExternalStringResourceBase()); | |
793 | |
794 CHECK_EQ(0, counter); | |
795 } | |
796 | |
797 HEAP->CollectAllGarbage(i::Heap::kNoGCFlags); | |
798 | |
799 CHECK_EQ(3, counter); | |
800 } | |
801 | |
802 | |
803 TEST(WriteLatin1String) { | |
804 HandleScope scope; | |
805 LocalContext env; | |
806 const char* latin1_ascii = "latin1 ascii"; | |
807 const char* latin1 = "\x99 latin1 non-ascii \xF8"; | |
808 const char* concat = "latin1 ascii\x99 latin1 non-ascii \xF8"; | |
809 const char* sub = "latin1 non-ascii \xF8"; | |
810 | |
811 Local<String> latin1_ascii_string = String::New(latin1_ascii, | |
812 String::kUndefinedLength, | |
813 String::LATIN1_ENCODING); | |
814 Local<String> latin1_string = String::New(latin1, | |
815 String::kUndefinedLength, | |
816 String::LATIN1_ENCODING); | |
817 Local<String> concat_string = String::Concat(latin1_ascii_string, | |
818 latin1_string); | |
819 Local<String> sub_string = v8::Utils::ToLocal( | |
820 FACTORY->NewSubString( | |
821 v8::Utils::OpenHandle(*latin1_string), 2, latin1_string->Length())); | |
822 | |
823 CHECK(v8::Utils::OpenHandle(*latin1_ascii_string)->IsSeqAsciiString()); | |
824 CHECK(v8::Utils::OpenHandle(*latin1_string)->IsSeqTwoByteString()); | |
825 CHECK(v8::Utils::OpenHandle(*concat_string)->IsConsString()); | |
826 CHECK(v8::Utils::OpenHandle(*sub_string)->IsSlicedString()); | |
827 | |
828 char buffer[64]; | |
829 CHECK_EQ(static_cast<int>(strlen(latin1_ascii)), | |
830 latin1_ascii_string->WriteLatin1(buffer)); | |
831 CHECK_EQ(0, strcmp(latin1_ascii, buffer)); | |
832 CHECK_EQ(static_cast<int>(strlen(latin1)), | |
833 latin1_string->WriteLatin1(buffer)); | |
834 CHECK_EQ(0, strcmp(latin1, buffer)); | |
835 CHECK_EQ(static_cast<int>(strlen(concat)), | |
836 concat_string->WriteLatin1(buffer)); | |
837 CHECK_EQ(0, strcmp(concat, buffer)); | |
838 CHECK_EQ(static_cast<int>(strlen(sub)), | |
839 sub_string->WriteLatin1(buffer)); | |
840 CHECK_EQ(0, strcmp(sub, buffer)); | |
841 | |
842 memset(buffer, 0x1, sizeof(buffer)); | |
843 CHECK_EQ(static_cast<int>(strlen(latin1)), | |
844 latin1_string->WriteLatin1(buffer, | |
845 0, | |
846 String::kUndefinedLength, | |
847 String::NO_NULL_TERMINATION)); | |
848 CHECK_EQ(0, strncmp(latin1, buffer, strlen(latin1))); | |
849 CHECK_NE(0, strcmp(latin1, buffer)); | |
850 buffer[strlen(latin1)] = '\0'; | |
851 CHECK_EQ(0, strcmp(latin1, buffer)); | |
852 | |
853 CHECK_EQ(static_cast<int>(strlen(latin1)) - 2, | |
854 latin1_string->WriteLatin1(buffer, 2)); | |
855 CHECK_EQ(0, strncmp(latin1 + 2, buffer, strlen(latin1))); | |
856 } | |
857 | |
858 | |
859 class TestLatin1Resource: public String::ExternalLatin1StringResource { | |
860 public: | |
861 explicit TestLatin1Resource(const char* data, int* counter = NULL) | |
862 : data_(data), length_(strlen(data)), counter_(counter) { } | |
863 | |
864 ~TestLatin1Resource() { | |
865 i::DeleteArray(data_); | |
866 if (counter_ != NULL) ++*counter_; | |
867 } | |
868 | |
869 const char* data() const { | |
870 return data_; | |
871 } | |
872 | |
873 size_t length() const { | |
874 return length_; | |
875 } | |
876 private: | |
877 const char* data_; | |
878 size_t length_; | |
879 int* counter_; | |
880 }; | |
881 | |
882 | |
883 TEST(ExternalLatin1String) { | |
884 HandleScope scope; | |
885 LocalContext env; | |
886 int counter = 0; | |
887 | |
888 { HandleScope scope; | |
889 char* latin1_ascii_a = i::StrDup("latin1 ascii a"); | |
890 char* latin1_ascii_b = i::StrDup("latin1 ascii b"); | |
891 char* latin1_a = i::StrDup("latin non-ascii \xAA"); | |
892 char* latin1_b = i::StrDup("latin non-ascii \xBB"); | |
893 | |
894 TestLatin1Resource* latin1_ascii_a_resource = | |
895 new TestLatin1Resource(latin1_ascii_a, &counter); | |
896 TestLatin1Resource* latin1_ascii_b_resource = | |
897 new TestLatin1Resource(latin1_ascii_b, &counter); | |
898 TestLatin1Resource* latin1_a_resource = | |
899 new TestLatin1Resource(latin1_a, &counter); | |
900 TestLatin1Resource* latin1_b_resource = | |
901 new TestLatin1Resource(latin1_b, &counter); | |
902 | |
903 Local<String> latin1_ascii_a_external = | |
904 String::NewExternal(latin1_ascii_a_resource); | |
905 Local<String> latin1_ascii_b_external = String::NewExternal( | |
906 latin1_ascii_b_resource, | |
907 String::LATIN1_ENCODING | String::ASCII_HINT); | |
908 CHECK_EQ(0, counter); | |
909 | |
910 // Non-ascii latin1 strings are internalized immediately as two-byte | |
911 // string and the external resource is disposed. | |
912 Local<String> latin1_a_external = String::NewExternal(latin1_a_resource); | |
913 Local<String> latin1_b_external = String::NewExternal( | |
914 latin1_b_resource, String::LATIN1_ENCODING | String::NOT_ASCII_HINT); | |
915 CHECK(v8::Utils::OpenHandle(*latin1_a_external)->IsSeqTwoByteString()); | |
916 CHECK(v8::Utils::OpenHandle(*latin1_b_external)->IsSeqTwoByteString()); | |
917 CHECK_EQ(2, counter); | |
918 | |
919 CHECK_EQ(latin1_ascii_a_external->GetExternalStringEncoding(), | |
920 (v8::String::LATIN1_ENCODING | v8::String::ASCII_HINT)); | |
921 CHECK_EQ(latin1_ascii_b_external->GetExternalStringEncoding(), | |
922 (v8::String::LATIN1_ENCODING | v8::String::ASCII_HINT)); | |
923 CHECK_EQ(latin1_a_external->GetExternalStringEncoding(), | |
924 v8::String::INVALID_ENCODING); | |
925 CHECK_EQ(latin1_b_external->GetExternalStringEncoding(), | |
926 v8::String::INVALID_ENCODING); | |
927 | |
928 CHECK_EQ(latin1_ascii_a_resource, | |
929 latin1_ascii_a_external->GetExternalStringResourceBase()); | |
930 CHECK_EQ(latin1_ascii_b_resource, | |
931 latin1_ascii_b_external->GetExternalStringResourceBase()); | |
932 } | |
933 | |
934 HEAP->CollectAllGarbage(i::Heap::kNoGCFlags); | |
935 CHECK_EQ(4, counter); | |
936 } | |
937 | |
938 | |
939 TEST(ExternalizeLatin1String) { | |
940 HandleScope scope; | |
941 LocalContext env; | |
942 int counter = 0; | |
943 | |
944 { HandleScope scope; | |
945 Local<String> latin1_a_ascii = String::New("latin1 a ascii"); | |
946 Local<String> latin1_b_ascii = String::New("latin1 b ascii"); | |
947 Local<String> latin1 = String::New("latin1 non-ascii \xAA", | |
948 String::kUndefinedLength, | |
949 String::LATIN1_ENCODING); | |
950 | |
951 CHECK(v8::Utils::OpenHandle(*latin1_a_ascii)->IsSeqAsciiString()); | |
952 CHECK(v8::Utils::OpenHandle(*latin1_b_ascii)->IsSeqAsciiString()); | |
953 CHECK(v8::Utils::OpenHandle(*latin1)->IsSeqTwoByteString()); | |
954 | |
955 // Run GC twice to put those strings into old space for externalizing. | |
956 HEAP->CollectGarbage(i::NEW_SPACE); | |
957 HEAP->CollectGarbage(i::NEW_SPACE); | |
958 | |
959 char* latin1_a_ascii_chars = i::NewArray<char>(64); | |
960 uint16_t* latin1_b_ascii_chars = i::NewArray<uint16_t>(64); | |
961 uint16_t* latin1_chars = i::NewArray<uint16_t>(64); | |
962 | |
963 latin1_a_ascii->WriteLatin1(latin1_a_ascii_chars); | |
964 latin1_b_ascii->Write(latin1_b_ascii_chars); | |
965 latin1->Write(latin1_chars); | |
966 | |
967 TestLatin1Resource* latin1_a_ascii_resource = | |
968 new TestLatin1Resource(latin1_a_ascii_chars, &counter); | |
969 TestResource* latin1_b_ascii_resource = | |
970 new TestResource(latin1_b_ascii_chars, &counter); | |
971 TestResource* latin1_resource = | |
972 new TestResource(latin1_chars, &counter); | |
973 | |
974 CHECK(latin1_a_ascii->MakeExternal(latin1_a_ascii_resource)); | |
975 CHECK(latin1_a_ascii->IsExternalAscii()); | |
976 CHECK_EQ(latin1_a_ascii->GetExternalStringEncoding(), | |
977 (v8::String::LATIN1_ENCODING | v8::String::ASCII_HINT)); | |
978 CHECK_EQ(latin1_a_ascii_resource, | |
979 latin1_a_ascii->GetExternalStringResourceBase()); | |
980 CHECK(latin1_a_ascii->Equals(String::New("latin1 a ascii"))); | |
981 | |
982 CHECK(latin1_b_ascii->MakeExternal(latin1_b_ascii_resource)); | |
983 CHECK(latin1_b_ascii->IsExternal()); | |
984 CHECK_EQ(latin1_b_ascii->GetExternalStringEncoding(), | |
985 (v8::String::UTF_16_ENCODING | v8::String::ASCII_HINT)); | |
986 CHECK_EQ(latin1_b_ascii_resource, | |
987 latin1_b_ascii->GetExternalStringResourceBase()); | |
988 CHECK(latin1_b_ascii->Equals(String::New("latin1 b ascii"))); | |
989 | |
990 CHECK(latin1->MakeExternal(latin1_resource)); | |
991 CHECK(latin1->IsExternal()); | |
992 CHECK_EQ(latin1->GetExternalStringEncoding(), | |
993 (v8::String::UTF_16_ENCODING | v8::String::NOT_ASCII_HINT)); | |
994 CHECK_EQ(latin1_resource, | |
995 latin1->GetExternalStringResourceBase()); | |
996 CHECK(latin1->Equals(String::New("latin1 non-ascii \xAA", | |
997 String::kUndefinedLength, | |
998 String::LATIN1_ENCODING))); | |
999 } | |
1000 | |
1001 HEAP->CollectAllGarbage(i::Heap::kNoGCFlags); | |
1002 CHECK_EQ(3, counter); | |
1003 } | |
1004 | |
1005 | |
1006 THREADED_TEST(StringConcat) { | 717 THREADED_TEST(StringConcat) { |
1007 { | 718 { |
1008 HandleScope scope; | 719 v8::HandleScope scope; |
1009 LocalContext env; | 720 LocalContext env; |
1010 const char* one_byte_string_1 = "function a_times_t"; | 721 const char* one_byte_string_1 = "function a_times_t"; |
1011 const char* two_byte_string_1 = "wo_plus_b(a, b) {return "; | 722 const char* two_byte_string_1 = "wo_plus_b(a, b) {return "; |
1012 const char* one_byte_extern_1 = "a * 2 + b;} a_times_two_plus_b(4, 8) + "; | 723 const char* one_byte_extern_1 = "a * 2 + b;} a_times_two_plus_b(4, 8) + "; |
1013 const char* two_byte_extern_1 = "a_times_two_plus_b(4, 8) + "; | 724 const char* two_byte_extern_1 = "a_times_two_plus_b(4, 8) + "; |
1014 const char* one_byte_string_2 = "a_times_two_plus_b(4, 8) + "; | 725 const char* one_byte_string_2 = "a_times_two_plus_b(4, 8) + "; |
1015 const char* two_byte_string_2 = "a_times_two_plus_b(4, 8) + "; | 726 const char* two_byte_string_2 = "a_times_two_plus_b(4, 8) + "; |
1016 const char* two_byte_extern_2 = "a_times_two_plus_b(1, 2);"; | 727 const char* two_byte_extern_2 = "a_times_two_plus_b(1, 2);"; |
1017 Local<String> left = v8_str(one_byte_string_1); | 728 Local<String> left = v8_str(one_byte_string_1); |
1018 | 729 |
(...skipping 16707 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
17726 | 17437 |
17727 i::Semaphore* sem_; | 17438 i::Semaphore* sem_; |
17728 volatile int sem_value_; | 17439 volatile int sem_value_; |
17729 }; | 17440 }; |
17730 | 17441 |
17731 | 17442 |
17732 THREADED_TEST(SemaphoreInterruption) { | 17443 THREADED_TEST(SemaphoreInterruption) { |
17733 ThreadInterruptTest().RunTest(); | 17444 ThreadInterruptTest().RunTest(); |
17734 } | 17445 } |
17735 #endif // WIN32 | 17446 #endif // WIN32 |
OLD | NEW |