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 94 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
105 ~Resource() { i::DeleteArray(data_); } | 105 ~Resource() { i::DeleteArray(data_); } |
106 virtual const uint16_t* data() const { return data_; } | 106 virtual const uint16_t* data() const { return data_; } |
107 virtual size_t length() const { return length_; } | 107 virtual size_t length() const { return length_; } |
108 | 108 |
109 private: | 109 private: |
110 const uc16* data_; | 110 const uc16* data_; |
111 size_t length_; | 111 size_t length_; |
112 }; | 112 }; |
113 | 113 |
114 | 114 |
115 class AsciiResource: public v8::String::ExternalAsciiStringResource { | 115 class OneByteResource : public v8::String::ExternalOneByteStringResource { |
116 public: | 116 public: |
117 AsciiResource(const char* data, size_t length) | 117 OneByteResource(const char* data, size_t length) |
118 : data_(data), length_(length) {} | 118 : data_(data), length_(length) {} |
119 ~AsciiResource() { i::DeleteArray(data_); } | 119 ~OneByteResource() { i::DeleteArray(data_); } |
120 virtual const char* data() const { return data_; } | 120 virtual const char* data() const { return data_; } |
121 virtual size_t length() const { return length_; } | 121 virtual size_t length() const { return length_; } |
122 | 122 |
123 private: | 123 private: |
124 const char* data_; | 124 const char* data_; |
125 size_t length_; | 125 size_t length_; |
126 }; | 126 }; |
127 | 127 |
128 | 128 |
129 static void InitializeBuildingBlocks(Handle<String>* building_blocks, | 129 static void InitializeBuildingBlocks(Handle<String>* building_blocks, |
(...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
195 for (int j = 0; j < len; j++) { | 195 for (int j = 0; j < len; j++) { |
196 CHECK_EQ(buf[j], building_blocks[i]->Get(j)); | 196 CHECK_EQ(buf[j], building_blocks[i]->Get(j)); |
197 } | 197 } |
198 break; | 198 break; |
199 } | 199 } |
200 case 3: { | 200 case 3: { |
201 char* buf = NewArray<char>(len); | 201 char* buf = NewArray<char>(len); |
202 for (int j = 0; j < len; j++) { | 202 for (int j = 0; j < len; j++) { |
203 buf[j] = rng->next(0x80); | 203 buf[j] = rng->next(0x80); |
204 } | 204 } |
205 AsciiResource* resource = new AsciiResource(buf, len); | 205 OneByteResource* resource = new OneByteResource(buf, len); |
206 building_blocks[i] = | 206 building_blocks[i] = |
207 v8::Utils::OpenHandle( | 207 v8::Utils::OpenHandle( |
208 *v8::String::NewExternal(CcTest::isolate(), resource)); | 208 *v8::String::NewExternal(CcTest::isolate(), resource)); |
209 for (int j = 0; j < len; j++) { | 209 for (int j = 0; j < len; j++) { |
210 CHECK_EQ(buf[j], building_blocks[i]->Get(j)); | 210 CHECK_EQ(buf[j], building_blocks[i]->Get(j)); |
211 } | 211 } |
212 break; | 212 break; |
213 } | 213 } |
214 } | 214 } |
215 for (int j = slice_depth; j > 0; j--) { | 215 for (int j = slice_depth; j > 0; j--) { |
(...skipping 231 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
447 CHECK(root->IsConsString() && root->IsFlat()); | 447 CHECK(root->IsConsString() && root->IsFlat()); |
448 } | 448 } |
449 return root; | 449 return root; |
450 } | 450 } |
451 | 451 |
452 | 452 |
453 static Handle<String> ConstructLeft( | 453 static Handle<String> ConstructLeft( |
454 ConsStringGenerationData* data, | 454 ConsStringGenerationData* data, |
455 int depth) { | 455 int depth) { |
456 Factory* factory = CcTest::i_isolate()->factory(); | 456 Factory* factory = CcTest::i_isolate()->factory(); |
457 Handle<String> answer = factory->NewStringFromStaticAscii(""); | 457 Handle<String> answer = factory->NewStringFromStaticChars(""); |
458 data->stats_.leaves_++; | 458 data->stats_.leaves_++; |
459 for (int i = 0; i < depth; i++) { | 459 for (int i = 0; i < depth; i++) { |
460 Handle<String> block = data->block(i); | 460 Handle<String> block = data->block(i); |
461 Handle<String> next = | 461 Handle<String> next = |
462 factory->NewConsString(answer, block).ToHandleChecked(); | 462 factory->NewConsString(answer, block).ToHandleChecked(); |
463 if (next->IsConsString()) data->stats_.leaves_++; | 463 if (next->IsConsString()) data->stats_.leaves_++; |
464 data->stats_.chars_ += block->length(); | 464 data->stats_.chars_ += block->length(); |
465 answer = next; | 465 answer = next; |
466 } | 466 } |
467 data->stats_.left_traversals_ = data->stats_.leaves_ - 2; | 467 data->stats_.left_traversals_ = data->stats_.leaves_ - 2; |
468 return answer; | 468 return answer; |
469 } | 469 } |
470 | 470 |
471 | 471 |
472 static Handle<String> ConstructRight( | 472 static Handle<String> ConstructRight( |
473 ConsStringGenerationData* data, | 473 ConsStringGenerationData* data, |
474 int depth) { | 474 int depth) { |
475 Factory* factory = CcTest::i_isolate()->factory(); | 475 Factory* factory = CcTest::i_isolate()->factory(); |
476 Handle<String> answer = factory->NewStringFromStaticAscii(""); | 476 Handle<String> answer = factory->NewStringFromStaticChars(""); |
477 data->stats_.leaves_++; | 477 data->stats_.leaves_++; |
478 for (int i = depth - 1; i >= 0; i--) { | 478 for (int i = depth - 1; i >= 0; i--) { |
479 Handle<String> block = data->block(i); | 479 Handle<String> block = data->block(i); |
480 Handle<String> next = | 480 Handle<String> next = |
481 factory->NewConsString(block, answer).ToHandleChecked(); | 481 factory->NewConsString(block, answer).ToHandleChecked(); |
482 if (next->IsConsString()) data->stats_.leaves_++; | 482 if (next->IsConsString()) data->stats_.leaves_++; |
483 data->stats_.chars_ += block->length(); | 483 data->stats_.chars_ += block->length(); |
484 answer = next; | 484 answer = next; |
485 } | 485 } |
486 data->stats_.right_traversals_ = data->stats_.leaves_ - 2; | 486 data->stats_.right_traversals_ = data->stats_.leaves_ - 2; |
(...skipping 354 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
841 return ConstructRandomString(data, 200); | 841 return ConstructRandomString(data, 200); |
842 } | 842 } |
843 | 843 |
844 | 844 |
845 TEST(StringCharacterStreamRandom) { | 845 TEST(StringCharacterStreamRandom) { |
846 printf("StringCharacterStreamRandom\n"); | 846 printf("StringCharacterStreamRandom\n"); |
847 TestStringCharacterStream(BuildRandomConsString, kUniqueRandomParameters*7); | 847 TestStringCharacterStream(BuildRandomConsString, kUniqueRandomParameters*7); |
848 } | 848 } |
849 | 849 |
850 | 850 |
851 static const int DEEP_ASCII_DEPTH = 100000; | 851 static const int kDeepOneByteDepth = 100000; |
852 | 852 |
853 | 853 |
854 TEST(DeepAscii) { | 854 TEST(DeepOneByte) { |
855 printf("TestDeepAscii\n"); | |
856 CcTest::InitializeVM(); | 855 CcTest::InitializeVM(); |
857 Factory* factory = CcTest::i_isolate()->factory(); | 856 Factory* factory = CcTest::i_isolate()->factory(); |
858 v8::HandleScope scope(CcTest::isolate()); | 857 v8::HandleScope scope(CcTest::isolate()); |
859 | 858 |
860 char* foo = NewArray<char>(DEEP_ASCII_DEPTH); | 859 char* foo = NewArray<char>(kDeepOneByteDepth); |
861 for (int i = 0; i < DEEP_ASCII_DEPTH; i++) { | 860 for (int i = 0; i < kDeepOneByteDepth; i++) { |
862 foo[i] = "foo "[i % 4]; | 861 foo[i] = "foo "[i % 4]; |
863 } | 862 } |
864 Handle<String> string = factory->NewStringFromOneByte( | 863 Handle<String> string = |
865 OneByteVector(foo, DEEP_ASCII_DEPTH)).ToHandleChecked(); | 864 factory->NewStringFromOneByte(OneByteVector(foo, kDeepOneByteDepth)) |
866 Handle<String> foo_string = factory->NewStringFromStaticAscii("foo"); | 865 .ToHandleChecked(); |
867 for (int i = 0; i < DEEP_ASCII_DEPTH; i += 10) { | 866 Handle<String> foo_string = factory->NewStringFromStaticChars("foo"); |
| 867 for (int i = 0; i < kDeepOneByteDepth; i += 10) { |
868 string = factory->NewConsString(string, foo_string).ToHandleChecked(); | 868 string = factory->NewConsString(string, foo_string).ToHandleChecked(); |
869 } | 869 } |
870 Handle<String> flat_string = | 870 Handle<String> flat_string = |
871 factory->NewConsString(string, foo_string).ToHandleChecked(); | 871 factory->NewConsString(string, foo_string).ToHandleChecked(); |
872 String::Flatten(flat_string); | 872 String::Flatten(flat_string); |
873 | 873 |
874 for (int i = 0; i < 500; i++) { | 874 for (int i = 0; i < 500; i++) { |
875 TraverseFirst(flat_string, string, DEEP_ASCII_DEPTH); | 875 TraverseFirst(flat_string, string, kDeepOneByteDepth); |
876 } | 876 } |
877 DeleteArray<char>(foo); | 877 DeleteArray<char>(foo); |
878 } | 878 } |
879 | 879 |
880 | 880 |
881 TEST(Utf8Conversion) { | 881 TEST(Utf8Conversion) { |
882 // Smoke test for converting strings to utf-8. | 882 // Smoke test for converting strings to utf-8. |
883 CcTest::InitializeVM(); | 883 CcTest::InitializeVM(); |
884 v8::HandleScope handle_scope(CcTest::isolate()); | 884 v8::HandleScope handle_scope(CcTest::isolate()); |
885 // A simple ascii string | 885 // A simple one-byte string |
886 const char* ascii_string = "abcdef12345"; | 886 const char* one_byte_string = "abcdef12345"; |
887 int len = v8::String::NewFromUtf8(CcTest::isolate(), ascii_string, | 887 int len = v8::String::NewFromUtf8(CcTest::isolate(), one_byte_string, |
888 v8::String::kNormalString, | 888 v8::String::kNormalString, |
889 StrLength(ascii_string))->Utf8Length(); | 889 StrLength(one_byte_string))->Utf8Length(); |
890 CHECK_EQ(StrLength(ascii_string), len); | 890 CHECK_EQ(StrLength(one_byte_string), len); |
891 // A mixed ascii and non-ascii string | 891 // A mixed one-byte and two-byte string |
892 // U+02E4 -> CB A4 | 892 // U+02E4 -> CB A4 |
893 // U+0064 -> 64 | 893 // U+0064 -> 64 |
894 // U+12E4 -> E1 8B A4 | 894 // U+12E4 -> E1 8B A4 |
895 // U+0030 -> 30 | 895 // U+0030 -> 30 |
896 // U+3045 -> E3 81 85 | 896 // U+3045 -> E3 81 85 |
897 const uint16_t mixed_string[] = {0x02E4, 0x0064, 0x12E4, 0x0030, 0x3045}; | 897 const uint16_t mixed_string[] = {0x02E4, 0x0064, 0x12E4, 0x0030, 0x3045}; |
898 // The characters we expect to be output | 898 // The characters we expect to be output |
899 const unsigned char as_utf8[11] = {0xCB, 0xA4, 0x64, 0xE1, 0x8B, 0xA4, 0x30, | 899 const unsigned char as_utf8[11] = {0xCB, 0xA4, 0x64, 0xE1, 0x8B, 0xA4, 0x30, |
900 0xE3, 0x81, 0x85, 0x00}; | 900 0xE3, 0x81, 0x85, 0x00}; |
901 // The number of bytes expected to be written for each length | 901 // The number of bytes expected to be written for each length |
(...skipping 25 matching lines...) Expand all Loading... |
927 | 927 |
928 TEST(ExternalShortStringAdd) { | 928 TEST(ExternalShortStringAdd) { |
929 LocalContext context; | 929 LocalContext context; |
930 v8::HandleScope handle_scope(CcTest::isolate()); | 930 v8::HandleScope handle_scope(CcTest::isolate()); |
931 | 931 |
932 // Make sure we cover all always-flat lengths and at least one above. | 932 // Make sure we cover all always-flat lengths and at least one above. |
933 static const int kMaxLength = 20; | 933 static const int kMaxLength = 20; |
934 CHECK_GT(kMaxLength, i::ConsString::kMinLength); | 934 CHECK_GT(kMaxLength, i::ConsString::kMinLength); |
935 | 935 |
936 // Allocate two JavaScript arrays for holding short strings. | 936 // Allocate two JavaScript arrays for holding short strings. |
937 v8::Handle<v8::Array> ascii_external_strings = | 937 v8::Handle<v8::Array> one_byte_external_strings = |
938 v8::Array::New(CcTest::isolate(), kMaxLength + 1); | 938 v8::Array::New(CcTest::isolate(), kMaxLength + 1); |
939 v8::Handle<v8::Array> non_ascii_external_strings = | 939 v8::Handle<v8::Array> non_one_byte_external_strings = |
940 v8::Array::New(CcTest::isolate(), kMaxLength + 1); | 940 v8::Array::New(CcTest::isolate(), kMaxLength + 1); |
941 | 941 |
942 // Generate short ascii and non-ascii external strings. | 942 // Generate short one-byte and two-byte external strings. |
943 for (int i = 0; i <= kMaxLength; i++) { | 943 for (int i = 0; i <= kMaxLength; i++) { |
944 char* ascii = NewArray<char>(i + 1); | 944 char* one_byte = NewArray<char>(i + 1); |
945 for (int j = 0; j < i; j++) { | 945 for (int j = 0; j < i; j++) { |
946 ascii[j] = 'a'; | 946 one_byte[j] = 'a'; |
947 } | 947 } |
948 // Terminating '\0' is left out on purpose. It is not required for external | 948 // Terminating '\0' is left out on purpose. It is not required for external |
949 // string data. | 949 // string data. |
950 AsciiResource* ascii_resource = new AsciiResource(ascii, i); | 950 OneByteResource* one_byte_resource = new OneByteResource(one_byte, i); |
951 v8::Local<v8::String> ascii_external_string = | 951 v8::Local<v8::String> one_byte_external_string = |
952 v8::String::NewExternal(CcTest::isolate(), ascii_resource); | 952 v8::String::NewExternal(CcTest::isolate(), one_byte_resource); |
953 | 953 |
954 ascii_external_strings->Set(v8::Integer::New(CcTest::isolate(), i), | 954 one_byte_external_strings->Set(v8::Integer::New(CcTest::isolate(), i), |
955 ascii_external_string); | 955 one_byte_external_string); |
956 uc16* non_ascii = NewArray<uc16>(i + 1); | 956 uc16* non_one_byte = NewArray<uc16>(i + 1); |
957 for (int j = 0; j < i; j++) { | 957 for (int j = 0; j < i; j++) { |
958 non_ascii[j] = 0x1234; | 958 non_one_byte[j] = 0x1234; |
959 } | 959 } |
960 // Terminating '\0' is left out on purpose. It is not required for external | 960 // Terminating '\0' is left out on purpose. It is not required for external |
961 // string data. | 961 // string data. |
962 Resource* resource = new Resource(non_ascii, i); | 962 Resource* resource = new Resource(non_one_byte, i); |
963 v8::Local<v8::String> non_ascii_external_string = | 963 v8::Local<v8::String> non_one_byte_external_string = |
964 v8::String::NewExternal(CcTest::isolate(), resource); | 964 v8::String::NewExternal(CcTest::isolate(), resource); |
965 non_ascii_external_strings->Set(v8::Integer::New(CcTest::isolate(), i), | 965 non_one_byte_external_strings->Set(v8::Integer::New(CcTest::isolate(), i), |
966 non_ascii_external_string); | 966 non_one_byte_external_string); |
967 } | 967 } |
968 | 968 |
969 // Add the arrays with the short external strings in the global object. | 969 // Add the arrays with the short external strings in the global object. |
970 v8::Handle<v8::Object> global = context->Global(); | 970 v8::Handle<v8::Object> global = context->Global(); |
971 global->Set(v8_str("external_ascii"), ascii_external_strings); | 971 global->Set(v8_str("external_one_byte"), one_byte_external_strings); |
972 global->Set(v8_str("external_non_ascii"), non_ascii_external_strings); | 972 global->Set(v8_str("external_non_one_byte"), non_one_byte_external_strings); |
973 global->Set(v8_str("max_length"), | 973 global->Set(v8_str("max_length"), |
974 v8::Integer::New(CcTest::isolate(), kMaxLength)); | 974 v8::Integer::New(CcTest::isolate(), kMaxLength)); |
975 | 975 |
976 // Add short external ascii and non-ascii strings checking the result. | 976 // Add short external one-byte and two-byte strings checking the result. |
977 static const char* source = | 977 static const char* source = |
978 "function test() {" | 978 "function test() {" |
979 " var ascii_chars = 'aaaaaaaaaaaaaaaaaaaa';" | 979 " var one_byte_chars = 'aaaaaaaaaaaaaaaaaaaa';" |
980 " var non_ascii_chars = '\\u1234\\u1234\\u1234\\u1234\\u1234\\u1234\\u1234\
\u1234\\u1234\\u1234\\u1234\\u1234\\u1234\\u1234\\u1234\\u1234\\u1234\\u1234\\u1
234\\u1234';" //NOLINT | 980 " var non_one_byte_chars = " |
981 " if (ascii_chars.length != max_length) return 1;" | 981 "'\\u1234\\u1234\\u1234\\u1234\\u1234\\u1234\\u1234\\u1234\\u1234\\u1" |
982 " if (non_ascii_chars.length != max_length) return 2;" | 982 "234\\u1234\\u1234\\u1234\\u1234\\u1234\\u1234\\u1234\\u1234\\u1234\\" |
983 " var ascii = Array(max_length + 1);" | 983 "u1234';" // NOLINT |
984 " var non_ascii = Array(max_length + 1);" | 984 " if (one_byte_chars.length != max_length) return 1;" |
985 " for (var i = 0; i <= max_length; i++) {" | 985 " if (non_one_byte_chars.length != max_length) return 2;" |
986 " ascii[i] = ascii_chars.substring(0, i);" | 986 " var one_byte = Array(max_length + 1);" |
987 " non_ascii[i] = non_ascii_chars.substring(0, i);" | 987 " var non_one_byte = Array(max_length + 1);" |
988 " };" | 988 " for (var i = 0; i <= max_length; i++) {" |
989 " for (var i = 0; i <= max_length; i++) {" | 989 " one_byte[i] = one_byte_chars.substring(0, i);" |
990 " if (ascii[i] != external_ascii[i]) return 3;" | 990 " non_one_byte[i] = non_one_byte_chars.substring(0, i);" |
991 " if (non_ascii[i] != external_non_ascii[i]) return 4;" | 991 " };" |
992 " for (var j = 0; j < i; j++) {" | 992 " for (var i = 0; i <= max_length; i++) {" |
993 " if (external_ascii[i] !=" | 993 " if (one_byte[i] != external_one_byte[i]) return 3;" |
994 " (external_ascii[j] + external_ascii[i - j])) return 5;" | 994 " if (non_one_byte[i] != external_non_one_byte[i]) return 4;" |
995 " if (external_non_ascii[i] !=" | 995 " for (var j = 0; j < i; j++) {" |
996 " (external_non_ascii[j] + external_non_ascii[i - j])) return 6;" | 996 " if (external_one_byte[i] !=" |
997 " if (non_ascii[i] != (non_ascii[j] + non_ascii[i - j])) return 7;" | 997 " (external_one_byte[j] + external_one_byte[i - j])) return " |
998 " if (ascii[i] != (ascii[j] + ascii[i - j])) return 8;" | 998 "5;" |
999 " if (ascii[i] != (external_ascii[j] + ascii[i - j])) return 9;" | 999 " if (external_non_one_byte[i] !=" |
1000 " if (ascii[i] != (ascii[j] + external_ascii[i - j])) return 10;" | 1000 " (external_non_one_byte[j] + external_non_one_byte[i - " |
1001 " if (non_ascii[i] !=" | 1001 "j])) return 6;" |
1002 " (external_non_ascii[j] + non_ascii[i - j])) return 11;" | 1002 " if (non_one_byte[i] != (non_one_byte[j] + non_one_byte[i - " |
1003 " if (non_ascii[i] !=" | 1003 "j])) return 7;" |
1004 " (non_ascii[j] + external_non_ascii[i - j])) return 12;" | 1004 " if (one_byte[i] != (one_byte[j] + one_byte[i - j])) return 8;" |
1005 " }" | 1005 " if (one_byte[i] != (external_one_byte[j] + one_byte[i - j])) " |
1006 " }" | 1006 "return 9;" |
1007 " return 0;" | 1007 " if (one_byte[i] != (one_byte[j] + external_one_byte[i - j])) " |
1008 "};" | 1008 "return 10;" |
1009 "test()"; | 1009 " if (non_one_byte[i] !=" |
| 1010 " (external_non_one_byte[j] + non_one_byte[i - j])) return " |
| 1011 "11;" |
| 1012 " if (non_one_byte[i] !=" |
| 1013 " (non_one_byte[j] + external_non_one_byte[i - j])) return " |
| 1014 "12;" |
| 1015 " }" |
| 1016 " }" |
| 1017 " return 0;" |
| 1018 "};" |
| 1019 "test()"; |
1010 CHECK_EQ(0, CompileRun(source)->Int32Value()); | 1020 CHECK_EQ(0, CompileRun(source)->Int32Value()); |
1011 } | 1021 } |
1012 | 1022 |
1013 | 1023 |
1014 TEST(JSONStringifySliceMadeExternal) { | 1024 TEST(JSONStringifySliceMadeExternal) { |
1015 CcTest::InitializeVM(); | 1025 CcTest::InitializeVM(); |
1016 // Create a sliced string from a one-byte string. The latter is turned | 1026 // Create a sliced string from a one-byte string. The latter is turned |
1017 // into a two-byte external string. Check that JSON.stringify works. | 1027 // into a two-byte external string. Check that JSON.stringify works. |
1018 v8::HandleScope handle_scope(CcTest::isolate()); | 1028 v8::HandleScope handle_scope(CcTest::isolate()); |
1019 v8::Handle<v8::String> underlying = | 1029 v8::Handle<v8::String> underlying = |
(...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1084 } | 1094 } |
1085 } | 1095 } |
1086 | 1096 |
1087 | 1097 |
1088 TEST(SliceFromCons) { | 1098 TEST(SliceFromCons) { |
1089 FLAG_string_slices = true; | 1099 FLAG_string_slices = true; |
1090 CcTest::InitializeVM(); | 1100 CcTest::InitializeVM(); |
1091 Factory* factory = CcTest::i_isolate()->factory(); | 1101 Factory* factory = CcTest::i_isolate()->factory(); |
1092 v8::HandleScope scope(CcTest::isolate()); | 1102 v8::HandleScope scope(CcTest::isolate()); |
1093 Handle<String> string = | 1103 Handle<String> string = |
1094 factory->NewStringFromStaticAscii("parentparentparent"); | 1104 factory->NewStringFromStaticChars("parentparentparent"); |
1095 Handle<String> parent = | 1105 Handle<String> parent = |
1096 factory->NewConsString(string, string).ToHandleChecked(); | 1106 factory->NewConsString(string, string).ToHandleChecked(); |
1097 CHECK(parent->IsConsString()); | 1107 CHECK(parent->IsConsString()); |
1098 CHECK(!parent->IsFlat()); | 1108 CHECK(!parent->IsFlat()); |
1099 Handle<String> slice = factory->NewSubString(parent, 1, 25); | 1109 Handle<String> slice = factory->NewSubString(parent, 1, 25); |
1100 // After slicing, the original string becomes a flat cons. | 1110 // After slicing, the original string becomes a flat cons. |
1101 CHECK(parent->IsFlat()); | 1111 CHECK(parent->IsFlat()); |
1102 CHECK(slice->IsSlicedString()); | 1112 CHECK(slice->IsSlicedString()); |
1103 CHECK_EQ(SlicedString::cast(*slice)->parent(), | 1113 CHECK_EQ(SlicedString::cast(*slice)->parent(), |
1104 // Parent could have been short-circuited. | 1114 // Parent could have been short-circuited. |
1105 parent->IsConsString() ? ConsString::cast(*parent)->first() | 1115 parent->IsConsString() ? ConsString::cast(*parent)->first() |
1106 : *parent); | 1116 : *parent); |
1107 CHECK(SlicedString::cast(*slice)->parent()->IsSeqString()); | 1117 CHECK(SlicedString::cast(*slice)->parent()->IsSeqString()); |
1108 CHECK(slice->IsFlat()); | 1118 CHECK(slice->IsFlat()); |
1109 } | 1119 } |
1110 | 1120 |
1111 | 1121 |
1112 class AsciiVectorResource : public v8::String::ExternalAsciiStringResource { | 1122 class OneByteVectorResource : public v8::String::ExternalOneByteStringResource { |
1113 public: | 1123 public: |
1114 explicit AsciiVectorResource(i::Vector<const char> vector) | 1124 explicit OneByteVectorResource(i::Vector<const char> vector) |
1115 : data_(vector) {} | 1125 : data_(vector) {} |
1116 virtual ~AsciiVectorResource() {} | 1126 virtual ~OneByteVectorResource() {} |
1117 virtual size_t length() const { return data_.length(); } | 1127 virtual size_t length() const { return data_.length(); } |
1118 virtual const char* data() const { return data_.start(); } | 1128 virtual const char* data() const { return data_.start(); } |
1119 private: | 1129 private: |
1120 i::Vector<const char> data_; | 1130 i::Vector<const char> data_; |
1121 }; | 1131 }; |
1122 | 1132 |
1123 | 1133 |
1124 TEST(SliceFromExternal) { | 1134 TEST(SliceFromExternal) { |
1125 FLAG_string_slices = true; | 1135 FLAG_string_slices = true; |
1126 CcTest::InitializeVM(); | 1136 CcTest::InitializeVM(); |
1127 Factory* factory = CcTest::i_isolate()->factory(); | 1137 Factory* factory = CcTest::i_isolate()->factory(); |
1128 v8::HandleScope scope(CcTest::isolate()); | 1138 v8::HandleScope scope(CcTest::isolate()); |
1129 AsciiVectorResource resource( | 1139 OneByteVectorResource resource( |
1130 i::Vector<const char>("abcdefghijklmnopqrstuvwxyz", 26)); | 1140 i::Vector<const char>("abcdefghijklmnopqrstuvwxyz", 26)); |
1131 Handle<String> string = | 1141 Handle<String> string = |
1132 factory->NewExternalStringFromAscii(&resource).ToHandleChecked(); | 1142 factory->NewExternalStringFromOneByte(&resource).ToHandleChecked(); |
1133 CHECK(string->IsExternalString()); | 1143 CHECK(string->IsExternalString()); |
1134 Handle<String> slice = factory->NewSubString(string, 1, 25); | 1144 Handle<String> slice = factory->NewSubString(string, 1, 25); |
1135 CHECK(slice->IsSlicedString()); | 1145 CHECK(slice->IsSlicedString()); |
1136 CHECK(string->IsExternalString()); | 1146 CHECK(string->IsExternalString()); |
1137 CHECK_EQ(SlicedString::cast(*slice)->parent(), *string); | 1147 CHECK_EQ(SlicedString::cast(*slice)->parent(), *string); |
1138 CHECK(SlicedString::cast(*slice)->parent()->IsExternalString()); | 1148 CHECK(SlicedString::cast(*slice)->parent()->IsExternalString()); |
1139 CHECK(slice->IsFlat()); | 1149 CHECK(slice->IsFlat()); |
1140 } | 1150 } |
1141 | 1151 |
1142 | 1152 |
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1192 | 1202 |
1193 result = CompileRun(slice_from_slice); | 1203 result = CompileRun(slice_from_slice); |
1194 CHECK(result->IsString()); | 1204 CHECK(result->IsString()); |
1195 string = v8::Utils::OpenHandle(v8::String::Cast(*result)); | 1205 string = v8::Utils::OpenHandle(v8::String::Cast(*result)); |
1196 CHECK(string->IsSlicedString()); | 1206 CHECK(string->IsSlicedString()); |
1197 CHECK(SlicedString::cast(*string)->parent()->IsSeqString()); | 1207 CHECK(SlicedString::cast(*string)->parent()->IsSeqString()); |
1198 CHECK_EQ("cdefghijklmnopqrstuvwx", string->ToCString().get()); | 1208 CHECK_EQ("cdefghijklmnopqrstuvwx", string->ToCString().get()); |
1199 } | 1209 } |
1200 | 1210 |
1201 | 1211 |
1202 TEST(AsciiArrayJoin) { | 1212 TEST(OneByteArrayJoin) { |
1203 // Set heap limits. | 1213 // Set heap limits. |
1204 v8::ResourceConstraints constraints; | 1214 v8::ResourceConstraints constraints; |
1205 constraints.set_max_semi_space_size(1); | 1215 constraints.set_max_semi_space_size(1); |
1206 constraints.set_max_old_space_size(4); | 1216 constraints.set_max_old_space_size(4); |
1207 v8::SetResourceConstraints(CcTest::isolate(), &constraints); | 1217 v8::SetResourceConstraints(CcTest::isolate(), &constraints); |
1208 | 1218 |
1209 // String s is made of 2^17 = 131072 'c' characters and a is an array | 1219 // String s is made of 2^17 = 131072 'c' characters and a is an array |
1210 // starting with 'bad', followed by 2^14 times the string s. That means the | 1220 // starting with 'bad', followed by 2^14 times the string s. That means the |
1211 // total length of the concatenated strings is 2^31 + 3. So on 32bit systems | 1221 // total length of the concatenated strings is 2^31 + 3. So on 32bit systems |
1212 // summing the lengths of the strings (as Smis) overflows and wraps. | 1222 // summing the lengths of the strings (as Smis) overflows and wraps. |
(...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1274 CompileRun("var slice = long.slice(1, 15);"); | 1284 CompileRun("var slice = long.slice(1, 15);"); |
1275 CheckException("%_SubString(slice, 0, 17);"); | 1285 CheckException("%_SubString(slice, 0, 17);"); |
1276 } | 1286 } |
1277 | 1287 |
1278 | 1288 |
1279 TEST(StringReplaceAtomTwoByteResult) { | 1289 TEST(StringReplaceAtomTwoByteResult) { |
1280 CcTest::InitializeVM(); | 1290 CcTest::InitializeVM(); |
1281 v8::HandleScope scope(CcTest::isolate()); | 1291 v8::HandleScope scope(CcTest::isolate()); |
1282 LocalContext context; | 1292 LocalContext context; |
1283 v8::Local<v8::Value> result = CompileRun( | 1293 v8::Local<v8::Value> result = CompileRun( |
1284 "var subject = 'ascii~only~string~'; " | 1294 "var subject = 'one_byte~only~string~'; " |
1285 "var replace = '\x80'; " | 1295 "var replace = '\x80'; " |
1286 "subject.replace(/~/g, replace); "); | 1296 "subject.replace(/~/g, replace); "); |
1287 CHECK(result->IsString()); | 1297 CHECK(result->IsString()); |
1288 Handle<String> string = v8::Utils::OpenHandle(v8::String::Cast(*result)); | 1298 Handle<String> string = v8::Utils::OpenHandle(v8::String::Cast(*result)); |
1289 CHECK(string->IsSeqTwoByteString()); | 1299 CHECK(string->IsSeqTwoByteString()); |
1290 | 1300 |
1291 v8::Local<v8::String> expected = v8_str("ascii\x80only\x80string\x80"); | 1301 v8::Local<v8::String> expected = v8_str("one_byte\x80only\x80string\x80"); |
1292 CHECK(expected->Equals(result)); | 1302 CHECK(expected->Equals(result)); |
1293 } | 1303 } |
1294 | 1304 |
1295 | 1305 |
1296 TEST(IsAscii) { | 1306 TEST(IsAscii) { |
1297 CHECK(String::IsAscii(static_cast<char*>(NULL), 0)); | 1307 CHECK(String::IsAscii(static_cast<char*>(NULL), 0)); |
1298 CHECK(String::IsOneByte(static_cast<uc16*>(NULL), 0)); | 1308 CHECK(String::IsOneByte(static_cast<uc16*>(NULL), 0)); |
1299 } | 1309 } |
1300 | 1310 |
1301 | 1311 |
(...skipping 66 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1368 virtual size_t length() const { return 1 << 30; } | 1378 virtual size_t length() const { return 1 << 30; } |
1369 }; | 1379 }; |
1370 | 1380 |
1371 | 1381 |
1372 TEST(InvalidExternalString) { | 1382 TEST(InvalidExternalString) { |
1373 CcTest::InitializeVM(); | 1383 CcTest::InitializeVM(); |
1374 LocalContext context; | 1384 LocalContext context; |
1375 Isolate* isolate = CcTest::i_isolate(); | 1385 Isolate* isolate = CcTest::i_isolate(); |
1376 { HandleScope scope(isolate); | 1386 { HandleScope scope(isolate); |
1377 DummyOneByteResource r; | 1387 DummyOneByteResource r; |
1378 CHECK(isolate->factory()->NewExternalStringFromAscii(&r).is_null()); | 1388 CHECK(isolate->factory()->NewExternalStringFromOneByte(&r).is_null()); |
1379 CHECK(isolate->has_pending_exception()); | 1389 CHECK(isolate->has_pending_exception()); |
1380 isolate->clear_pending_exception(); | 1390 isolate->clear_pending_exception(); |
1381 } | 1391 } |
1382 | 1392 |
1383 { HandleScope scope(isolate); | 1393 { HandleScope scope(isolate); |
1384 DummyResource r; | 1394 DummyResource r; |
1385 CHECK(isolate->factory()->NewExternalStringFromTwoByte(&r).is_null()); | 1395 CHECK(isolate->factory()->NewExternalStringFromTwoByte(&r).is_null()); |
1386 CHECK(isolate->has_pending_exception()); | 1396 CHECK(isolate->has_pending_exception()); |
1387 isolate->clear_pending_exception(); | 1397 isolate->clear_pending_exception(); |
1388 } | 1398 } |
(...skipping 14 matching lines...) Expand all Loading... |
1403 CHECK(isolate->has_pending_exception()); \ | 1413 CHECK(isolate->has_pending_exception()); \ |
1404 isolate->clear_pending_exception(); \ | 1414 isolate->clear_pending_exception(); \ |
1405 dummy.Dispose(); \ | 1415 dummy.Dispose(); \ |
1406 } | 1416 } |
1407 | 1417 |
1408 INVALID_STRING_TEST(NewStringFromAscii, char) | 1418 INVALID_STRING_TEST(NewStringFromAscii, char) |
1409 INVALID_STRING_TEST(NewStringFromUtf8, char) | 1419 INVALID_STRING_TEST(NewStringFromUtf8, char) |
1410 INVALID_STRING_TEST(NewStringFromOneByte, uint8_t) | 1420 INVALID_STRING_TEST(NewStringFromOneByte, uint8_t) |
1411 | 1421 |
1412 #undef INVALID_STRING_TEST | 1422 #undef INVALID_STRING_TEST |
OLD | NEW |