1c81c894dabeceb472d668027ca59e73096f5cfafsgjesse@chromium.org// Copyright 2009 the V8 project authors. All rights reserved. 2c81c894dabeceb472d668027ca59e73096f5cfafsgjesse@chromium.org// Redistribution and use in source and binary forms, with or without 3c81c894dabeceb472d668027ca59e73096f5cfafsgjesse@chromium.org// modification, are permitted provided that the following conditions are 4c81c894dabeceb472d668027ca59e73096f5cfafsgjesse@chromium.org// met: 5c81c894dabeceb472d668027ca59e73096f5cfafsgjesse@chromium.org// 6c81c894dabeceb472d668027ca59e73096f5cfafsgjesse@chromium.org// * Redistributions of source code must retain the above copyright 7c81c894dabeceb472d668027ca59e73096f5cfafsgjesse@chromium.org// notice, this list of conditions and the following disclaimer. 8c81c894dabeceb472d668027ca59e73096f5cfafsgjesse@chromium.org// * Redistributions in binary form must reproduce the above 9c81c894dabeceb472d668027ca59e73096f5cfafsgjesse@chromium.org// copyright notice, this list of conditions and the following 10c81c894dabeceb472d668027ca59e73096f5cfafsgjesse@chromium.org// disclaimer in the documentation and/or other materials provided 11c81c894dabeceb472d668027ca59e73096f5cfafsgjesse@chromium.org// with the distribution. 12c81c894dabeceb472d668027ca59e73096f5cfafsgjesse@chromium.org// * Neither the name of Google Inc. nor the names of its 13c81c894dabeceb472d668027ca59e73096f5cfafsgjesse@chromium.org// contributors may be used to endorse or promote products derived 14c81c894dabeceb472d668027ca59e73096f5cfafsgjesse@chromium.org// from this software without specific prior written permission. 15c81c894dabeceb472d668027ca59e73096f5cfafsgjesse@chromium.org// 16c81c894dabeceb472d668027ca59e73096f5cfafsgjesse@chromium.org// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 17c81c894dabeceb472d668027ca59e73096f5cfafsgjesse@chromium.org// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 18c81c894dabeceb472d668027ca59e73096f5cfafsgjesse@chromium.org// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 19c81c894dabeceb472d668027ca59e73096f5cfafsgjesse@chromium.org// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 20c81c894dabeceb472d668027ca59e73096f5cfafsgjesse@chromium.org// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 21c81c894dabeceb472d668027ca59e73096f5cfafsgjesse@chromium.org// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 22c81c894dabeceb472d668027ca59e73096f5cfafsgjesse@chromium.org// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 23c81c894dabeceb472d668027ca59e73096f5cfafsgjesse@chromium.org// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 24c81c894dabeceb472d668027ca59e73096f5cfafsgjesse@chromium.org// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 25c81c894dabeceb472d668027ca59e73096f5cfafsgjesse@chromium.org// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 26c81c894dabeceb472d668027ca59e73096f5cfafsgjesse@chromium.org// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 27c81c894dabeceb472d668027ca59e73096f5cfafsgjesse@chromium.org 28196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org#include "src/v8.h" 29196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org#include "test/cctest/cctest.h" 30c81c894dabeceb472d668027ca59e73096f5cfafsgjesse@chromium.org 315de0074a922429f5e0ec2cf140c2d2989bf88140yangguo@chromium.org#include "src/base/platform/platform.h" 324b0feeef5d01dbc2948080b4f69daa37e1083461machenbach@chromium.org 33c81c894dabeceb472d668027ca59e73096f5cfafsgjesse@chromium.org 345de0074a922429f5e0ec2cf140c2d2989bf88140yangguo@chromium.orgv8::base::Semaphore* semaphore = NULL; 35c81c894dabeceb472d668027ca59e73096f5cfafsgjesse@chromium.org 36c81c894dabeceb472d668027ca59e73096f5cfafsgjesse@chromium.org 371510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.orgvoid Signal(const v8::FunctionCallbackInfo<v8::Value>& args) { 38c81c894dabeceb472d668027ca59e73096f5cfafsgjesse@chromium.org semaphore->Signal(); 39c81c894dabeceb472d668027ca59e73096f5cfafsgjesse@chromium.org} 40c81c894dabeceb472d668027ca59e73096f5cfafsgjesse@chromium.org 41c81c894dabeceb472d668027ca59e73096f5cfafsgjesse@chromium.org 421510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.orgvoid TerminateCurrentThread(const v8::FunctionCallbackInfo<v8::Value>& args) { 43528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org CHECK(!v8::V8::IsExecutionTerminating(args.GetIsolate())); 44528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org v8::V8::TerminateExecution(args.GetIsolate()); 45c81c894dabeceb472d668027ca59e73096f5cfafsgjesse@chromium.org} 46c81c894dabeceb472d668027ca59e73096f5cfafsgjesse@chromium.org 47c81c894dabeceb472d668027ca59e73096f5cfafsgjesse@chromium.org 481510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.orgvoid Fail(const v8::FunctionCallbackInfo<v8::Value>& args) { 49c81c894dabeceb472d668027ca59e73096f5cfafsgjesse@chromium.org CHECK(false); 50c81c894dabeceb472d668027ca59e73096f5cfafsgjesse@chromium.org} 51c81c894dabeceb472d668027ca59e73096f5cfafsgjesse@chromium.org 52c81c894dabeceb472d668027ca59e73096f5cfafsgjesse@chromium.org 531510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.orgvoid Loop(const v8::FunctionCallbackInfo<v8::Value>& args) { 54528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org CHECK(!v8::V8::IsExecutionTerminating(args.GetIsolate())); 55f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.org v8::Handle<v8::String> source = v8::String::NewFromUtf8( 56f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.org args.GetIsolate(), "try { doloop(); fail(); } catch(e) { fail(); }"); 572ab99526496cda7ff426115c76a1c475a1b4f4a5sgjesse@chromium.org v8::Handle<v8::Value> result = v8::Script::Compile(source)->Run(); 582ab99526496cda7ff426115c76a1c475a1b4f4a5sgjesse@chromium.org CHECK(result.IsEmpty()); 59528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org CHECK(v8::V8::IsExecutionTerminating(args.GetIsolate())); 60c81c894dabeceb472d668027ca59e73096f5cfafsgjesse@chromium.org} 61c81c894dabeceb472d668027ca59e73096f5cfafsgjesse@chromium.org 62c81c894dabeceb472d668027ca59e73096f5cfafsgjesse@chromium.org 631510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.orgvoid DoLoop(const v8::FunctionCallbackInfo<v8::Value>& args) { 64c81c894dabeceb472d668027ca59e73096f5cfafsgjesse@chromium.org v8::TryCatch try_catch; 65528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org CHECK(!v8::V8::IsExecutionTerminating(args.GetIsolate())); 66f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.org v8::Script::Compile(v8::String::NewFromUtf8(args.GetIsolate(), 67f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.org "function f() {" 68f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.org " var term = true;" 69f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.org " try {" 70f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.org " while(true) {" 71f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.org " if (term) terminate();" 72f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.org " term = false;" 73f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.org " }" 74f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.org " fail();" 75f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.org " } catch(e) {" 76f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.org " fail();" 77f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.org " }" 78f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.org "}" 79f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.org "f()"))->Run(); 80c81c894dabeceb472d668027ca59e73096f5cfafsgjesse@chromium.org CHECK(try_catch.HasCaught()); 81c81c894dabeceb472d668027ca59e73096f5cfafsgjesse@chromium.org CHECK(try_catch.Exception()->IsNull()); 82c81c894dabeceb472d668027ca59e73096f5cfafsgjesse@chromium.org CHECK(try_catch.Message().IsEmpty()); 83c81c894dabeceb472d668027ca59e73096f5cfafsgjesse@chromium.org CHECK(!try_catch.CanContinue()); 84528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org CHECK(v8::V8::IsExecutionTerminating(args.GetIsolate())); 85c81c894dabeceb472d668027ca59e73096f5cfafsgjesse@chromium.org} 86c81c894dabeceb472d668027ca59e73096f5cfafsgjesse@chromium.org 87c81c894dabeceb472d668027ca59e73096f5cfafsgjesse@chromium.org 881510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.orgvoid DoLoopNoCall(const v8::FunctionCallbackInfo<v8::Value>& args) { 8901beca7f8d9f549e04ec575a0bca96d859ab55a5ager@chromium.org v8::TryCatch try_catch; 90528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org CHECK(!v8::V8::IsExecutionTerminating(args.GetIsolate())); 91f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.org v8::Script::Compile(v8::String::NewFromUtf8(args.GetIsolate(), 92f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.org "var term = true;" 93f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.org "while(true) {" 94f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.org " if (term) terminate();" 95f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.org " term = false;" 96f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.org "}"))->Run(); 9701beca7f8d9f549e04ec575a0bca96d859ab55a5ager@chromium.org CHECK(try_catch.HasCaught()); 9801beca7f8d9f549e04ec575a0bca96d859ab55a5ager@chromium.org CHECK(try_catch.Exception()->IsNull()); 9901beca7f8d9f549e04ec575a0bca96d859ab55a5ager@chromium.org CHECK(try_catch.Message().IsEmpty()); 10001beca7f8d9f549e04ec575a0bca96d859ab55a5ager@chromium.org CHECK(!try_catch.CanContinue()); 101528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org CHECK(v8::V8::IsExecutionTerminating(args.GetIsolate())); 10201beca7f8d9f549e04ec575a0bca96d859ab55a5ager@chromium.org} 10301beca7f8d9f549e04ec575a0bca96d859ab55a5ager@chromium.org 10401beca7f8d9f549e04ec575a0bca96d859ab55a5ager@chromium.org 105c81c894dabeceb472d668027ca59e73096f5cfafsgjesse@chromium.orgv8::Handle<v8::ObjectTemplate> CreateGlobalTemplate( 106f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.org v8::Isolate* isolate, 1071510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org v8::FunctionCallback terminate, 1081510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org v8::FunctionCallback doloop) { 1099cbaabda8b4daeb06759ace10c926ab55bb69d7bulan@chromium.org v8::Handle<v8::ObjectTemplate> global = v8::ObjectTemplate::New(isolate); 110f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.org global->Set(v8::String::NewFromUtf8(isolate, "terminate"), 1114f99be9ff2091451687891a05d99cc31990de709hpayer@chromium.org v8::FunctionTemplate::New(isolate, terminate)); 112f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.org global->Set(v8::String::NewFromUtf8(isolate, "fail"), 1134f99be9ff2091451687891a05d99cc31990de709hpayer@chromium.org v8::FunctionTemplate::New(isolate, Fail)); 114f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.org global->Set(v8::String::NewFromUtf8(isolate, "loop"), 1154f99be9ff2091451687891a05d99cc31990de709hpayer@chromium.org v8::FunctionTemplate::New(isolate, Loop)); 116f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.org global->Set(v8::String::NewFromUtf8(isolate, "doloop"), 1174f99be9ff2091451687891a05d99cc31990de709hpayer@chromium.org v8::FunctionTemplate::New(isolate, doloop)); 118c81c894dabeceb472d668027ca59e73096f5cfafsgjesse@chromium.org return global; 119c81c894dabeceb472d668027ca59e73096f5cfafsgjesse@chromium.org} 120c81c894dabeceb472d668027ca59e73096f5cfafsgjesse@chromium.org 121c81c894dabeceb472d668027ca59e73096f5cfafsgjesse@chromium.org 122c81c894dabeceb472d668027ca59e73096f5cfafsgjesse@chromium.org// Test that a single thread of JavaScript execution can terminate 123c81c894dabeceb472d668027ca59e73096f5cfafsgjesse@chromium.org// itself. 124c81c894dabeceb472d668027ca59e73096f5cfafsgjesse@chromium.orgTEST(TerminateOnlyV8ThreadFromThreadItself) { 125528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org v8::HandleScope scope(CcTest::isolate()); 126c81c894dabeceb472d668027ca59e73096f5cfafsgjesse@chromium.org v8::Handle<v8::ObjectTemplate> global = 127f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.org CreateGlobalTemplate(CcTest::isolate(), TerminateCurrentThread, DoLoop); 12857ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org v8::Handle<v8::Context> context = 129528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org v8::Context::New(CcTest::isolate(), NULL, global); 13001beca7f8d9f549e04ec575a0bca96d859ab55a5ager@chromium.org v8::Context::Scope context_scope(context); 131528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org CHECK(!v8::V8::IsExecutionTerminating(CcTest::isolate())); 13201beca7f8d9f549e04ec575a0bca96d859ab55a5ager@chromium.org // Run a loop that will be infinite if thread termination does not work. 133f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.org v8::Handle<v8::String> source = v8::String::NewFromUtf8( 134f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.org CcTest::isolate(), "try { loop(); fail(); } catch(e) { fail(); }"); 13501beca7f8d9f549e04ec575a0bca96d859ab55a5ager@chromium.org v8::Script::Compile(source)->Run(); 13601beca7f8d9f549e04ec575a0bca96d859ab55a5ager@chromium.org // Test that we can run the code again after thread termination. 137528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org CHECK(!v8::V8::IsExecutionTerminating(CcTest::isolate())); 13801beca7f8d9f549e04ec575a0bca96d859ab55a5ager@chromium.org v8::Script::Compile(source)->Run(); 13901beca7f8d9f549e04ec575a0bca96d859ab55a5ager@chromium.org} 14001beca7f8d9f549e04ec575a0bca96d859ab55a5ager@chromium.org 14101beca7f8d9f549e04ec575a0bca96d859ab55a5ager@chromium.org 14201beca7f8d9f549e04ec575a0bca96d859ab55a5ager@chromium.org// Test that a single thread of JavaScript execution can terminate 14301beca7f8d9f549e04ec575a0bca96d859ab55a5ager@chromium.org// itself in a loop that performs no calls. 14401beca7f8d9f549e04ec575a0bca96d859ab55a5ager@chromium.orgTEST(TerminateOnlyV8ThreadFromThreadItselfNoLoop) { 145528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org v8::HandleScope scope(CcTest::isolate()); 146f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.org v8::Handle<v8::ObjectTemplate> global = CreateGlobalTemplate( 147f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.org CcTest::isolate(), TerminateCurrentThread, DoLoopNoCall); 14857ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org v8::Handle<v8::Context> context = 149528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org v8::Context::New(CcTest::isolate(), NULL, global); 150c81c894dabeceb472d668027ca59e73096f5cfafsgjesse@chromium.org v8::Context::Scope context_scope(context); 151528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org CHECK(!v8::V8::IsExecutionTerminating(CcTest::isolate())); 152c81c894dabeceb472d668027ca59e73096f5cfafsgjesse@chromium.org // Run a loop that will be infinite if thread termination does not work. 153f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.org v8::Handle<v8::String> source = v8::String::NewFromUtf8( 154f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.org CcTest::isolate(), "try { loop(); fail(); } catch(e) { fail(); }"); 155c81c894dabeceb472d668027ca59e73096f5cfafsgjesse@chromium.org v8::Script::Compile(source)->Run(); 156528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org CHECK(!v8::V8::IsExecutionTerminating(CcTest::isolate())); 157c81c894dabeceb472d668027ca59e73096f5cfafsgjesse@chromium.org // Test that we can run the code again after thread termination. 158c81c894dabeceb472d668027ca59e73096f5cfafsgjesse@chromium.org v8::Script::Compile(source)->Run(); 159c81c894dabeceb472d668027ca59e73096f5cfafsgjesse@chromium.org} 160c81c894dabeceb472d668027ca59e73096f5cfafsgjesse@chromium.org 161c81c894dabeceb472d668027ca59e73096f5cfafsgjesse@chromium.org 1625de0074a922429f5e0ec2cf140c2d2989bf88140yangguo@chromium.orgclass TerminatorThread : public v8::base::Thread { 163ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org public: 164ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org explicit TerminatorThread(i::Isolate* isolate) 1655e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org : Thread(Options("TerminatorThread")), 1665e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org isolate_(reinterpret_cast<v8::Isolate*>(isolate)) {} 167c81c894dabeceb472d668027ca59e73096f5cfafsgjesse@chromium.org void Run() { 168c81c894dabeceb472d668027ca59e73096f5cfafsgjesse@chromium.org semaphore->Wait(); 1696d786c9805481bd13ecb29c3155540f2f32950e1svenpanne@chromium.org CHECK(!v8::V8::IsExecutionTerminating(isolate_)); 1706d786c9805481bd13ecb29c3155540f2f32950e1svenpanne@chromium.org v8::V8::TerminateExecution(isolate_); 171c81c894dabeceb472d668027ca59e73096f5cfafsgjesse@chromium.org } 1726d786c9805481bd13ecb29c3155540f2f32950e1svenpanne@chromium.org 1736d786c9805481bd13ecb29c3155540f2f32950e1svenpanne@chromium.org private: 1746d786c9805481bd13ecb29c3155540f2f32950e1svenpanne@chromium.org v8::Isolate* isolate_; 175c81c894dabeceb472d668027ca59e73096f5cfafsgjesse@chromium.org}; 176c81c894dabeceb472d668027ca59e73096f5cfafsgjesse@chromium.org 177c81c894dabeceb472d668027ca59e73096f5cfafsgjesse@chromium.org 178c81c894dabeceb472d668027ca59e73096f5cfafsgjesse@chromium.org// Test that a single thread of JavaScript execution can be terminated 179c81c894dabeceb472d668027ca59e73096f5cfafsgjesse@chromium.org// from the side by another thread. 180c81c894dabeceb472d668027ca59e73096f5cfafsgjesse@chromium.orgTEST(TerminateOnlyV8ThreadFromOtherThread) { 1815de0074a922429f5e0ec2cf140c2d2989bf88140yangguo@chromium.org semaphore = new v8::base::Semaphore(0); 182528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org TerminatorThread thread(CcTest::i_isolate()); 183c81c894dabeceb472d668027ca59e73096f5cfafsgjesse@chromium.org thread.Start(); 184c81c894dabeceb472d668027ca59e73096f5cfafsgjesse@chromium.org 185528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org v8::HandleScope scope(CcTest::isolate()); 186f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.org v8::Handle<v8::ObjectTemplate> global = 187f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.org CreateGlobalTemplate(CcTest::isolate(), Signal, DoLoop); 18857ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org v8::Handle<v8::Context> context = 189528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org v8::Context::New(CcTest::isolate(), NULL, global); 190c81c894dabeceb472d668027ca59e73096f5cfafsgjesse@chromium.org v8::Context::Scope context_scope(context); 191528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org CHECK(!v8::V8::IsExecutionTerminating(CcTest::isolate())); 192c81c894dabeceb472d668027ca59e73096f5cfafsgjesse@chromium.org // Run a loop that will be infinite if thread termination does not work. 193f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.org v8::Handle<v8::String> source = v8::String::NewFromUtf8( 194f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.org CcTest::isolate(), "try { loop(); fail(); } catch(e) { fail(); }"); 195c81c894dabeceb472d668027ca59e73096f5cfafsgjesse@chromium.org v8::Script::Compile(source)->Run(); 196c81c894dabeceb472d668027ca59e73096f5cfafsgjesse@chromium.org 197c81c894dabeceb472d668027ca59e73096f5cfafsgjesse@chromium.org thread.Join(); 198c81c894dabeceb472d668027ca59e73096f5cfafsgjesse@chromium.org delete semaphore; 199c81c894dabeceb472d668027ca59e73096f5cfafsgjesse@chromium.org semaphore = NULL; 200c81c894dabeceb472d668027ca59e73096f5cfafsgjesse@chromium.org} 201c81c894dabeceb472d668027ca59e73096f5cfafsgjesse@chromium.org 202c81c894dabeceb472d668027ca59e73096f5cfafsgjesse@chromium.org 20318ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.orgint call_count = 0; 20418ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org 20518ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org 2061510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.orgvoid TerminateOrReturnObject(const v8::FunctionCallbackInfo<v8::Value>& args) { 20718ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org if (++call_count == 10) { 208528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org CHECK(!v8::V8::IsExecutionTerminating(args.GetIsolate())); 209528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org v8::V8::TerminateExecution(args.GetIsolate()); 2101510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org return; 21118ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org } 2120f13e74b7310d8b14f19c6b93b36ff95059f97f6ulan@chromium.org v8::Local<v8::Object> result = v8::Object::New(args.GetIsolate()); 213f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.org result->Set(v8::String::NewFromUtf8(args.GetIsolate(), "x"), 2140f13e74b7310d8b14f19c6b93b36ff95059f97f6ulan@chromium.org v8::Integer::New(args.GetIsolate(), 42)); 2151510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org args.GetReturnValue().Set(result); 21618ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org} 21718ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org 21818ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org 2191510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.orgvoid LoopGetProperty(const v8::FunctionCallbackInfo<v8::Value>& args) { 22018ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org v8::TryCatch try_catch; 221528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org CHECK(!v8::V8::IsExecutionTerminating(args.GetIsolate())); 222f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.org v8::Script::Compile( 223f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.org v8::String::NewFromUtf8(args.GetIsolate(), 224f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.org "function f() {" 225f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.org " try {" 226f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.org " while(true) {" 227f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.org " terminate_or_return_object().x;" 228f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.org " }" 229f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.org " fail();" 230f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.org " } catch(e) {" 231f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.org " fail();" 232f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.org " }" 233f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.org "}" 234f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.org "f()"))->Run(); 23518ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org CHECK(try_catch.HasCaught()); 23618ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org CHECK(try_catch.Exception()->IsNull()); 23718ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org CHECK(try_catch.Message().IsEmpty()); 23818ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org CHECK(!try_catch.CanContinue()); 239528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org CHECK(v8::V8::IsExecutionTerminating(args.GetIsolate())); 24018ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org} 24118ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org 24218ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org 24318ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org// Test that we correctly handle termination exceptions if they are 24418ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org// triggered by the creation of error objects in connection with ICs. 24518ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.orgTEST(TerminateLoadICException) { 2464f99be9ff2091451687891a05d99cc31990de709hpayer@chromium.org v8::Isolate* isolate = CcTest::isolate(); 2474f99be9ff2091451687891a05d99cc31990de709hpayer@chromium.org v8::HandleScope scope(isolate); 2489cbaabda8b4daeb06759ace10c926ab55bb69d7bulan@chromium.org v8::Handle<v8::ObjectTemplate> global = v8::ObjectTemplate::New(isolate); 249f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.org global->Set( 2504f99be9ff2091451687891a05d99cc31990de709hpayer@chromium.org v8::String::NewFromUtf8(isolate, "terminate_or_return_object"), 2514f99be9ff2091451687891a05d99cc31990de709hpayer@chromium.org v8::FunctionTemplate::New(isolate, TerminateOrReturnObject)); 2524f99be9ff2091451687891a05d99cc31990de709hpayer@chromium.org global->Set(v8::String::NewFromUtf8(isolate, "fail"), 2534f99be9ff2091451687891a05d99cc31990de709hpayer@chromium.org v8::FunctionTemplate::New(isolate, Fail)); 2544f99be9ff2091451687891a05d99cc31990de709hpayer@chromium.org global->Set(v8::String::NewFromUtf8(isolate, "loop"), 2554f99be9ff2091451687891a05d99cc31990de709hpayer@chromium.org v8::FunctionTemplate::New(isolate, LoopGetProperty)); 25618ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org 25757ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org v8::Handle<v8::Context> context = 2584f99be9ff2091451687891a05d99cc31990de709hpayer@chromium.org v8::Context::New(isolate, NULL, global); 25918ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org v8::Context::Scope context_scope(context); 2604f99be9ff2091451687891a05d99cc31990de709hpayer@chromium.org CHECK(!v8::V8::IsExecutionTerminating(isolate)); 26118ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org // Run a loop that will be infinite if thread termination does not work. 262f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.org v8::Handle<v8::String> source = v8::String::NewFromUtf8( 2634f99be9ff2091451687891a05d99cc31990de709hpayer@chromium.org isolate, "try { loop(); fail(); } catch(e) { fail(); }"); 26418ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org call_count = 0; 26518ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org v8::Script::Compile(source)->Run(); 26618ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org // Test that we can run the code again after thread termination. 2674f99be9ff2091451687891a05d99cc31990de709hpayer@chromium.org CHECK(!v8::V8::IsExecutionTerminating(isolate)); 26818ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org call_count = 0; 26918ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org v8::Script::Compile(source)->Run(); 27018ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org} 2719155e252524a2bf92aecd27493feafed86702312kmillikin@chromium.org 272e0e1b0d3e70c933d36ed381d511e9fda39f2a751mstarzinger@chromium.org 2731510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.orgvoid ReenterAfterTermination(const v8::FunctionCallbackInfo<v8::Value>& args) { 2749155e252524a2bf92aecd27493feafed86702312kmillikin@chromium.org v8::TryCatch try_catch; 275528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org CHECK(!v8::V8::IsExecutionTerminating(args.GetIsolate())); 276f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.org v8::Script::Compile(v8::String::NewFromUtf8(args.GetIsolate(), 277f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.org "function f() {" 278f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.org " var term = true;" 279f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.org " try {" 280f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.org " while(true) {" 281f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.org " if (term) terminate();" 282f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.org " term = false;" 283f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.org " }" 284f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.org " fail();" 285f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.org " } catch(e) {" 286f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.org " fail();" 287f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.org " }" 288f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.org "}" 289f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.org "f()"))->Run(); 2909155e252524a2bf92aecd27493feafed86702312kmillikin@chromium.org CHECK(try_catch.HasCaught()); 2919155e252524a2bf92aecd27493feafed86702312kmillikin@chromium.org CHECK(try_catch.Exception()->IsNull()); 2929155e252524a2bf92aecd27493feafed86702312kmillikin@chromium.org CHECK(try_catch.Message().IsEmpty()); 2939155e252524a2bf92aecd27493feafed86702312kmillikin@chromium.org CHECK(!try_catch.CanContinue()); 294528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org CHECK(v8::V8::IsExecutionTerminating(args.GetIsolate())); 295f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.org v8::Script::Compile(v8::String::NewFromUtf8(args.GetIsolate(), 296f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.org "function f() { fail(); } f()")) 297f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.org ->Run(); 2989155e252524a2bf92aecd27493feafed86702312kmillikin@chromium.org} 2999155e252524a2bf92aecd27493feafed86702312kmillikin@chromium.org 300e0e1b0d3e70c933d36ed381d511e9fda39f2a751mstarzinger@chromium.org 3019155e252524a2bf92aecd27493feafed86702312kmillikin@chromium.org// Test that reentry into V8 while the termination exception is still pending 3029155e252524a2bf92aecd27493feafed86702312kmillikin@chromium.org// (has not yet unwound the 0-level JS frame) does not crash. 3039155e252524a2bf92aecd27493feafed86702312kmillikin@chromium.orgTEST(TerminateAndReenterFromThreadItself) { 3044f99be9ff2091451687891a05d99cc31990de709hpayer@chromium.org v8::Isolate* isolate = CcTest::isolate(); 3054f99be9ff2091451687891a05d99cc31990de709hpayer@chromium.org v8::HandleScope scope(isolate); 306f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.org v8::Handle<v8::ObjectTemplate> global = CreateGlobalTemplate( 3074f99be9ff2091451687891a05d99cc31990de709hpayer@chromium.org isolate, TerminateCurrentThread, ReenterAfterTermination); 30857ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org v8::Handle<v8::Context> context = 3094f99be9ff2091451687891a05d99cc31990de709hpayer@chromium.org v8::Context::New(isolate, NULL, global); 3109155e252524a2bf92aecd27493feafed86702312kmillikin@chromium.org v8::Context::Scope context_scope(context); 3119155e252524a2bf92aecd27493feafed86702312kmillikin@chromium.org CHECK(!v8::V8::IsExecutionTerminating()); 312f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.org v8::Handle<v8::String> source = v8::String::NewFromUtf8( 3134f99be9ff2091451687891a05d99cc31990de709hpayer@chromium.org isolate, "try { loop(); fail(); } catch(e) { fail(); }"); 3149155e252524a2bf92aecd27493feafed86702312kmillikin@chromium.org v8::Script::Compile(source)->Run(); 3154f99be9ff2091451687891a05d99cc31990de709hpayer@chromium.org CHECK(!v8::V8::IsExecutionTerminating(isolate)); 3169155e252524a2bf92aecd27493feafed86702312kmillikin@chromium.org // Check we can run JS again after termination. 317f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.org CHECK(v8::Script::Compile( 3184f99be9ff2091451687891a05d99cc31990de709hpayer@chromium.org v8::String::NewFromUtf8(isolate, 319f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.org "function f() { return true; }" 320f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.org "f()")) 321f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.org ->Run() 322f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.org ->IsTrue()); 3239155e252524a2bf92aecd27493feafed86702312kmillikin@chromium.org} 32432d7dbafe29be06cec1edd36c31fbe2865c799f4ulan@chromium.org 325e0e1b0d3e70c933d36ed381d511e9fda39f2a751mstarzinger@chromium.org 3261510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.orgvoid DoLoopCancelTerminate(const v8::FunctionCallbackInfo<v8::Value>& args) { 32732d7dbafe29be06cec1edd36c31fbe2865c799f4ulan@chromium.org v8::TryCatch try_catch; 32832d7dbafe29be06cec1edd36c31fbe2865c799f4ulan@chromium.org CHECK(!v8::V8::IsExecutionTerminating()); 329f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.org v8::Script::Compile(v8::String::NewFromUtf8(args.GetIsolate(), 330f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.org "var term = true;" 331f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.org "while(true) {" 332f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.org " if (term) terminate();" 333f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.org " term = false;" 334f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.org "}" 335f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.org "fail();"))->Run(); 33632d7dbafe29be06cec1edd36c31fbe2865c799f4ulan@chromium.org CHECK(try_catch.HasCaught()); 33732d7dbafe29be06cec1edd36c31fbe2865c799f4ulan@chromium.org CHECK(try_catch.Exception()->IsNull()); 33832d7dbafe29be06cec1edd36c31fbe2865c799f4ulan@chromium.org CHECK(try_catch.Message().IsEmpty()); 33932d7dbafe29be06cec1edd36c31fbe2865c799f4ulan@chromium.org CHECK(!try_catch.CanContinue()); 34032d7dbafe29be06cec1edd36c31fbe2865c799f4ulan@chromium.org CHECK(v8::V8::IsExecutionTerminating()); 34132d7dbafe29be06cec1edd36c31fbe2865c799f4ulan@chromium.org CHECK(try_catch.HasTerminated()); 342528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org v8::V8::CancelTerminateExecution(CcTest::isolate()); 34332d7dbafe29be06cec1edd36c31fbe2865c799f4ulan@chromium.org CHECK(!v8::V8::IsExecutionTerminating()); 34432d7dbafe29be06cec1edd36c31fbe2865c799f4ulan@chromium.org} 34532d7dbafe29be06cec1edd36c31fbe2865c799f4ulan@chromium.org 346e0e1b0d3e70c933d36ed381d511e9fda39f2a751mstarzinger@chromium.org 34732d7dbafe29be06cec1edd36c31fbe2865c799f4ulan@chromium.org// Test that a single thread of JavaScript execution can terminate 34832d7dbafe29be06cec1edd36c31fbe2865c799f4ulan@chromium.org// itself and then resume execution. 34932d7dbafe29be06cec1edd36c31fbe2865c799f4ulan@chromium.orgTEST(TerminateCancelTerminateFromThreadItself) { 350528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org v8::Isolate* isolate = CcTest::isolate(); 351c5d4971574b7a205fa0e788d8121dc79485e5e67hpayer@chromium.org v8::HandleScope scope(isolate); 352f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.org v8::Handle<v8::ObjectTemplate> global = CreateGlobalTemplate( 353f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.org isolate, TerminateCurrentThread, DoLoopCancelTerminate); 354c5d4971574b7a205fa0e788d8121dc79485e5e67hpayer@chromium.org v8::Handle<v8::Context> context = v8::Context::New(isolate, NULL, global); 35532d7dbafe29be06cec1edd36c31fbe2865c799f4ulan@chromium.org v8::Context::Scope context_scope(context); 356528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org CHECK(!v8::V8::IsExecutionTerminating(CcTest::isolate())); 357f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.org v8::Handle<v8::String> source = v8::String::NewFromUtf8( 358f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.org isolate, "try { doloop(); } catch(e) { fail(); } 'completed';"); 35932d7dbafe29be06cec1edd36c31fbe2865c799f4ulan@chromium.org // Check that execution completed with correct return value. 36032d7dbafe29be06cec1edd36c31fbe2865c799f4ulan@chromium.org CHECK(v8::Script::Compile(source)->Run()->Equals(v8_str("completed"))); 36132d7dbafe29be06cec1edd36c31fbe2865c799f4ulan@chromium.org} 362e31b63e9608909e17e35a3330b0075140af2fe91machenbach@chromium.org 363e31b63e9608909e17e35a3330b0075140af2fe91machenbach@chromium.org 364e31b63e9608909e17e35a3330b0075140af2fe91machenbach@chromium.orgvoid MicrotaskShouldNotRun(const v8::FunctionCallbackInfo<v8::Value>& info) { 365e31b63e9608909e17e35a3330b0075140af2fe91machenbach@chromium.org CHECK(false); 366e31b63e9608909e17e35a3330b0075140af2fe91machenbach@chromium.org} 367e31b63e9608909e17e35a3330b0075140af2fe91machenbach@chromium.org 368e31b63e9608909e17e35a3330b0075140af2fe91machenbach@chromium.org 369e31b63e9608909e17e35a3330b0075140af2fe91machenbach@chromium.orgvoid MicrotaskLoopForever(const v8::FunctionCallbackInfo<v8::Value>& info) { 370e31b63e9608909e17e35a3330b0075140af2fe91machenbach@chromium.org v8::Isolate* isolate = info.GetIsolate(); 371e31b63e9608909e17e35a3330b0075140af2fe91machenbach@chromium.org v8::HandleScope scope(isolate); 372e31b63e9608909e17e35a3330b0075140af2fe91machenbach@chromium.org // Enqueue another should-not-run task to ensure we clean out the queue 373e31b63e9608909e17e35a3330b0075140af2fe91machenbach@chromium.org // when we terminate. 374e31b63e9608909e17e35a3330b0075140af2fe91machenbach@chromium.org isolate->EnqueueMicrotask(v8::Function::New(isolate, MicrotaskShouldNotRun)); 375e31b63e9608909e17e35a3330b0075140af2fe91machenbach@chromium.org CompileRun("terminate(); while (true) { }"); 376e31b63e9608909e17e35a3330b0075140af2fe91machenbach@chromium.org CHECK(v8::V8::IsExecutionTerminating()); 377e31b63e9608909e17e35a3330b0075140af2fe91machenbach@chromium.org} 378e31b63e9608909e17e35a3330b0075140af2fe91machenbach@chromium.org 379e31b63e9608909e17e35a3330b0075140af2fe91machenbach@chromium.org 380e31b63e9608909e17e35a3330b0075140af2fe91machenbach@chromium.orgTEST(TerminateFromOtherThreadWhileMicrotaskRunning) { 3815de0074a922429f5e0ec2cf140c2d2989bf88140yangguo@chromium.org semaphore = new v8::base::Semaphore(0); 382e31b63e9608909e17e35a3330b0075140af2fe91machenbach@chromium.org TerminatorThread thread(CcTest::i_isolate()); 383e31b63e9608909e17e35a3330b0075140af2fe91machenbach@chromium.org thread.Start(); 384e31b63e9608909e17e35a3330b0075140af2fe91machenbach@chromium.org 385e31b63e9608909e17e35a3330b0075140af2fe91machenbach@chromium.org v8::Isolate* isolate = CcTest::isolate(); 386e31b63e9608909e17e35a3330b0075140af2fe91machenbach@chromium.org isolate->SetAutorunMicrotasks(false); 387e31b63e9608909e17e35a3330b0075140af2fe91machenbach@chromium.org v8::HandleScope scope(isolate); 388e31b63e9608909e17e35a3330b0075140af2fe91machenbach@chromium.org v8::Handle<v8::ObjectTemplate> global = 389e31b63e9608909e17e35a3330b0075140af2fe91machenbach@chromium.org CreateGlobalTemplate(CcTest::isolate(), Signal, DoLoop); 390e31b63e9608909e17e35a3330b0075140af2fe91machenbach@chromium.org v8::Handle<v8::Context> context = 391e31b63e9608909e17e35a3330b0075140af2fe91machenbach@chromium.org v8::Context::New(CcTest::isolate(), NULL, global); 392e31b63e9608909e17e35a3330b0075140af2fe91machenbach@chromium.org v8::Context::Scope context_scope(context); 393e31b63e9608909e17e35a3330b0075140af2fe91machenbach@chromium.org isolate->EnqueueMicrotask(v8::Function::New(isolate, MicrotaskLoopForever)); 394e31b63e9608909e17e35a3330b0075140af2fe91machenbach@chromium.org // The second task should never be run because we bail out if we're 395e31b63e9608909e17e35a3330b0075140af2fe91machenbach@chromium.org // terminating. 396e31b63e9608909e17e35a3330b0075140af2fe91machenbach@chromium.org isolate->EnqueueMicrotask(v8::Function::New(isolate, MicrotaskShouldNotRun)); 397e31b63e9608909e17e35a3330b0075140af2fe91machenbach@chromium.org isolate->RunMicrotasks(); 398e31b63e9608909e17e35a3330b0075140af2fe91machenbach@chromium.org 399e31b63e9608909e17e35a3330b0075140af2fe91machenbach@chromium.org v8::V8::CancelTerminateExecution(isolate); 400e31b63e9608909e17e35a3330b0075140af2fe91machenbach@chromium.org isolate->RunMicrotasks(); // should not run MicrotaskShouldNotRun 401e31b63e9608909e17e35a3330b0075140af2fe91machenbach@chromium.org 402e31b63e9608909e17e35a3330b0075140af2fe91machenbach@chromium.org thread.Join(); 403e31b63e9608909e17e35a3330b0075140af2fe91machenbach@chromium.org delete semaphore; 404e31b63e9608909e17e35a3330b0075140af2fe91machenbach@chromium.org semaphore = NULL; 405e31b63e9608909e17e35a3330b0075140af2fe91machenbach@chromium.org} 406d0bddc653152f270a27fe32d5d7b0f5c0fa3b00cmachenbach@chromium.org 407d0bddc653152f270a27fe32d5d7b0f5c0fa3b00cmachenbach@chromium.org 408d0bddc653152f270a27fe32d5d7b0f5c0fa3b00cmachenbach@chromium.orgstatic int callback_counter = 0; 409d0bddc653152f270a27fe32d5d7b0f5c0fa3b00cmachenbach@chromium.org 410d0bddc653152f270a27fe32d5d7b0f5c0fa3b00cmachenbach@chromium.org 411d0bddc653152f270a27fe32d5d7b0f5c0fa3b00cmachenbach@chromium.orgstatic void CounterCallback(v8::Isolate* isolate, void* data) { 412d0bddc653152f270a27fe32d5d7b0f5c0fa3b00cmachenbach@chromium.org callback_counter++; 413d0bddc653152f270a27fe32d5d7b0f5c0fa3b00cmachenbach@chromium.org} 414d0bddc653152f270a27fe32d5d7b0f5c0fa3b00cmachenbach@chromium.org 415d0bddc653152f270a27fe32d5d7b0f5c0fa3b00cmachenbach@chromium.org 416d0bddc653152f270a27fe32d5d7b0f5c0fa3b00cmachenbach@chromium.orgTEST(PostponeTerminateException) { 417d0bddc653152f270a27fe32d5d7b0f5c0fa3b00cmachenbach@chromium.org v8::Isolate* isolate = CcTest::isolate(); 418d0bddc653152f270a27fe32d5d7b0f5c0fa3b00cmachenbach@chromium.org v8::HandleScope scope(isolate); 419d0bddc653152f270a27fe32d5d7b0f5c0fa3b00cmachenbach@chromium.org v8::Handle<v8::ObjectTemplate> global = 420d0bddc653152f270a27fe32d5d7b0f5c0fa3b00cmachenbach@chromium.org CreateGlobalTemplate(CcTest::isolate(), TerminateCurrentThread, DoLoop); 421d0bddc653152f270a27fe32d5d7b0f5c0fa3b00cmachenbach@chromium.org v8::Handle<v8::Context> context = 422d0bddc653152f270a27fe32d5d7b0f5c0fa3b00cmachenbach@chromium.org v8::Context::New(CcTest::isolate(), NULL, global); 423d0bddc653152f270a27fe32d5d7b0f5c0fa3b00cmachenbach@chromium.org v8::Context::Scope context_scope(context); 424d0bddc653152f270a27fe32d5d7b0f5c0fa3b00cmachenbach@chromium.org 425d0bddc653152f270a27fe32d5d7b0f5c0fa3b00cmachenbach@chromium.org v8::TryCatch try_catch; 426d0bddc653152f270a27fe32d5d7b0f5c0fa3b00cmachenbach@chromium.org static const char* terminate_and_loop = 427d0bddc653152f270a27fe32d5d7b0f5c0fa3b00cmachenbach@chromium.org "terminate(); for (var i = 0; i < 10000; i++);"; 428d0bddc653152f270a27fe32d5d7b0f5c0fa3b00cmachenbach@chromium.org 429d0bddc653152f270a27fe32d5d7b0f5c0fa3b00cmachenbach@chromium.org { // Postpone terminate execution interrupts. 430d0bddc653152f270a27fe32d5d7b0f5c0fa3b00cmachenbach@chromium.org i::PostponeInterruptsScope p1(CcTest::i_isolate(), 431d0bddc653152f270a27fe32d5d7b0f5c0fa3b00cmachenbach@chromium.org i::StackGuard::TERMINATE_EXECUTION) ; 432d0bddc653152f270a27fe32d5d7b0f5c0fa3b00cmachenbach@chromium.org 433d0bddc653152f270a27fe32d5d7b0f5c0fa3b00cmachenbach@chromium.org // API interrupts should still be triggered. 434d0bddc653152f270a27fe32d5d7b0f5c0fa3b00cmachenbach@chromium.org CcTest::isolate()->RequestInterrupt(&CounterCallback, NULL); 435d0bddc653152f270a27fe32d5d7b0f5c0fa3b00cmachenbach@chromium.org CHECK_EQ(0, callback_counter); 436d0bddc653152f270a27fe32d5d7b0f5c0fa3b00cmachenbach@chromium.org CompileRun(terminate_and_loop); 437d0bddc653152f270a27fe32d5d7b0f5c0fa3b00cmachenbach@chromium.org CHECK(!try_catch.HasTerminated()); 438d0bddc653152f270a27fe32d5d7b0f5c0fa3b00cmachenbach@chromium.org CHECK_EQ(1, callback_counter); 439d0bddc653152f270a27fe32d5d7b0f5c0fa3b00cmachenbach@chromium.org 440d0bddc653152f270a27fe32d5d7b0f5c0fa3b00cmachenbach@chromium.org { // Postpone API interrupts as well. 441d0bddc653152f270a27fe32d5d7b0f5c0fa3b00cmachenbach@chromium.org i::PostponeInterruptsScope p2(CcTest::i_isolate(), 442d0bddc653152f270a27fe32d5d7b0f5c0fa3b00cmachenbach@chromium.org i::StackGuard::API_INTERRUPT); 443d0bddc653152f270a27fe32d5d7b0f5c0fa3b00cmachenbach@chromium.org 444d0bddc653152f270a27fe32d5d7b0f5c0fa3b00cmachenbach@chromium.org // None of the two interrupts should trigger. 445d0bddc653152f270a27fe32d5d7b0f5c0fa3b00cmachenbach@chromium.org CcTest::isolate()->RequestInterrupt(&CounterCallback, NULL); 446d0bddc653152f270a27fe32d5d7b0f5c0fa3b00cmachenbach@chromium.org CompileRun(terminate_and_loop); 447d0bddc653152f270a27fe32d5d7b0f5c0fa3b00cmachenbach@chromium.org CHECK(!try_catch.HasTerminated()); 448d0bddc653152f270a27fe32d5d7b0f5c0fa3b00cmachenbach@chromium.org CHECK_EQ(1, callback_counter); 449d0bddc653152f270a27fe32d5d7b0f5c0fa3b00cmachenbach@chromium.org } 450d0bddc653152f270a27fe32d5d7b0f5c0fa3b00cmachenbach@chromium.org 451d0bddc653152f270a27fe32d5d7b0f5c0fa3b00cmachenbach@chromium.org // Now the previously requested API interrupt should trigger. 452d0bddc653152f270a27fe32d5d7b0f5c0fa3b00cmachenbach@chromium.org CompileRun(terminate_and_loop); 453d0bddc653152f270a27fe32d5d7b0f5c0fa3b00cmachenbach@chromium.org CHECK(!try_catch.HasTerminated()); 454d0bddc653152f270a27fe32d5d7b0f5c0fa3b00cmachenbach@chromium.org CHECK_EQ(2, callback_counter); 455d0bddc653152f270a27fe32d5d7b0f5c0fa3b00cmachenbach@chromium.org } 456d0bddc653152f270a27fe32d5d7b0f5c0fa3b00cmachenbach@chromium.org 457d0bddc653152f270a27fe32d5d7b0f5c0fa3b00cmachenbach@chromium.org // Now the previously requested terminate execution interrupt should trigger. 458d0bddc653152f270a27fe32d5d7b0f5c0fa3b00cmachenbach@chromium.org CompileRun("for (var i = 0; i < 10000; i++);"); 459d0bddc653152f270a27fe32d5d7b0f5c0fa3b00cmachenbach@chromium.org CHECK(try_catch.HasTerminated()); 460d0bddc653152f270a27fe32d5d7b0f5c0fa3b00cmachenbach@chromium.org CHECK_EQ(2, callback_counter); 461d0bddc653152f270a27fe32d5d7b0f5c0fa3b00cmachenbach@chromium.org} 462ada3a6017e603965f87fa34f6e2fa60379e8d697machenbach@chromium.org 463ada3a6017e603965f87fa34f6e2fa60379e8d697machenbach@chromium.org 464ada3a6017e603965f87fa34f6e2fa60379e8d697machenbach@chromium.orgTEST(ErrorObjectAfterTermination) { 465ada3a6017e603965f87fa34f6e2fa60379e8d697machenbach@chromium.org v8::Isolate* isolate = CcTest::isolate(); 466ada3a6017e603965f87fa34f6e2fa60379e8d697machenbach@chromium.org v8::HandleScope scope(isolate); 467ada3a6017e603965f87fa34f6e2fa60379e8d697machenbach@chromium.org v8::Handle<v8::Context> context = v8::Context::New(CcTest::isolate()); 468ada3a6017e603965f87fa34f6e2fa60379e8d697machenbach@chromium.org v8::Context::Scope context_scope(context); 469ada3a6017e603965f87fa34f6e2fa60379e8d697machenbach@chromium.org v8::V8::TerminateExecution(isolate); 470ada3a6017e603965f87fa34f6e2fa60379e8d697machenbach@chromium.org v8::Local<v8::Value> error = v8::Exception::Error(v8_str("error")); 471ada3a6017e603965f87fa34f6e2fa60379e8d697machenbach@chromium.org // TODO(yangguo): crbug/403509. Check for empty handle instead. 472ada3a6017e603965f87fa34f6e2fa60379e8d697machenbach@chromium.org CHECK(error->IsUndefined()); 473ada3a6017e603965f87fa34f6e2fa60379e8d697machenbach@chromium.org} 474