Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(114)

Side by Side Diff: test/cctest/test-api.cc

Issue 10828229: Add basic support for Latin1 strings to the API. (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Created 8 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« src/parser.cc ('K') | « src/parser.cc ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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
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
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 }
OLDNEW
« src/parser.cc ('K') | « src/parser.cc ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698