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 7028 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
7039 v8::RegisterExtension(new Extension("B", "", 1, bDeps)); | 7039 v8::RegisterExtension(new Extension("B", "", 1, bDeps)); |
7040 last_location = NULL; | 7040 last_location = NULL; |
7041 v8::ExtensionConfiguration config(1, bDeps); | 7041 v8::ExtensionConfiguration config(1, bDeps); |
7042 v8::Handle<Context> context = | 7042 v8::Handle<Context> context = |
7043 Context::New(CcTest::isolate(), &config); | 7043 Context::New(CcTest::isolate(), &config); |
7044 CHECK(context.IsEmpty()); | 7044 CHECK(context.IsEmpty()); |
7045 CHECK_NE(last_location, NULL); | 7045 CHECK_NE(last_location, NULL); |
7046 } | 7046 } |
7047 | 7047 |
7048 | 7048 |
7049 static const char* js_code_causing_huge_string_flattening = | |
7050 "var str = 'X';" | |
7051 "for (var i = 0; i < 30; i++) {" | |
7052 " str = str + str;" | |
7053 "}" | |
7054 "str.match(/X/);"; | |
7055 | |
7056 | |
7057 TEST(RegexpOutOfMemory) { | |
7058 // Execute a script that causes out of memory when flattening a string. | |
7059 v8::HandleScope scope(CcTest::isolate()); | |
7060 v8::V8::SetFatalErrorHandler(OOMCallback); | |
7061 LocalContext context; | |
7062 Local<Script> script = Script::Compile(String::NewFromUtf8( | |
7063 CcTest::isolate(), js_code_causing_huge_string_flattening)); | |
7064 last_location = NULL; | |
7065 script->Run(); | |
7066 | |
7067 CHECK(false); // Should not return. | |
7068 } | |
7069 | |
7070 | |
7071 static void MissingScriptInfoMessageListener(v8::Handle<v8::Message> message, | 7049 static void MissingScriptInfoMessageListener(v8::Handle<v8::Message> message, |
7072 v8::Handle<Value> data) { | 7050 v8::Handle<Value> data) { |
7073 CHECK(message->GetScriptResourceName()->IsUndefined()); | 7051 CHECK(message->GetScriptResourceName()->IsUndefined()); |
7074 CHECK_EQ(v8::Undefined(CcTest::isolate()), message->GetScriptResourceName()); | 7052 CHECK_EQ(v8::Undefined(CcTest::isolate()), message->GetScriptResourceName()); |
7075 message->GetLineNumber(); | 7053 message->GetLineNumber(); |
7076 message->GetSourceLine(); | 7054 message->GetSourceLine(); |
7077 } | 7055 } |
7078 | 7056 |
7079 | 7057 |
7080 THREADED_TEST(ErrorWithMissingScriptInfo) { | 7058 THREADED_TEST(ErrorWithMissingScriptInfo) { |
7081 LocalContext context; | 7059 LocalContext context; |
7082 v8::HandleScope scope(context->GetIsolate()); | 7060 v8::HandleScope scope(context->GetIsolate()); |
7083 v8::V8::AddMessageListener(MissingScriptInfoMessageListener); | 7061 v8::V8::AddMessageListener(MissingScriptInfoMessageListener); |
7084 Script::Compile(v8_str("throw Error()"))->Run(); | 7062 Script::Compile(v8_str("throw Error()"))->Run(); |
7085 v8::V8::RemoveMessageListeners(MissingScriptInfoMessageListener); | 7063 v8::V8::RemoveMessageListeners(MissingScriptInfoMessageListener); |
7086 } | 7064 } |
7087 | 7065 |
7088 | 7066 |
7089 int global_index = 0; | |
7090 | |
7091 template<typename T> | |
7092 class Snorkel { | |
7093 public: | |
7094 explicit Snorkel(v8::Persistent<T>* handle) : handle_(handle) { | |
7095 index_ = global_index++; | |
7096 } | |
7097 v8::Persistent<T>* handle_; | |
7098 int index_; | |
7099 }; | |
7100 | |
7101 class Whammy { | |
7102 public: | |
7103 explicit Whammy(v8::Isolate* isolate) : cursor_(0), isolate_(isolate) { } | |
7104 ~Whammy() { script_.Reset(); } | |
7105 v8::Handle<Script> getScript() { | |
7106 if (script_.IsEmpty()) script_.Reset(isolate_, v8_compile("({}).blammo")); | |
7107 return Local<Script>::New(isolate_, script_); | |
7108 } | |
7109 | |
7110 public: | |
7111 static const int kObjectCount = 256; | |
7112 int cursor_; | |
7113 v8::Isolate* isolate_; | |
7114 v8::Persistent<v8::Object> objects_[kObjectCount]; | |
7115 v8::Persistent<Script> script_; | |
7116 }; | |
7117 | |
7118 static void HandleWeakReference( | |
7119 const v8::WeakCallbackData<v8::Value, Snorkel<v8::Value> >& data) { | |
7120 data.GetParameter()->handle_->ClearWeak(); | |
7121 delete data.GetParameter(); | |
7122 } | |
7123 | |
7124 void WhammyPropertyGetter(Local<String> name, | |
7125 const v8::PropertyCallbackInfo<v8::Value>& info) { | |
7126 Whammy* whammy = | |
7127 static_cast<Whammy*>(v8::Handle<v8::External>::Cast(info.Data())->Value()); | |
7128 | |
7129 v8::Persistent<v8::Object>& prev = whammy->objects_[whammy->cursor_]; | |
7130 | |
7131 v8::Handle<v8::Object> obj = v8::Object::New(info.GetIsolate()); | |
7132 if (!prev.IsEmpty()) { | |
7133 v8::Local<v8::Object>::New(info.GetIsolate(), prev) | |
7134 ->Set(v8_str("next"), obj); | |
7135 prev.SetWeak<Value, Snorkel<Value> >(new Snorkel<Value>(&prev.As<Value>()), | |
7136 &HandleWeakReference); | |
7137 } | |
7138 whammy->objects_[whammy->cursor_].Reset(info.GetIsolate(), obj); | |
7139 whammy->cursor_ = (whammy->cursor_ + 1) % Whammy::kObjectCount; | |
7140 info.GetReturnValue().Set(whammy->getScript()->Run()); | |
7141 } | |
7142 | |
7143 | |
7144 TEST(WeakReference) { | |
7145 i::FLAG_expose_gc = true; | |
7146 v8::Isolate* isolate = CcTest::isolate(); | |
7147 v8::HandleScope handle_scope(isolate); | |
7148 v8::Handle<v8::ObjectTemplate> templ= v8::ObjectTemplate::New(isolate); | |
7149 Whammy* whammy = new Whammy(CcTest::isolate()); | |
7150 templ->SetNamedPropertyHandler(WhammyPropertyGetter, | |
7151 0, 0, 0, 0, | |
7152 v8::External::New(CcTest::isolate(), whammy)); | |
7153 const char* extension_list[] = { "v8/gc" }; | |
7154 v8::ExtensionConfiguration extensions(1, extension_list); | |
7155 v8::Handle<Context> context = | |
7156 Context::New(CcTest::isolate(), &extensions); | |
7157 Context::Scope context_scope(context); | |
7158 | |
7159 v8::Handle<v8::Object> interceptor = templ->NewInstance(); | |
7160 context->Global()->Set(v8_str("whammy"), interceptor); | |
7161 const char* code = | |
7162 "var last;" | |
7163 "for (var i = 0; i < 10000; i++) {" | |
7164 " var obj = whammy.length;" | |
7165 " if (last) last.next = obj;" | |
7166 " last = obj;" | |
7167 "}" | |
7168 "gc();" | |
7169 "4"; | |
7170 v8::Handle<Value> result = CompileRun(code); | |
7171 CHECK_EQ(4.0, result->NumberValue()); | |
7172 delete whammy; | |
7173 } | |
7174 | |
7175 | |
7176 struct FlagAndPersistent { | 7067 struct FlagAndPersistent { |
7177 bool flag; | 7068 bool flag; |
7178 v8::Persistent<v8::Object> handle; | 7069 v8::Persistent<v8::Object> handle; |
7179 }; | 7070 }; |
7180 | 7071 |
7181 | 7072 |
7182 static void DisposeAndSetFlag( | 7073 static void DisposeAndSetFlag( |
7183 const v8::WeakCallbackData<v8::Object, FlagAndPersistent>& data) { | 7074 const v8::WeakCallbackData<v8::Object, FlagAndPersistent>& data) { |
7184 data.GetParameter()->handle.Reset(); | 7075 data.GetParameter()->handle.Reset(); |
7185 data.GetParameter()->flag = true; | 7076 data.GetParameter()->flag = true; |
(...skipping 7741 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
14927 v8::ScriptData* deserialized_sd = | 14818 v8::ScriptData* deserialized_sd = |
14928 v8::ScriptData::New(serialized_data, serialized_data_length); | 14819 v8::ScriptData::New(serialized_data, serialized_data_length); |
14929 | 14820 |
14930 // Verify that the original is the same as the deserialized. | 14821 // Verify that the original is the same as the deserialized. |
14931 CHECK_EQ(sd->Length(), deserialized_sd->Length()); | 14822 CHECK_EQ(sd->Length(), deserialized_sd->Length()); |
14932 CHECK_EQ(0, memcmp(sd->Data(), deserialized_sd->Data(), sd->Length())); | 14823 CHECK_EQ(0, memcmp(sd->Data(), deserialized_sd->Data(), sd->Length())); |
14933 CHECK_EQ(sd->HasError(), deserialized_sd->HasError()); | 14824 CHECK_EQ(sd->HasError(), deserialized_sd->HasError()); |
14934 | 14825 |
14935 delete sd; | 14826 delete sd; |
14936 delete deserialized_sd; | 14827 delete deserialized_sd; |
| 14828 i::DeleteArray(serialized_data); |
14937 } | 14829 } |
14938 | 14830 |
14939 | 14831 |
14940 // Attempts to deserialize bad data. | 14832 // Attempts to deserialize bad data. |
14941 TEST(PreCompileDeserializationError) { | 14833 TEST(PreCompileDeserializationError) { |
14942 v8::V8::Initialize(); | 14834 v8::V8::Initialize(); |
14943 const char* data = "DONT CARE"; | 14835 const char* data = "DONT CARE"; |
14944 int invalid_size = 3; | 14836 int invalid_size = 3; |
14945 v8::ScriptData* sd = v8::ScriptData::New(data, invalid_size); | 14837 v8::ScriptData* sd = v8::ScriptData::New(data, invalid_size); |
14946 | 14838 |
(...skipping 28 matching lines...) Expand all Loading... |
14975 v8::TryCatch try_catch; | 14867 v8::TryCatch try_catch; |
14976 | 14868 |
14977 Local<String> source = String::NewFromUtf8(isolate, script); | 14869 Local<String> source = String::NewFromUtf8(isolate, script); |
14978 Local<Script> compiled_script = Script::New(source, NULL, sd); | 14870 Local<Script> compiled_script = Script::New(source, NULL, sd); |
14979 CHECK(try_catch.HasCaught()); | 14871 CHECK(try_catch.HasCaught()); |
14980 String::Utf8Value exception_value(try_catch.Message()->Get()); | 14872 String::Utf8Value exception_value(try_catch.Message()->Get()); |
14981 CHECK_EQ("Uncaught SyntaxError: Invalid preparser data for function bar", | 14873 CHECK_EQ("Uncaught SyntaxError: Invalid preparser data for function bar", |
14982 *exception_value); | 14874 *exception_value); |
14983 | 14875 |
14984 try_catch.Reset(); | 14876 try_catch.Reset(); |
| 14877 delete sd; |
14985 | 14878 |
14986 // Overwrite function bar's start position with 200. The function entry | 14879 // Overwrite function bar's start position with 200. The function entry |
14987 // will not be found when searching for it by position and we should fall | 14880 // will not be found when searching for it by position and we should fall |
14988 // back on eager compilation. | 14881 // back on eager compilation. |
14989 sd = v8::ScriptData::PreCompile(v8::String::NewFromUtf8( | 14882 sd = v8::ScriptData::PreCompile(v8::String::NewFromUtf8( |
14990 isolate, script, v8::String::kNormalString, i::StrLength(script))); | 14883 isolate, script, v8::String::kNormalString, i::StrLength(script))); |
14991 sd_data = reinterpret_cast<unsigned*>(const_cast<char*>(sd->Data())); | 14884 sd_data = reinterpret_cast<unsigned*>(const_cast<char*>(sd->Data())); |
14992 sd_data[kHeaderSize + 1 * kFunctionEntrySize + kFunctionEntryStartOffset] = | 14885 sd_data[kHeaderSize + 1 * kFunctionEntrySize + kFunctionEntryStartOffset] = |
14993 200; | 14886 200; |
14994 compiled_script = Script::New(source, NULL, sd); | 14887 compiled_script = Script::New(source, NULL, sd); |
(...skipping 296 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
15291 | 15184 |
15292 v8::TryCatch try_catch; | 15185 v8::TryCatch try_catch; |
15293 timeout_thread.Start(); | 15186 timeout_thread.Start(); |
15294 | 15187 |
15295 CompileRun("/((a*)*)*b/.exec(a)"); | 15188 CompileRun("/((a*)*)*b/.exec(a)"); |
15296 CHECK(try_catch.HasTerminated()); | 15189 CHECK(try_catch.HasTerminated()); |
15297 | 15190 |
15298 timeout_thread.Join(); | 15191 timeout_thread.Join(); |
15299 | 15192 |
15300 regexp_interruption_data.string.Reset(); | 15193 regexp_interruption_data.string.Reset(); |
| 15194 i::DeleteArray(uc16_content); |
15301 } | 15195 } |
15302 | 15196 |
15303 #endif // V8_INTERPRETED_REGEXP | 15197 #endif // V8_INTERPRETED_REGEXP |
15304 | 15198 |
15305 | 15199 |
15306 // Test that we cannot set a property on the global object if there | 15200 // Test that we cannot set a property on the global object if there |
15307 // is a read-only property in the prototype chain. | 15201 // is a read-only property in the prototype chain. |
15308 TEST(ReadOnlyPropertyInGlobalProto) { | 15202 TEST(ReadOnlyPropertyInGlobalProto) { |
15309 i::FLAG_es5_readonly = true; | 15203 i::FLAG_es5_readonly = true; |
15310 v8::Isolate* isolate = CcTest::isolate(); | 15204 v8::Isolate* isolate = CcTest::isolate(); |
(...skipping 3838 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
19149 v8::V8::SetFatalErrorHandler(StoringErrorCallback); | 19043 v8::V8::SetFatalErrorHandler(StoringErrorCallback); |
19150 last_location = last_message = NULL; | 19044 last_location = last_message = NULL; |
19151 isolate->Dispose(); | 19045 isolate->Dispose(); |
19152 CHECK_EQ(last_location, NULL); | 19046 CHECK_EQ(last_location, NULL); |
19153 CHECK_EQ(last_message, NULL); | 19047 CHECK_EQ(last_message, NULL); |
19154 } | 19048 } |
19155 | 19049 |
19156 | 19050 |
19157 UNINITIALIZED_TEST(DisposeIsolateWhenInUse) { | 19051 UNINITIALIZED_TEST(DisposeIsolateWhenInUse) { |
19158 v8::Isolate* isolate = v8::Isolate::New(); | 19052 v8::Isolate* isolate = v8::Isolate::New(); |
19159 CHECK(isolate); | 19053 { |
19160 isolate->Enter(); | 19054 v8::Isolate::Scope i_scope(isolate); |
19161 v8::HandleScope scope(isolate); | 19055 v8::HandleScope scope(isolate); |
19162 LocalContext context(isolate); | 19056 LocalContext context(isolate); |
19163 // Run something in this isolate. | 19057 // Run something in this isolate. |
19164 ExpectTrue("true"); | 19058 ExpectTrue("true"); |
19165 v8::V8::SetFatalErrorHandler(StoringErrorCallback); | 19059 v8::V8::SetFatalErrorHandler(StoringErrorCallback); |
19166 last_location = last_message = NULL; | 19060 last_location = last_message = NULL; |
19167 // Still entered, should fail. | 19061 // Still entered, should fail. |
| 19062 isolate->Dispose(); |
| 19063 CHECK_NE(last_location, NULL); |
| 19064 CHECK_NE(last_message, NULL); |
| 19065 } |
19168 isolate->Dispose(); | 19066 isolate->Dispose(); |
19169 CHECK_NE(last_location, NULL); | |
19170 CHECK_NE(last_message, NULL); | |
19171 } | 19067 } |
19172 | 19068 |
19173 | 19069 |
19174 TEST(RunTwoIsolatesOnSingleThread) { | 19070 TEST(RunTwoIsolatesOnSingleThread) { |
19175 // Run isolate 1. | 19071 // Run isolate 1. |
19176 v8::Isolate* isolate1 = v8::Isolate::New(); | 19072 v8::Isolate* isolate1 = v8::Isolate::New(); |
19177 isolate1->Enter(); | 19073 isolate1->Enter(); |
19178 v8::Persistent<v8::Context> context1; | 19074 v8::Persistent<v8::Context> context1; |
19179 { | 19075 { |
19180 v8::HandleScope scope(isolate1); | 19076 v8::HandleScope scope(isolate1); |
(...skipping 194 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
19375 } | 19271 } |
19376 { | 19272 { |
19377 v8::Isolate::Scope isolate_scope(isolate); | 19273 v8::Isolate::Scope isolate_scope(isolate); |
19378 v8::HandleScope handle_scope(isolate); | 19274 v8::HandleScope handle_scope(isolate); |
19379 context = v8::Context::New(isolate); | 19275 context = v8::Context::New(isolate); |
19380 v8::Context::Scope context_scope(context); | 19276 v8::Context::Scope context_scope(context); |
19381 Local<Value> v = CompileRun("22"); | 19277 Local<Value> v = CompileRun("22"); |
19382 CHECK(v->IsNumber()); | 19278 CHECK(v->IsNumber()); |
19383 CHECK_EQ(22, static_cast<int>(v->NumberValue())); | 19279 CHECK_EQ(22, static_cast<int>(v->NumberValue())); |
19384 } | 19280 } |
| 19281 isolate->Dispose(); |
19385 } | 19282 } |
19386 | 19283 |
19387 class InitDefaultIsolateThread : public v8::internal::Thread { | 19284 class InitDefaultIsolateThread : public v8::internal::Thread { |
19388 public: | 19285 public: |
19389 enum TestCase { | 19286 enum TestCase { |
19390 IgnoreOOM, | 19287 IgnoreOOM, |
19391 SetResourceConstraints, | 19288 SetResourceConstraints, |
19392 SetFatalHandler, | 19289 SetFatalHandler, |
19393 SetCounterFunction, | 19290 SetCounterFunction, |
19394 SetCreateHistogramFunction, | 19291 SetCreateHistogramFunction, |
(...skipping 2666 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
22061 | 21958 |
22062 | 21959 |
22063 TEST(TestFunctionCallOptimization) { | 21960 TEST(TestFunctionCallOptimization) { |
22064 i::FLAG_allow_natives_syntax = true; | 21961 i::FLAG_allow_natives_syntax = true; |
22065 ApiCallOptimizationChecker checker; | 21962 ApiCallOptimizationChecker checker; |
22066 checker.Run(true, true); | 21963 checker.Run(true, true); |
22067 checker.Run(false, true); | 21964 checker.Run(false, true); |
22068 checker.Run(true, false); | 21965 checker.Run(true, false); |
22069 checker.Run(false, false); | 21966 checker.Run(false, false); |
22070 } | 21967 } |
OLD | NEW |