| 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 |