| 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 82 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 93 }; | 93 }; |
| 94 | 94 |
| 95 | 95 |
| 96 using namespace v8::internal; | 96 using namespace v8::internal; |
| 97 | 97 |
| 98 static v8::Persistent<v8::Context> env; | 98 static v8::Persistent<v8::Context> env; |
| 99 | 99 |
| 100 | 100 |
| 101 static void InitializeVM() { | 101 static void InitializeVM() { |
| 102 if (env.IsEmpty()) { | 102 if (env.IsEmpty()) { |
| 103 v8::HandleScope scope; | |
| 104 const char* extensions[] = { "v8/print" }; | 103 const char* extensions[] = { "v8/print" }; |
| 105 v8::ExtensionConfiguration config(1, extensions); | 104 v8::ExtensionConfiguration config(1, extensions); |
| 106 env = v8::Context::New(&config); | 105 env = v8::Context::New(&config); |
| 107 } | 106 } |
| 108 env->Enter(); | 107 env->Enter(); |
| 109 } | 108 } |
| 110 | 109 |
| 111 | 110 |
| 112 static const int DEEP_DEPTH = 8 * 1024; | 111 static const int DEEP_DEPTH = 8 * 1024; |
| 113 static const int SUPER_DEEP_DEPTH = 80 * 1024; | 112 static const int SUPER_DEEP_DEPTH = 80 * 1024; |
| (...skipping 455 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 569 i++; | 568 i++; |
| 570 } | 569 } |
| 571 s1->Get(s1->length() - 1); | 570 s1->Get(s1->length() - 1); |
| 572 s2->Get(s2->length() - 1); | 571 s2->Get(s2->length() - 1); |
| 573 } | 572 } |
| 574 | 573 |
| 575 | 574 |
| 576 TEST(Traverse) { | 575 TEST(Traverse) { |
| 577 printf("TestTraverse\n"); | 576 printf("TestTraverse\n"); |
| 578 InitializeVM(); | 577 InitializeVM(); |
| 579 v8::HandleScope scope; | 578 v8::HandleScope scope(env->GetIsolate()); |
| 580 ZoneScope zone(Isolate::Current()->runtime_zone(), DELETE_ON_EXIT); | 579 ZoneScope zone(Isolate::Current()->runtime_zone(), DELETE_ON_EXIT); |
| 581 ConsStringGenerationData data(false); | 580 ConsStringGenerationData data(false); |
| 582 Handle<String> flat = ConstructBalanced(&data); | 581 Handle<String> flat = ConstructBalanced(&data); |
| 583 FlattenString(flat); | 582 FlattenString(flat); |
| 584 Handle<String> left_asymmetric = ConstructLeft(&data, DEEP_DEPTH); | 583 Handle<String> left_asymmetric = ConstructLeft(&data, DEEP_DEPTH); |
| 585 Handle<String> right_asymmetric = ConstructRight(&data, DEEP_DEPTH); | 584 Handle<String> right_asymmetric = ConstructRight(&data, DEEP_DEPTH); |
| 586 Handle<String> symmetric = ConstructBalanced(&data); | 585 Handle<String> symmetric = ConstructBalanced(&data); |
| 587 printf("1\n"); | 586 printf("1\n"); |
| 588 Traverse(flat, symmetric); | 587 Traverse(flat, symmetric); |
| 589 printf("2\n"); | 588 printf("2\n"); |
| (...skipping 268 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 858 TestStringCharacterStream(BuildRandomConsString, kUniqueRandomParameters*7); | 857 TestStringCharacterStream(BuildRandomConsString, kUniqueRandomParameters*7); |
| 859 } | 858 } |
| 860 | 859 |
| 861 | 860 |
| 862 static const int DEEP_ASCII_DEPTH = 100000; | 861 static const int DEEP_ASCII_DEPTH = 100000; |
| 863 | 862 |
| 864 | 863 |
| 865 TEST(DeepAscii) { | 864 TEST(DeepAscii) { |
| 866 printf("TestDeepAscii\n"); | 865 printf("TestDeepAscii\n"); |
| 867 InitializeVM(); | 866 InitializeVM(); |
| 868 v8::HandleScope scope; | 867 v8::HandleScope scope(env->GetIsolate()); |
| 869 | 868 |
| 870 char* foo = NewArray<char>(DEEP_ASCII_DEPTH); | 869 char* foo = NewArray<char>(DEEP_ASCII_DEPTH); |
| 871 for (int i = 0; i < DEEP_ASCII_DEPTH; i++) { | 870 for (int i = 0; i < DEEP_ASCII_DEPTH; i++) { |
| 872 foo[i] = "foo "[i % 4]; | 871 foo[i] = "foo "[i % 4]; |
| 873 } | 872 } |
| 874 Handle<String> string = | 873 Handle<String> string = |
| 875 FACTORY->NewStringFromAscii(Vector<const char>(foo, DEEP_ASCII_DEPTH)); | 874 FACTORY->NewStringFromAscii(Vector<const char>(foo, DEEP_ASCII_DEPTH)); |
| 876 Handle<String> foo_string = FACTORY->NewStringFromAscii(CStrVector("foo")); | 875 Handle<String> foo_string = FACTORY->NewStringFromAscii(CStrVector("foo")); |
| 877 for (int i = 0; i < DEEP_ASCII_DEPTH; i += 10) { | 876 for (int i = 0; i < DEEP_ASCII_DEPTH; i += 10) { |
| 878 string = FACTORY->NewConsString(string, foo_string); | 877 string = FACTORY->NewConsString(string, foo_string); |
| 879 } | 878 } |
| 880 Handle<String> flat_string = FACTORY->NewConsString(string, foo_string); | 879 Handle<String> flat_string = FACTORY->NewConsString(string, foo_string); |
| 881 FlattenString(flat_string); | 880 FlattenString(flat_string); |
| 882 | 881 |
| 883 for (int i = 0; i < 500; i++) { | 882 for (int i = 0; i < 500; i++) { |
| 884 TraverseFirst(flat_string, string, DEEP_ASCII_DEPTH); | 883 TraverseFirst(flat_string, string, DEEP_ASCII_DEPTH); |
| 885 } | 884 } |
| 886 DeleteArray<char>(foo); | 885 DeleteArray<char>(foo); |
| 887 } | 886 } |
| 888 | 887 |
| 889 | 888 |
| 890 TEST(Utf8Conversion) { | 889 TEST(Utf8Conversion) { |
| 891 // Smoke test for converting strings to utf-8. | 890 // Smoke test for converting strings to utf-8. |
| 892 InitializeVM(); | 891 InitializeVM(); |
| 893 v8::HandleScope handle_scope; | 892 v8::HandleScope handle_scope(env->GetIsolate()); |
| 894 // A simple ascii string | 893 // A simple ascii string |
| 895 const char* ascii_string = "abcdef12345"; | 894 const char* ascii_string = "abcdef12345"; |
| 896 int len = | 895 int len = |
| 897 v8::String::New(ascii_string, | 896 v8::String::New(ascii_string, |
| 898 StrLength(ascii_string))->Utf8Length(); | 897 StrLength(ascii_string))->Utf8Length(); |
| 899 CHECK_EQ(StrLength(ascii_string), len); | 898 CHECK_EQ(StrLength(ascii_string), len); |
| 900 // A mixed ascii and non-ascii string | 899 // A mixed ascii and non-ascii string |
| 901 // U+02E4 -> CB A4 | 900 // U+02E4 -> CB A4 |
| 902 // U+0064 -> 64 | 901 // U+0064 -> 64 |
| 903 // U+12E4 -> E1 8B A4 | 902 // U+12E4 -> E1 8B A4 |
| (...skipping 26 matching lines...) Expand all Loading... |
| 930 for (int j = lengths[i]; j < 11; j++) | 929 for (int j = lengths[i]; j < 11; j++) |
| 931 CHECK_EQ(kNoChar, buffer[j]); | 930 CHECK_EQ(kNoChar, buffer[j]); |
| 932 } | 931 } |
| 933 } | 932 } |
| 934 | 933 |
| 935 | 934 |
| 936 TEST(ExternalShortStringAdd) { | 935 TEST(ExternalShortStringAdd) { |
| 937 ZoneScope zonescope(Isolate::Current()->runtime_zone(), DELETE_ON_EXIT); | 936 ZoneScope zonescope(Isolate::Current()->runtime_zone(), DELETE_ON_EXIT); |
| 938 | 937 |
| 939 InitializeVM(); | 938 InitializeVM(); |
| 940 v8::HandleScope handle_scope; | 939 v8::HandleScope handle_scope(env->GetIsolate()); |
| 941 Zone* zone = Isolate::Current()->runtime_zone(); | 940 Zone* zone = Isolate::Current()->runtime_zone(); |
| 942 | 941 |
| 943 // Make sure we cover all always-flat lengths and at least one above. | 942 // Make sure we cover all always-flat lengths and at least one above. |
| 944 static const int kMaxLength = 20; | 943 static const int kMaxLength = 20; |
| 945 CHECK_GT(kMaxLength, i::ConsString::kMinLength); | 944 CHECK_GT(kMaxLength, i::ConsString::kMinLength); |
| 946 | 945 |
| 947 // Allocate two JavaScript arrays for holding short strings. | 946 // Allocate two JavaScript arrays for holding short strings. |
| 948 v8::Handle<v8::Array> ascii_external_strings = | 947 v8::Handle<v8::Array> ascii_external_strings = |
| 949 v8::Array::New(kMaxLength + 1); | 948 v8::Array::New(kMaxLength + 1); |
| 950 v8::Handle<v8::Array> non_ascii_external_strings = | 949 v8::Handle<v8::Array> non_ascii_external_strings = |
| (...skipping 71 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1022 | 1021 |
| 1023 | 1022 |
| 1024 TEST(CachedHashOverflow) { | 1023 TEST(CachedHashOverflow) { |
| 1025 // We incorrectly allowed strings to be tagged as array indices even if their | 1024 // We incorrectly allowed strings to be tagged as array indices even if their |
| 1026 // values didn't fit in the hash field. | 1025 // values didn't fit in the hash field. |
| 1027 // See http://code.google.com/p/v8/issues/detail?id=728 | 1026 // See http://code.google.com/p/v8/issues/detail?id=728 |
| 1028 Isolate* isolate = Isolate::Current(); | 1027 Isolate* isolate = Isolate::Current(); |
| 1029 ZoneScope zone(isolate->runtime_zone(), DELETE_ON_EXIT); | 1028 ZoneScope zone(isolate->runtime_zone(), DELETE_ON_EXIT); |
| 1030 | 1029 |
| 1031 InitializeVM(); | 1030 InitializeVM(); |
| 1032 v8::HandleScope handle_scope; | 1031 v8::HandleScope handle_scope(env->GetIsolate()); |
| 1033 // Lines must be executed sequentially. Combining them into one script | 1032 // Lines must be executed sequentially. Combining them into one script |
| 1034 // makes the bug go away. | 1033 // makes the bug go away. |
| 1035 const char* lines[] = { | 1034 const char* lines[] = { |
| 1036 "var x = [];", | 1035 "var x = [];", |
| 1037 "x[4] = 42;", | 1036 "x[4] = 42;", |
| 1038 "var s = \"1073741828\";", | 1037 "var s = \"1073741828\";", |
| 1039 "x[s];", | 1038 "x[s];", |
| 1040 "x[s] = 37;", | 1039 "x[s] = 37;", |
| 1041 "x[4];", | 1040 "x[4];", |
| 1042 "x[s];", | 1041 "x[s];", |
| (...skipping 22 matching lines...) Expand all Loading... |
| 1065 CHECK_EQ(Smi::cast(results[i]->ToSmi()->ToObjectChecked())->value(), | 1064 CHECK_EQ(Smi::cast(results[i]->ToSmi()->ToObjectChecked())->value(), |
| 1066 result->ToInt32()->Value()); | 1065 result->ToInt32()->Value()); |
| 1067 } | 1066 } |
| 1068 } | 1067 } |
| 1069 } | 1068 } |
| 1070 | 1069 |
| 1071 | 1070 |
| 1072 TEST(SliceFromCons) { | 1071 TEST(SliceFromCons) { |
| 1073 FLAG_string_slices = true; | 1072 FLAG_string_slices = true; |
| 1074 InitializeVM(); | 1073 InitializeVM(); |
| 1075 v8::HandleScope scope; | 1074 v8::HandleScope scope(env->GetIsolate()); |
| 1076 Handle<String> string = | 1075 Handle<String> string = |
| 1077 FACTORY->NewStringFromAscii(CStrVector("parentparentparent")); | 1076 FACTORY->NewStringFromAscii(CStrVector("parentparentparent")); |
| 1078 Handle<String> parent = FACTORY->NewConsString(string, string); | 1077 Handle<String> parent = FACTORY->NewConsString(string, string); |
| 1079 CHECK(parent->IsConsString()); | 1078 CHECK(parent->IsConsString()); |
| 1080 CHECK(!parent->IsFlat()); | 1079 CHECK(!parent->IsFlat()); |
| 1081 Handle<String> slice = FACTORY->NewSubString(parent, 1, 25); | 1080 Handle<String> slice = FACTORY->NewSubString(parent, 1, 25); |
| 1082 // After slicing, the original string becomes a flat cons. | 1081 // After slicing, the original string becomes a flat cons. |
| 1083 CHECK(parent->IsFlat()); | 1082 CHECK(parent->IsFlat()); |
| 1084 CHECK(slice->IsSlicedString()); | 1083 CHECK(slice->IsSlicedString()); |
| 1085 CHECK_EQ(SlicedString::cast(*slice)->parent(), | 1084 CHECK_EQ(SlicedString::cast(*slice)->parent(), |
| (...skipping 11 matching lines...) Expand all Loading... |
| 1097 virtual size_t length() const { return data_.length(); } | 1096 virtual size_t length() const { return data_.length(); } |
| 1098 virtual const char* data() const { return data_.start(); } | 1097 virtual const char* data() const { return data_.start(); } |
| 1099 private: | 1098 private: |
| 1100 i::Vector<const char> data_; | 1099 i::Vector<const char> data_; |
| 1101 }; | 1100 }; |
| 1102 | 1101 |
| 1103 | 1102 |
| 1104 TEST(SliceFromExternal) { | 1103 TEST(SliceFromExternal) { |
| 1105 FLAG_string_slices = true; | 1104 FLAG_string_slices = true; |
| 1106 InitializeVM(); | 1105 InitializeVM(); |
| 1107 v8::HandleScope scope; | 1106 v8::HandleScope scope(env->GetIsolate()); |
| 1108 AsciiVectorResource resource( | 1107 AsciiVectorResource resource( |
| 1109 i::Vector<const char>("abcdefghijklmnopqrstuvwxyz", 26)); | 1108 i::Vector<const char>("abcdefghijklmnopqrstuvwxyz", 26)); |
| 1110 Handle<String> string = FACTORY->NewExternalStringFromAscii(&resource); | 1109 Handle<String> string = FACTORY->NewExternalStringFromAscii(&resource); |
| 1111 CHECK(string->IsExternalString()); | 1110 CHECK(string->IsExternalString()); |
| 1112 Handle<String> slice = FACTORY->NewSubString(string, 1, 25); | 1111 Handle<String> slice = FACTORY->NewSubString(string, 1, 25); |
| 1113 CHECK(slice->IsSlicedString()); | 1112 CHECK(slice->IsSlicedString()); |
| 1114 CHECK(string->IsExternalString()); | 1113 CHECK(string->IsExternalString()); |
| 1115 CHECK_EQ(SlicedString::cast(*slice)->parent(), *string); | 1114 CHECK_EQ(SlicedString::cast(*slice)->parent(), *string); |
| 1116 CHECK(SlicedString::cast(*slice)->parent()->IsExternalString()); | 1115 CHECK(SlicedString::cast(*slice)->parent()->IsExternalString()); |
| 1117 CHECK(slice->IsFlat()); | 1116 CHECK(slice->IsFlat()); |
| 1118 } | 1117 } |
| 1119 | 1118 |
| 1120 | 1119 |
| 1121 TEST(TrivialSlice) { | 1120 TEST(TrivialSlice) { |
| 1122 // This tests whether a slice that contains the entire parent string | 1121 // This tests whether a slice that contains the entire parent string |
| 1123 // actually creates a new string (it should not). | 1122 // actually creates a new string (it should not). |
| 1124 FLAG_string_slices = true; | 1123 FLAG_string_slices = true; |
| 1125 InitializeVM(); | 1124 InitializeVM(); |
| 1126 v8::HandleScope scope; | 1125 v8::HandleScope scope(env->GetIsolate()); |
| 1127 v8::Local<v8::Value> result; | 1126 v8::Local<v8::Value> result; |
| 1128 Handle<String> string; | 1127 Handle<String> string; |
| 1129 const char* init = "var str = 'abcdefghijklmnopqrstuvwxyz';"; | 1128 const char* init = "var str = 'abcdefghijklmnopqrstuvwxyz';"; |
| 1130 const char* check = "str.slice(0,26)"; | 1129 const char* check = "str.slice(0,26)"; |
| 1131 const char* crosscheck = "str.slice(1,25)"; | 1130 const char* crosscheck = "str.slice(1,25)"; |
| 1132 | 1131 |
| 1133 CompileRun(init); | 1132 CompileRun(init); |
| 1134 | 1133 |
| 1135 result = CompileRun(check); | 1134 result = CompileRun(check); |
| 1136 CHECK(result->IsString()); | 1135 CHECK(result->IsString()); |
| 1137 string = v8::Utils::OpenHandle(v8::String::Cast(*result)); | 1136 string = v8::Utils::OpenHandle(v8::String::Cast(*result)); |
| 1138 CHECK(!string->IsSlicedString()); | 1137 CHECK(!string->IsSlicedString()); |
| 1139 | 1138 |
| 1140 string = FACTORY->NewSubString(string, 0, 26); | 1139 string = FACTORY->NewSubString(string, 0, 26); |
| 1141 CHECK(!string->IsSlicedString()); | 1140 CHECK(!string->IsSlicedString()); |
| 1142 result = CompileRun(crosscheck); | 1141 result = CompileRun(crosscheck); |
| 1143 CHECK(result->IsString()); | 1142 CHECK(result->IsString()); |
| 1144 string = v8::Utils::OpenHandle(v8::String::Cast(*result)); | 1143 string = v8::Utils::OpenHandle(v8::String::Cast(*result)); |
| 1145 CHECK(string->IsSlicedString()); | 1144 CHECK(string->IsSlicedString()); |
| 1146 CHECK_EQ("bcdefghijklmnopqrstuvwxy", *(string->ToCString())); | 1145 CHECK_EQ("bcdefghijklmnopqrstuvwxy", *(string->ToCString())); |
| 1147 } | 1146 } |
| 1148 | 1147 |
| 1149 | 1148 |
| 1150 TEST(SliceFromSlice) { | 1149 TEST(SliceFromSlice) { |
| 1151 // This tests whether a slice that contains the entire parent string | 1150 // This tests whether a slice that contains the entire parent string |
| 1152 // actually creates a new string (it should not). | 1151 // actually creates a new string (it should not). |
| 1153 FLAG_string_slices = true; | 1152 FLAG_string_slices = true; |
| 1154 InitializeVM(); | 1153 InitializeVM(); |
| 1155 v8::HandleScope scope; | 1154 v8::HandleScope scope(env->GetIsolate()); |
| 1156 v8::Local<v8::Value> result; | 1155 v8::Local<v8::Value> result; |
| 1157 Handle<String> string; | 1156 Handle<String> string; |
| 1158 const char* init = "var str = 'abcdefghijklmnopqrstuvwxyz';"; | 1157 const char* init = "var str = 'abcdefghijklmnopqrstuvwxyz';"; |
| 1159 const char* slice = "var slice = str.slice(1,-1); slice"; | 1158 const char* slice = "var slice = str.slice(1,-1); slice"; |
| 1160 const char* slice_from_slice = "slice.slice(1,-1);"; | 1159 const char* slice_from_slice = "slice.slice(1,-1);"; |
| 1161 | 1160 |
| 1162 CompileRun(init); | 1161 CompileRun(init); |
| 1163 result = CompileRun(slice); | 1162 result = CompileRun(slice); |
| 1164 CHECK(result->IsString()); | 1163 CHECK(result->IsString()); |
| 1165 string = v8::Utils::OpenHandle(v8::String::Cast(*result)); | 1164 string = v8::Utils::OpenHandle(v8::String::Cast(*result)); |
| (...skipping 23 matching lines...) Expand all Loading... |
| 1189 // total length of the concatenated strings is 2^31 + 3. So on 32bit systems | 1188 // total length of the concatenated strings is 2^31 + 3. So on 32bit systems |
| 1190 // summing the lengths of the strings (as Smis) overflows and wraps. | 1189 // summing the lengths of the strings (as Smis) overflows and wraps. |
| 1191 static const char* join_causing_out_of_memory = | 1190 static const char* join_causing_out_of_memory = |
| 1192 "var two_14 = Math.pow(2, 14);" | 1191 "var two_14 = Math.pow(2, 14);" |
| 1193 "var two_17 = Math.pow(2, 17);" | 1192 "var two_17 = Math.pow(2, 17);" |
| 1194 "var s = Array(two_17 + 1).join('c');" | 1193 "var s = Array(two_17 + 1).join('c');" |
| 1195 "var a = ['bad'];" | 1194 "var a = ['bad'];" |
| 1196 "for (var i = 1; i <= two_14; i++) a.push(s);" | 1195 "for (var i = 1; i <= two_14; i++) a.push(s);" |
| 1197 "a.join("");"; | 1196 "a.join("");"; |
| 1198 | 1197 |
| 1199 v8::HandleScope scope; | 1198 v8::HandleScope scope(v8::Isolate::GetCurrent()); |
| 1200 LocalContext context; | 1199 LocalContext context; |
| 1201 v8::V8::IgnoreOutOfMemoryException(); | 1200 v8::V8::IgnoreOutOfMemoryException(); |
| 1202 v8::Local<v8::Script> script = | 1201 v8::Local<v8::Script> script = |
| 1203 v8::Script::Compile(v8::String::New(join_causing_out_of_memory)); | 1202 v8::Script::Compile(v8::String::New(join_causing_out_of_memory)); |
| 1204 v8::Local<v8::Value> result = script->Run(); | 1203 v8::Local<v8::Value> result = script->Run(); |
| 1205 | 1204 |
| 1206 // Check for out of memory state. | 1205 // Check for out of memory state. |
| 1207 CHECK(result.IsEmpty()); | 1206 CHECK(result.IsEmpty()); |
| 1208 CHECK(context->HasOutOfMemoryException()); | 1207 CHECK(context->HasOutOfMemoryException()); |
| 1209 } | 1208 } |
| 1210 | 1209 |
| 1211 | 1210 |
| 1212 static void CheckException(const char* source) { | 1211 static void CheckException(const char* source) { |
| 1213 // An empty handle is returned upon exception. | 1212 // An empty handle is returned upon exception. |
| 1214 CHECK(CompileRun(source).IsEmpty()); | 1213 CHECK(CompileRun(source).IsEmpty()); |
| 1215 } | 1214 } |
| 1216 | 1215 |
| 1217 | 1216 |
| 1218 TEST(RobustSubStringStub) { | 1217 TEST(RobustSubStringStub) { |
| 1219 // This tests whether the SubStringStub can handle unsafe arguments. | 1218 // This tests whether the SubStringStub can handle unsafe arguments. |
| 1220 // If not recognized, those unsafe arguments lead to out-of-bounds reads. | 1219 // If not recognized, those unsafe arguments lead to out-of-bounds reads. |
| 1221 FLAG_allow_natives_syntax = true; | 1220 FLAG_allow_natives_syntax = true; |
| 1222 InitializeVM(); | 1221 InitializeVM(); |
| 1223 v8::HandleScope scope; | 1222 v8::HandleScope scope(env->GetIsolate()); |
| 1224 v8::Local<v8::Value> result; | 1223 v8::Local<v8::Value> result; |
| 1225 Handle<String> string; | 1224 Handle<String> string; |
| 1226 CompileRun("var short = 'abcdef';"); | 1225 CompileRun("var short = 'abcdef';"); |
| 1227 | 1226 |
| 1228 // Invalid indices. | 1227 // Invalid indices. |
| 1229 CheckException("%_SubString(short, 0, 10000);"); | 1228 CheckException("%_SubString(short, 0, 10000);"); |
| 1230 CheckException("%_SubString(short, -1234, 5);"); | 1229 CheckException("%_SubString(short, -1234, 5);"); |
| 1231 CheckException("%_SubString(short, 5, 2);"); | 1230 CheckException("%_SubString(short, 5, 2);"); |
| 1232 // Special HeapNumbers. | 1231 // Special HeapNumbers. |
| 1233 CheckException("%_SubString(short, 1, Infinity);"); | 1232 CheckException("%_SubString(short, 1, Infinity);"); |
| (...skipping 23 matching lines...) Expand all Loading... |
| 1257 // Test that out-of-bounds substring of a slice fails when the indices | 1256 // Test that out-of-bounds substring of a slice fails when the indices |
| 1258 // would have been valid for the underlying string. | 1257 // would have been valid for the underlying string. |
| 1259 CompileRun("var slice = long.slice(1, 15);"); | 1258 CompileRun("var slice = long.slice(1, 15);"); |
| 1260 CheckException("%_SubString(slice, 0, 17);"); | 1259 CheckException("%_SubString(slice, 0, 17);"); |
| 1261 } | 1260 } |
| 1262 | 1261 |
| 1263 | 1262 |
| 1264 TEST(RegExpOverflow) { | 1263 TEST(RegExpOverflow) { |
| 1265 // Result string has the length 2^32, causing a 32-bit integer overflow. | 1264 // Result string has the length 2^32, causing a 32-bit integer overflow. |
| 1266 InitializeVM(); | 1265 InitializeVM(); |
| 1267 v8::HandleScope scope; | 1266 v8::HandleScope scope(env->GetIsolate()); |
| 1268 LocalContext context; | 1267 LocalContext context; |
| 1269 v8::V8::IgnoreOutOfMemoryException(); | 1268 v8::V8::IgnoreOutOfMemoryException(); |
| 1270 v8::Local<v8::Value> result = CompileRun( | 1269 v8::Local<v8::Value> result = CompileRun( |
| 1271 "var a = 'a'; " | 1270 "var a = 'a'; " |
| 1272 "for (var i = 0; i < 16; i++) { " | 1271 "for (var i = 0; i < 16; i++) { " |
| 1273 " a += a; " | 1272 " a += a; " |
| 1274 "} " | 1273 "} " |
| 1275 "a.replace(/a/g, a); "); | 1274 "a.replace(/a/g, a); "); |
| 1276 CHECK(result.IsEmpty()); | 1275 CHECK(result.IsEmpty()); |
| 1277 CHECK(context->HasOutOfMemoryException()); | 1276 CHECK(context->HasOutOfMemoryException()); |
| 1278 } | 1277 } |
| 1279 | 1278 |
| 1280 | 1279 |
| 1281 TEST(StringReplaceAtomTwoByteResult) { | 1280 TEST(StringReplaceAtomTwoByteResult) { |
| 1282 InitializeVM(); | 1281 InitializeVM(); |
| 1283 v8::HandleScope scope; | 1282 v8::HandleScope scope(env->GetIsolate()); |
| 1284 LocalContext context; | 1283 LocalContext context; |
| 1285 v8::Local<v8::Value> result = CompileRun( | 1284 v8::Local<v8::Value> result = CompileRun( |
| 1286 "var subject = 'ascii~only~string~'; " | 1285 "var subject = 'ascii~only~string~'; " |
| 1287 "var replace = '\x80'; " | 1286 "var replace = '\x80'; " |
| 1288 "subject.replace(/~/g, replace); "); | 1287 "subject.replace(/~/g, replace); "); |
| 1289 CHECK(result->IsString()); | 1288 CHECK(result->IsString()); |
| 1290 Handle<String> string = v8::Utils::OpenHandle(v8::String::Cast(*result)); | 1289 Handle<String> string = v8::Utils::OpenHandle(v8::String::Cast(*result)); |
| 1291 CHECK(string->IsSeqTwoByteString()); | 1290 CHECK(string->IsSeqTwoByteString()); |
| 1292 | 1291 |
| 1293 v8::Local<v8::String> expected = v8_str("ascii\x80only\x80string\x80"); | 1292 v8::Local<v8::String> expected = v8_str("ascii\x80only\x80string\x80"); |
| (...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1351 continue; | 1350 continue; |
| 1352 } | 1351 } |
| 1353 if (upper != c && lower != c) { | 1352 if (upper != c && lower != c) { |
| 1354 CheckCanonicalEquivalence(c, test); | 1353 CheckCanonicalEquivalence(c, test); |
| 1355 continue; | 1354 continue; |
| 1356 } | 1355 } |
| 1357 CHECK_EQ(Min(upper, lower), test); | 1356 CHECK_EQ(Min(upper, lower), test); |
| 1358 } | 1357 } |
| 1359 } | 1358 } |
| 1360 #endif // ENABLE_LATIN_1 | 1359 #endif // ENABLE_LATIN_1 |
| OLD | NEW |