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