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