OLD | NEW |
1 // Copyright 2009 the V8 project authors. All rights reserved. | 1 // Copyright 2009 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 97 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
108 global->Set(v8::String::New("fail"), v8::FunctionTemplate::New(Fail)); | 108 global->Set(v8::String::New("fail"), v8::FunctionTemplate::New(Fail)); |
109 global->Set(v8::String::New("loop"), v8::FunctionTemplate::New(Loop)); | 109 global->Set(v8::String::New("loop"), v8::FunctionTemplate::New(Loop)); |
110 global->Set(v8::String::New("doloop"), v8::FunctionTemplate::New(doloop)); | 110 global->Set(v8::String::New("doloop"), v8::FunctionTemplate::New(doloop)); |
111 return global; | 111 return global; |
112 } | 112 } |
113 | 113 |
114 | 114 |
115 // Test that a single thread of JavaScript execution can terminate | 115 // Test that a single thread of JavaScript execution can terminate |
116 // itself. | 116 // itself. |
117 TEST(TerminateOnlyV8ThreadFromThreadItself) { | 117 TEST(TerminateOnlyV8ThreadFromThreadItself) { |
118 v8::HandleScope scope(v8::Isolate::GetCurrent()); | 118 v8::HandleScope scope(CcTest::isolate()); |
119 v8::Handle<v8::ObjectTemplate> global = | 119 v8::Handle<v8::ObjectTemplate> global = |
120 CreateGlobalTemplate(TerminateCurrentThread, DoLoop); | 120 CreateGlobalTemplate(TerminateCurrentThread, DoLoop); |
121 v8::Handle<v8::Context> context = | 121 v8::Handle<v8::Context> context = |
122 v8::Context::New(v8::Isolate::GetCurrent(), NULL, global); | 122 v8::Context::New(CcTest::isolate(), NULL, global); |
123 v8::Context::Scope context_scope(context); | 123 v8::Context::Scope context_scope(context); |
124 CHECK(!v8::V8::IsExecutionTerminating()); | 124 CHECK(!v8::V8::IsExecutionTerminating()); |
125 // Run a loop that will be infinite if thread termination does not work. | 125 // Run a loop that will be infinite if thread termination does not work. |
126 v8::Handle<v8::String> source = | 126 v8::Handle<v8::String> source = |
127 v8::String::New("try { loop(); fail(); } catch(e) { fail(); }"); | 127 v8::String::New("try { loop(); fail(); } catch(e) { fail(); }"); |
128 v8::Script::Compile(source)->Run(); | 128 v8::Script::Compile(source)->Run(); |
129 // Test that we can run the code again after thread termination. | 129 // Test that we can run the code again after thread termination. |
130 CHECK(!v8::V8::IsExecutionTerminating()); | 130 CHECK(!v8::V8::IsExecutionTerminating()); |
131 v8::Script::Compile(source)->Run(); | 131 v8::Script::Compile(source)->Run(); |
132 } | 132 } |
133 | 133 |
134 | 134 |
135 // Test that a single thread of JavaScript execution can terminate | 135 // Test that a single thread of JavaScript execution can terminate |
136 // itself in a loop that performs no calls. | 136 // itself in a loop that performs no calls. |
137 TEST(TerminateOnlyV8ThreadFromThreadItselfNoLoop) { | 137 TEST(TerminateOnlyV8ThreadFromThreadItselfNoLoop) { |
138 v8::HandleScope scope(v8::Isolate::GetCurrent()); | 138 v8::HandleScope scope(CcTest::isolate()); |
139 v8::Handle<v8::ObjectTemplate> global = | 139 v8::Handle<v8::ObjectTemplate> global = |
140 CreateGlobalTemplate(TerminateCurrentThread, DoLoopNoCall); | 140 CreateGlobalTemplate(TerminateCurrentThread, DoLoopNoCall); |
141 v8::Handle<v8::Context> context = | 141 v8::Handle<v8::Context> context = |
142 v8::Context::New(v8::Isolate::GetCurrent(), NULL, global); | 142 v8::Context::New(CcTest::isolate(), NULL, global); |
143 v8::Context::Scope context_scope(context); | 143 v8::Context::Scope context_scope(context); |
144 CHECK(!v8::V8::IsExecutionTerminating()); | 144 CHECK(!v8::V8::IsExecutionTerminating()); |
145 // Run a loop that will be infinite if thread termination does not work. | 145 // Run a loop that will be infinite if thread termination does not work. |
146 v8::Handle<v8::String> source = | 146 v8::Handle<v8::String> source = |
147 v8::String::New("try { loop(); fail(); } catch(e) { fail(); }"); | 147 v8::String::New("try { loop(); fail(); } catch(e) { fail(); }"); |
148 v8::Script::Compile(source)->Run(); | 148 v8::Script::Compile(source)->Run(); |
149 CHECK(!v8::V8::IsExecutionTerminating()); | 149 CHECK(!v8::V8::IsExecutionTerminating()); |
150 // Test that we can run the code again after thread termination. | 150 // Test that we can run the code again after thread termination. |
151 v8::Script::Compile(source)->Run(); | 151 v8::Script::Compile(source)->Run(); |
152 } | 152 } |
(...skipping 15 matching lines...) Expand all Loading... |
168 }; | 168 }; |
169 | 169 |
170 | 170 |
171 // Test that a single thread of JavaScript execution can be terminated | 171 // Test that a single thread of JavaScript execution can be terminated |
172 // from the side by another thread. | 172 // from the side by another thread. |
173 TEST(TerminateOnlyV8ThreadFromOtherThread) { | 173 TEST(TerminateOnlyV8ThreadFromOtherThread) { |
174 semaphore = new v8::internal::Semaphore(0); | 174 semaphore = new v8::internal::Semaphore(0); |
175 TerminatorThread thread(i::Isolate::Current()); | 175 TerminatorThread thread(i::Isolate::Current()); |
176 thread.Start(); | 176 thread.Start(); |
177 | 177 |
178 v8::HandleScope scope(v8::Isolate::GetCurrent()); | 178 v8::HandleScope scope(CcTest::isolate()); |
179 v8::Handle<v8::ObjectTemplate> global = CreateGlobalTemplate(Signal, DoLoop); | 179 v8::Handle<v8::ObjectTemplate> global = CreateGlobalTemplate(Signal, DoLoop); |
180 v8::Handle<v8::Context> context = | 180 v8::Handle<v8::Context> context = |
181 v8::Context::New(v8::Isolate::GetCurrent(), NULL, global); | 181 v8::Context::New(CcTest::isolate(), NULL, global); |
182 v8::Context::Scope context_scope(context); | 182 v8::Context::Scope context_scope(context); |
183 CHECK(!v8::V8::IsExecutionTerminating()); | 183 CHECK(!v8::V8::IsExecutionTerminating()); |
184 // Run a loop that will be infinite if thread termination does not work. | 184 // Run a loop that will be infinite if thread termination does not work. |
185 v8::Handle<v8::String> source = | 185 v8::Handle<v8::String> source = |
186 v8::String::New("try { loop(); fail(); } catch(e) { fail(); }"); | 186 v8::String::New("try { loop(); fail(); } catch(e) { fail(); }"); |
187 v8::Script::Compile(source)->Run(); | 187 v8::Script::Compile(source)->Run(); |
188 | 188 |
189 thread.Join(); | 189 thread.Join(); |
190 delete semaphore; | 190 delete semaphore; |
191 semaphore = NULL; | 191 semaphore = NULL; |
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
225 CHECK(try_catch.Exception()->IsNull()); | 225 CHECK(try_catch.Exception()->IsNull()); |
226 CHECK(try_catch.Message().IsEmpty()); | 226 CHECK(try_catch.Message().IsEmpty()); |
227 CHECK(!try_catch.CanContinue()); | 227 CHECK(!try_catch.CanContinue()); |
228 CHECK(v8::V8::IsExecutionTerminating()); | 228 CHECK(v8::V8::IsExecutionTerminating()); |
229 } | 229 } |
230 | 230 |
231 | 231 |
232 // Test that we correctly handle termination exceptions if they are | 232 // Test that we correctly handle termination exceptions if they are |
233 // triggered by the creation of error objects in connection with ICs. | 233 // triggered by the creation of error objects in connection with ICs. |
234 UNINITIALIZED_TEST(TerminateLoadICException) { | 234 UNINITIALIZED_TEST(TerminateLoadICException) { |
235 v8::HandleScope scope(v8::Isolate::GetCurrent()); | 235 v8::HandleScope scope(CcTest::isolate()); |
236 v8::Handle<v8::ObjectTemplate> global = v8::ObjectTemplate::New(); | 236 v8::Handle<v8::ObjectTemplate> global = v8::ObjectTemplate::New(); |
237 global->Set(v8::String::New("terminate_or_return_object"), | 237 global->Set(v8::String::New("terminate_or_return_object"), |
238 v8::FunctionTemplate::New(TerminateOrReturnObject)); | 238 v8::FunctionTemplate::New(TerminateOrReturnObject)); |
239 global->Set(v8::String::New("fail"), v8::FunctionTemplate::New(Fail)); | 239 global->Set(v8::String::New("fail"), v8::FunctionTemplate::New(Fail)); |
240 global->Set(v8::String::New("loop"), | 240 global->Set(v8::String::New("loop"), |
241 v8::FunctionTemplate::New(LoopGetProperty)); | 241 v8::FunctionTemplate::New(LoopGetProperty)); |
242 | 242 |
243 v8::Handle<v8::Context> context = | 243 v8::Handle<v8::Context> context = |
244 v8::Context::New(v8::Isolate::GetCurrent(), NULL, global); | 244 v8::Context::New(CcTest::isolate(), NULL, global); |
245 v8::Context::Scope context_scope(context); | 245 v8::Context::Scope context_scope(context); |
246 CHECK(!v8::V8::IsExecutionTerminating()); | 246 CHECK(!v8::V8::IsExecutionTerminating()); |
247 // Run a loop that will be infinite if thread termination does not work. | 247 // Run a loop that will be infinite if thread termination does not work. |
248 v8::Handle<v8::String> source = | 248 v8::Handle<v8::String> source = |
249 v8::String::New("try { loop(); fail(); } catch(e) { fail(); }"); | 249 v8::String::New("try { loop(); fail(); } catch(e) { fail(); }"); |
250 call_count = 0; | 250 call_count = 0; |
251 v8::Script::Compile(source)->Run(); | 251 v8::Script::Compile(source)->Run(); |
252 // Test that we can run the code again after thread termination. | 252 // Test that we can run the code again after thread termination. |
253 CHECK(!v8::V8::IsExecutionTerminating()); | 253 CHECK(!v8::V8::IsExecutionTerminating()); |
254 call_count = 0; | 254 call_count = 0; |
(...skipping 22 matching lines...) Expand all Loading... |
277 CHECK(try_catch.Message().IsEmpty()); | 277 CHECK(try_catch.Message().IsEmpty()); |
278 CHECK(!try_catch.CanContinue()); | 278 CHECK(!try_catch.CanContinue()); |
279 CHECK(v8::V8::IsExecutionTerminating()); | 279 CHECK(v8::V8::IsExecutionTerminating()); |
280 v8::Script::Compile(v8::String::New("function f() { fail(); } f()"))->Run(); | 280 v8::Script::Compile(v8::String::New("function f() { fail(); } f()"))->Run(); |
281 } | 281 } |
282 | 282 |
283 | 283 |
284 // Test that reentry into V8 while the termination exception is still pending | 284 // Test that reentry into V8 while the termination exception is still pending |
285 // (has not yet unwound the 0-level JS frame) does not crash. | 285 // (has not yet unwound the 0-level JS frame) does not crash. |
286 TEST(TerminateAndReenterFromThreadItself) { | 286 TEST(TerminateAndReenterFromThreadItself) { |
287 v8::HandleScope scope(v8::Isolate::GetCurrent()); | 287 v8::HandleScope scope(CcTest::isolate()); |
288 v8::Handle<v8::ObjectTemplate> global = | 288 v8::Handle<v8::ObjectTemplate> global = |
289 CreateGlobalTemplate(TerminateCurrentThread, ReenterAfterTermination); | 289 CreateGlobalTemplate(TerminateCurrentThread, ReenterAfterTermination); |
290 v8::Handle<v8::Context> context = | 290 v8::Handle<v8::Context> context = |
291 v8::Context::New(v8::Isolate::GetCurrent(), NULL, global); | 291 v8::Context::New(CcTest::isolate(), NULL, global); |
292 v8::Context::Scope context_scope(context); | 292 v8::Context::Scope context_scope(context); |
293 CHECK(!v8::V8::IsExecutionTerminating()); | 293 CHECK(!v8::V8::IsExecutionTerminating()); |
294 v8::Handle<v8::String> source = | 294 v8::Handle<v8::String> source = |
295 v8::String::New("try { loop(); fail(); } catch(e) { fail(); }"); | 295 v8::String::New("try { loop(); fail(); } catch(e) { fail(); }"); |
296 v8::Script::Compile(source)->Run(); | 296 v8::Script::Compile(source)->Run(); |
297 CHECK(!v8::V8::IsExecutionTerminating()); | 297 CHECK(!v8::V8::IsExecutionTerminating()); |
298 // Check we can run JS again after termination. | 298 // Check we can run JS again after termination. |
299 CHECK(v8::Script::Compile(v8::String::New("function f() { return true; }" | 299 CHECK(v8::Script::Compile(v8::String::New("function f() { return true; }" |
300 "f()"))->Run()->IsTrue()); | 300 "f()"))->Run()->IsTrue()); |
301 } | 301 } |
302 | 302 |
303 | 303 |
304 void DoLoopCancelTerminate(const v8::FunctionCallbackInfo<v8::Value>& args) { | 304 void DoLoopCancelTerminate(const v8::FunctionCallbackInfo<v8::Value>& args) { |
305 v8::TryCatch try_catch; | 305 v8::TryCatch try_catch; |
306 CHECK(!v8::V8::IsExecutionTerminating()); | 306 CHECK(!v8::V8::IsExecutionTerminating()); |
307 v8::Script::Compile(v8::String::New("var term = true;" | 307 v8::Script::Compile(v8::String::New("var term = true;" |
308 "while(true) {" | 308 "while(true) {" |
309 " if (term) terminate();" | 309 " if (term) terminate();" |
310 " term = false;" | 310 " term = false;" |
311 "}" | 311 "}" |
312 "fail();"))->Run(); | 312 "fail();"))->Run(); |
313 CHECK(try_catch.HasCaught()); | 313 CHECK(try_catch.HasCaught()); |
314 CHECK(try_catch.Exception()->IsNull()); | 314 CHECK(try_catch.Exception()->IsNull()); |
315 CHECK(try_catch.Message().IsEmpty()); | 315 CHECK(try_catch.Message().IsEmpty()); |
316 CHECK(!try_catch.CanContinue()); | 316 CHECK(!try_catch.CanContinue()); |
317 CHECK(v8::V8::IsExecutionTerminating()); | 317 CHECK(v8::V8::IsExecutionTerminating()); |
318 CHECK(try_catch.HasTerminated()); | 318 CHECK(try_catch.HasTerminated()); |
319 v8::V8::CancelTerminateExecution(v8::Isolate::GetCurrent()); | 319 v8::V8::CancelTerminateExecution(CcTest::isolate()); |
320 CHECK(!v8::V8::IsExecutionTerminating()); | 320 CHECK(!v8::V8::IsExecutionTerminating()); |
321 } | 321 } |
322 | 322 |
323 | 323 |
324 // Test that a single thread of JavaScript execution can terminate | 324 // Test that a single thread of JavaScript execution can terminate |
325 // itself and then resume execution. | 325 // itself and then resume execution. |
326 TEST(TerminateCancelTerminateFromThreadItself) { | 326 TEST(TerminateCancelTerminateFromThreadItself) { |
327 v8::Isolate* isolate = v8::Isolate::GetCurrent(); | 327 v8::Isolate* isolate = CcTest::isolate(); |
328 v8::HandleScope scope(isolate); | 328 v8::HandleScope scope(isolate); |
329 v8::Handle<v8::ObjectTemplate> global = | 329 v8::Handle<v8::ObjectTemplate> global = |
330 CreateGlobalTemplate(TerminateCurrentThread, DoLoopCancelTerminate); | 330 CreateGlobalTemplate(TerminateCurrentThread, DoLoopCancelTerminate); |
331 v8::Handle<v8::Context> context = v8::Context::New(isolate, NULL, global); | 331 v8::Handle<v8::Context> context = v8::Context::New(isolate, NULL, global); |
332 v8::Context::Scope context_scope(context); | 332 v8::Context::Scope context_scope(context); |
333 CHECK(!v8::V8::IsExecutionTerminating()); | 333 CHECK(!v8::V8::IsExecutionTerminating()); |
334 v8::Handle<v8::String> source = | 334 v8::Handle<v8::String> source = |
335 v8::String::New("try { doloop(); } catch(e) { fail(); } 'completed';"); | 335 v8::String::New("try { doloop(); } catch(e) { fail(); } 'completed';"); |
336 // Check that execution completed with correct return value. | 336 // Check that execution completed with correct return value. |
337 CHECK(v8::Script::Compile(source)->Run()->Equals(v8_str("completed"))); | 337 CHECK(v8::Script::Compile(source)->Run()->Equals(v8_str("completed"))); |
338 } | 338 } |
OLD | NEW |