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 "src/platform.h"
30196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org#include "test/cctest/cctest.h"
31c81c894dabeceb472d668027ca59e73096f5cfafsgjesse@chromium.org
32c81c894dabeceb472d668027ca59e73096f5cfafsgjesse@chromium.org
33c81c894dabeceb472d668027ca59e73096f5cfafsgjesse@chromium.orgv8::internal::Semaphore* semaphore = NULL;
34c81c894dabeceb472d668027ca59e73096f5cfafsgjesse@chromium.org
35c81c894dabeceb472d668027ca59e73096f5cfafsgjesse@chromium.org
361510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.orgvoid Signal(const v8::FunctionCallbackInfo<v8::Value>& args) {
37c81c894dabeceb472d668027ca59e73096f5cfafsgjesse@chromium.org  semaphore->Signal();
38c81c894dabeceb472d668027ca59e73096f5cfafsgjesse@chromium.org}
39c81c894dabeceb472d668027ca59e73096f5cfafsgjesse@chromium.org
40c81c894dabeceb472d668027ca59e73096f5cfafsgjesse@chromium.org
411510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.orgvoid TerminateCurrentThread(const v8::FunctionCallbackInfo<v8::Value>& args) {
42528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org  CHECK(!v8::V8::IsExecutionTerminating(args.GetIsolate()));
43528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org  v8::V8::TerminateExecution(args.GetIsolate());
44c81c894dabeceb472d668027ca59e73096f5cfafsgjesse@chromium.org}
45c81c894dabeceb472d668027ca59e73096f5cfafsgjesse@chromium.org
46c81c894dabeceb472d668027ca59e73096f5cfafsgjesse@chromium.org
471510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.orgvoid Fail(const v8::FunctionCallbackInfo<v8::Value>& args) {
48c81c894dabeceb472d668027ca59e73096f5cfafsgjesse@chromium.org  CHECK(false);
49c81c894dabeceb472d668027ca59e73096f5cfafsgjesse@chromium.org}
50c81c894dabeceb472d668027ca59e73096f5cfafsgjesse@chromium.org
51c81c894dabeceb472d668027ca59e73096f5cfafsgjesse@chromium.org
521510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.orgvoid Loop(const v8::FunctionCallbackInfo<v8::Value>& args) {
53528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org  CHECK(!v8::V8::IsExecutionTerminating(args.GetIsolate()));
54f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.org  v8::Handle<v8::String> source = v8::String::NewFromUtf8(
55f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.org      args.GetIsolate(), "try { doloop(); fail(); } catch(e) { fail(); }");
562ab99526496cda7ff426115c76a1c475a1b4f4a5sgjesse@chromium.org  v8::Handle<v8::Value> result = v8::Script::Compile(source)->Run();
572ab99526496cda7ff426115c76a1c475a1b4f4a5sgjesse@chromium.org  CHECK(result.IsEmpty());
58528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org  CHECK(v8::V8::IsExecutionTerminating(args.GetIsolate()));
59c81c894dabeceb472d668027ca59e73096f5cfafsgjesse@chromium.org}
60c81c894dabeceb472d668027ca59e73096f5cfafsgjesse@chromium.org
61c81c894dabeceb472d668027ca59e73096f5cfafsgjesse@chromium.org
621510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.orgvoid DoLoop(const v8::FunctionCallbackInfo<v8::Value>& args) {
63c81c894dabeceb472d668027ca59e73096f5cfafsgjesse@chromium.org  v8::TryCatch try_catch;
64528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org  CHECK(!v8::V8::IsExecutionTerminating(args.GetIsolate()));
65f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.org  v8::Script::Compile(v8::String::NewFromUtf8(args.GetIsolate(),
66f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.org                                              "function f() {"
67f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.org                                              "  var term = true;"
68f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.org                                              "  try {"
69f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.org                                              "    while(true) {"
70f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.org                                              "      if (term) terminate();"
71f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.org                                              "      term = false;"
72f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.org                                              "    }"
73f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.org                                              "    fail();"
74f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.org                                              "  } catch(e) {"
75f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.org                                              "    fail();"
76f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.org                                              "  }"
77f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.org                                              "}"
78f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.org                                              "f()"))->Run();
79c81c894dabeceb472d668027ca59e73096f5cfafsgjesse@chromium.org  CHECK(try_catch.HasCaught());
80c81c894dabeceb472d668027ca59e73096f5cfafsgjesse@chromium.org  CHECK(try_catch.Exception()->IsNull());
81c81c894dabeceb472d668027ca59e73096f5cfafsgjesse@chromium.org  CHECK(try_catch.Message().IsEmpty());
82c81c894dabeceb472d668027ca59e73096f5cfafsgjesse@chromium.org  CHECK(!try_catch.CanContinue());
83528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org  CHECK(v8::V8::IsExecutionTerminating(args.GetIsolate()));
84c81c894dabeceb472d668027ca59e73096f5cfafsgjesse@chromium.org}
85c81c894dabeceb472d668027ca59e73096f5cfafsgjesse@chromium.org
86c81c894dabeceb472d668027ca59e73096f5cfafsgjesse@chromium.org
871510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.orgvoid DoLoopNoCall(const v8::FunctionCallbackInfo<v8::Value>& args) {
8801beca7f8d9f549e04ec575a0bca96d859ab55a5ager@chromium.org  v8::TryCatch try_catch;
89528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org  CHECK(!v8::V8::IsExecutionTerminating(args.GetIsolate()));
90f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.org  v8::Script::Compile(v8::String::NewFromUtf8(args.GetIsolate(),
91f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.org                                              "var term = true;"
92f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.org                                              "while(true) {"
93f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.org                                              "  if (term) terminate();"
94f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.org                                              "  term = false;"
95f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.org                                              "}"))->Run();
9601beca7f8d9f549e04ec575a0bca96d859ab55a5ager@chromium.org  CHECK(try_catch.HasCaught());
9701beca7f8d9f549e04ec575a0bca96d859ab55a5ager@chromium.org  CHECK(try_catch.Exception()->IsNull());
9801beca7f8d9f549e04ec575a0bca96d859ab55a5ager@chromium.org  CHECK(try_catch.Message().IsEmpty());
9901beca7f8d9f549e04ec575a0bca96d859ab55a5ager@chromium.org  CHECK(!try_catch.CanContinue());
100528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org  CHECK(v8::V8::IsExecutionTerminating(args.GetIsolate()));
10101beca7f8d9f549e04ec575a0bca96d859ab55a5ager@chromium.org}
10201beca7f8d9f549e04ec575a0bca96d859ab55a5ager@chromium.org
10301beca7f8d9f549e04ec575a0bca96d859ab55a5ager@chromium.org
104c81c894dabeceb472d668027ca59e73096f5cfafsgjesse@chromium.orgv8::Handle<v8::ObjectTemplate> CreateGlobalTemplate(
105f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.org    v8::Isolate* isolate,
1061510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org    v8::FunctionCallback terminate,
1071510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org    v8::FunctionCallback doloop) {
1089cbaabda8b4daeb06759ace10c926ab55bb69d7bulan@chromium.org  v8::Handle<v8::ObjectTemplate> global = v8::ObjectTemplate::New(isolate);
109f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.org  global->Set(v8::String::NewFromUtf8(isolate, "terminate"),
1104f99be9ff2091451687891a05d99cc31990de709hpayer@chromium.org              v8::FunctionTemplate::New(isolate, terminate));
111f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.org  global->Set(v8::String::NewFromUtf8(isolate, "fail"),
1124f99be9ff2091451687891a05d99cc31990de709hpayer@chromium.org              v8::FunctionTemplate::New(isolate, Fail));
113f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.org  global->Set(v8::String::NewFromUtf8(isolate, "loop"),
1144f99be9ff2091451687891a05d99cc31990de709hpayer@chromium.org              v8::FunctionTemplate::New(isolate, Loop));
115f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.org  global->Set(v8::String::NewFromUtf8(isolate, "doloop"),
1164f99be9ff2091451687891a05d99cc31990de709hpayer@chromium.org              v8::FunctionTemplate::New(isolate, doloop));
117c81c894dabeceb472d668027ca59e73096f5cfafsgjesse@chromium.org  return global;
118c81c894dabeceb472d668027ca59e73096f5cfafsgjesse@chromium.org}
119c81c894dabeceb472d668027ca59e73096f5cfafsgjesse@chromium.org
120c81c894dabeceb472d668027ca59e73096f5cfafsgjesse@chromium.org
121c81c894dabeceb472d668027ca59e73096f5cfafsgjesse@chromium.org// Test that a single thread of JavaScript execution can terminate
122c81c894dabeceb472d668027ca59e73096f5cfafsgjesse@chromium.org// itself.
123c81c894dabeceb472d668027ca59e73096f5cfafsgjesse@chromium.orgTEST(TerminateOnlyV8ThreadFromThreadItself) {
124528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org  v8::HandleScope scope(CcTest::isolate());
125c81c894dabeceb472d668027ca59e73096f5cfafsgjesse@chromium.org  v8::Handle<v8::ObjectTemplate> global =
126f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.org      CreateGlobalTemplate(CcTest::isolate(), TerminateCurrentThread, DoLoop);
12757ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org  v8::Handle<v8::Context> context =
128528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org      v8::Context::New(CcTest::isolate(), NULL, global);
12901beca7f8d9f549e04ec575a0bca96d859ab55a5ager@chromium.org  v8::Context::Scope context_scope(context);
130528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org  CHECK(!v8::V8::IsExecutionTerminating(CcTest::isolate()));
13101beca7f8d9f549e04ec575a0bca96d859ab55a5ager@chromium.org  // Run a loop that will be infinite if thread termination does not work.
132f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.org  v8::Handle<v8::String> source = v8::String::NewFromUtf8(
133f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.org      CcTest::isolate(), "try { loop(); fail(); } catch(e) { fail(); }");
13401beca7f8d9f549e04ec575a0bca96d859ab55a5ager@chromium.org  v8::Script::Compile(source)->Run();
13501beca7f8d9f549e04ec575a0bca96d859ab55a5ager@chromium.org  // Test that we can run the code again after thread termination.
136528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org  CHECK(!v8::V8::IsExecutionTerminating(CcTest::isolate()));
13701beca7f8d9f549e04ec575a0bca96d859ab55a5ager@chromium.org  v8::Script::Compile(source)->Run();
13801beca7f8d9f549e04ec575a0bca96d859ab55a5ager@chromium.org}
13901beca7f8d9f549e04ec575a0bca96d859ab55a5ager@chromium.org
14001beca7f8d9f549e04ec575a0bca96d859ab55a5ager@chromium.org
14101beca7f8d9f549e04ec575a0bca96d859ab55a5ager@chromium.org// Test that a single thread of JavaScript execution can terminate
14201beca7f8d9f549e04ec575a0bca96d859ab55a5ager@chromium.org// itself in a loop that performs no calls.
14301beca7f8d9f549e04ec575a0bca96d859ab55a5ager@chromium.orgTEST(TerminateOnlyV8ThreadFromThreadItselfNoLoop) {
144528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org  v8::HandleScope scope(CcTest::isolate());
145f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.org  v8::Handle<v8::ObjectTemplate> global = CreateGlobalTemplate(
146f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.org      CcTest::isolate(), TerminateCurrentThread, DoLoopNoCall);
14757ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org  v8::Handle<v8::Context> context =
148528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org      v8::Context::New(CcTest::isolate(), NULL, global);
149c81c894dabeceb472d668027ca59e73096f5cfafsgjesse@chromium.org  v8::Context::Scope context_scope(context);
150528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org  CHECK(!v8::V8::IsExecutionTerminating(CcTest::isolate()));
151c81c894dabeceb472d668027ca59e73096f5cfafsgjesse@chromium.org  // Run a loop that will be infinite if thread termination does not work.
152f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.org  v8::Handle<v8::String> source = v8::String::NewFromUtf8(
153f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.org      CcTest::isolate(), "try { loop(); fail(); } catch(e) { fail(); }");
154c81c894dabeceb472d668027ca59e73096f5cfafsgjesse@chromium.org  v8::Script::Compile(source)->Run();
155528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org  CHECK(!v8::V8::IsExecutionTerminating(CcTest::isolate()));
156c81c894dabeceb472d668027ca59e73096f5cfafsgjesse@chromium.org  // Test that we can run the code again after thread termination.
157c81c894dabeceb472d668027ca59e73096f5cfafsgjesse@chromium.org  v8::Script::Compile(source)->Run();
158c81c894dabeceb472d668027ca59e73096f5cfafsgjesse@chromium.org}
159c81c894dabeceb472d668027ca59e73096f5cfafsgjesse@chromium.org
160c81c894dabeceb472d668027ca59e73096f5cfafsgjesse@chromium.org
161c81c894dabeceb472d668027ca59e73096f5cfafsgjesse@chromium.orgclass TerminatorThread : public v8::internal::Thread {
162ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org public:
163ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  explicit TerminatorThread(i::Isolate* isolate)
1646d786c9805481bd13ecb29c3155540f2f32950e1svenpanne@chromium.org      : Thread("TerminatorThread"),
1656d786c9805481bd13ecb29c3155540f2f32950e1svenpanne@chromium.org        isolate_(reinterpret_cast<v8::Isolate*>(isolate)) { }
166c81c894dabeceb472d668027ca59e73096f5cfafsgjesse@chromium.org  void Run() {
167c81c894dabeceb472d668027ca59e73096f5cfafsgjesse@chromium.org    semaphore->Wait();
1686d786c9805481bd13ecb29c3155540f2f32950e1svenpanne@chromium.org    CHECK(!v8::V8::IsExecutionTerminating(isolate_));
1696d786c9805481bd13ecb29c3155540f2f32950e1svenpanne@chromium.org    v8::V8::TerminateExecution(isolate_);
170c81c894dabeceb472d668027ca59e73096f5cfafsgjesse@chromium.org  }
1716d786c9805481bd13ecb29c3155540f2f32950e1svenpanne@chromium.org
1726d786c9805481bd13ecb29c3155540f2f32950e1svenpanne@chromium.org private:
1736d786c9805481bd13ecb29c3155540f2f32950e1svenpanne@chromium.org  v8::Isolate* isolate_;
174c81c894dabeceb472d668027ca59e73096f5cfafsgjesse@chromium.org};
175c81c894dabeceb472d668027ca59e73096f5cfafsgjesse@chromium.org
176c81c894dabeceb472d668027ca59e73096f5cfafsgjesse@chromium.org
177c81c894dabeceb472d668027ca59e73096f5cfafsgjesse@chromium.org// Test that a single thread of JavaScript execution can be terminated
178c81c894dabeceb472d668027ca59e73096f5cfafsgjesse@chromium.org// from the side by another thread.
179c81c894dabeceb472d668027ca59e73096f5cfafsgjesse@chromium.orgTEST(TerminateOnlyV8ThreadFromOtherThread) {
180e900018c7a2a695fde788911564da37535c7e736mstarzinger@chromium.org  semaphore = new v8::internal::Semaphore(0);
181528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org  TerminatorThread thread(CcTest::i_isolate());
182c81c894dabeceb472d668027ca59e73096f5cfafsgjesse@chromium.org  thread.Start();
183c81c894dabeceb472d668027ca59e73096f5cfafsgjesse@chromium.org
184528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org  v8::HandleScope scope(CcTest::isolate());
185f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.org  v8::Handle<v8::ObjectTemplate> global =
186f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.org      CreateGlobalTemplate(CcTest::isolate(), Signal, DoLoop);
18757ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org  v8::Handle<v8::Context> context =
188528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org      v8::Context::New(CcTest::isolate(), NULL, global);
189c81c894dabeceb472d668027ca59e73096f5cfafsgjesse@chromium.org  v8::Context::Scope context_scope(context);
190528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org  CHECK(!v8::V8::IsExecutionTerminating(CcTest::isolate()));
191c81c894dabeceb472d668027ca59e73096f5cfafsgjesse@chromium.org  // Run a loop that will be infinite if thread termination does not work.
192f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.org  v8::Handle<v8::String> source = v8::String::NewFromUtf8(
193f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.org      CcTest::isolate(), "try { loop(); fail(); } catch(e) { fail(); }");
194c81c894dabeceb472d668027ca59e73096f5cfafsgjesse@chromium.org  v8::Script::Compile(source)->Run();
195c81c894dabeceb472d668027ca59e73096f5cfafsgjesse@chromium.org
196c81c894dabeceb472d668027ca59e73096f5cfafsgjesse@chromium.org  thread.Join();
197c81c894dabeceb472d668027ca59e73096f5cfafsgjesse@chromium.org  delete semaphore;
198c81c894dabeceb472d668027ca59e73096f5cfafsgjesse@chromium.org  semaphore = NULL;
199c81c894dabeceb472d668027ca59e73096f5cfafsgjesse@chromium.org}
200c81c894dabeceb472d668027ca59e73096f5cfafsgjesse@chromium.org
201c81c894dabeceb472d668027ca59e73096f5cfafsgjesse@chromium.org
20218ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.orgint call_count = 0;
20318ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org
20418ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org
2051510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.orgvoid TerminateOrReturnObject(const v8::FunctionCallbackInfo<v8::Value>& args) {
20618ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org  if (++call_count == 10) {
207528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org    CHECK(!v8::V8::IsExecutionTerminating(args.GetIsolate()));
208528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org    v8::V8::TerminateExecution(args.GetIsolate());
2091510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org    return;
21018ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org  }
2110f13e74b7310d8b14f19c6b93b36ff95059f97f6ulan@chromium.org  v8::Local<v8::Object> result = v8::Object::New(args.GetIsolate());
212f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.org  result->Set(v8::String::NewFromUtf8(args.GetIsolate(), "x"),
2130f13e74b7310d8b14f19c6b93b36ff95059f97f6ulan@chromium.org              v8::Integer::New(args.GetIsolate(), 42));
2141510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org  args.GetReturnValue().Set(result);
21518ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org}
21618ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org
21718ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org
2181510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.orgvoid LoopGetProperty(const v8::FunctionCallbackInfo<v8::Value>& args) {
21918ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org  v8::TryCatch try_catch;
220528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org  CHECK(!v8::V8::IsExecutionTerminating(args.GetIsolate()));
221f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.org  v8::Script::Compile(
222f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.org      v8::String::NewFromUtf8(args.GetIsolate(),
223f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.org                              "function f() {"
224f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.org                              "  try {"
225f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.org                              "    while(true) {"
226f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.org                              "      terminate_or_return_object().x;"
227f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.org                              "    }"
228f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.org                              "    fail();"
229f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.org                              "  } catch(e) {"
230f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.org                              "    fail();"
231f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.org                              "  }"
232f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.org                              "}"
233f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.org                              "f()"))->Run();
23418ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org  CHECK(try_catch.HasCaught());
23518ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org  CHECK(try_catch.Exception()->IsNull());
23618ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org  CHECK(try_catch.Message().IsEmpty());
23718ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org  CHECK(!try_catch.CanContinue());
238528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org  CHECK(v8::V8::IsExecutionTerminating(args.GetIsolate()));
23918ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org}
24018ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org
24118ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org
24218ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org// Test that we correctly handle termination exceptions if they are
24318ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org// triggered by the creation of error objects in connection with ICs.
24418ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.orgTEST(TerminateLoadICException) {
2454f99be9ff2091451687891a05d99cc31990de709hpayer@chromium.org  v8::Isolate* isolate = CcTest::isolate();
2464f99be9ff2091451687891a05d99cc31990de709hpayer@chromium.org  v8::HandleScope scope(isolate);
2479cbaabda8b4daeb06759ace10c926ab55bb69d7bulan@chromium.org  v8::Handle<v8::ObjectTemplate> global = v8::ObjectTemplate::New(isolate);
248f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.org  global->Set(
2494f99be9ff2091451687891a05d99cc31990de709hpayer@chromium.org      v8::String::NewFromUtf8(isolate, "terminate_or_return_object"),
2504f99be9ff2091451687891a05d99cc31990de709hpayer@chromium.org      v8::FunctionTemplate::New(isolate, TerminateOrReturnObject));
2514f99be9ff2091451687891a05d99cc31990de709hpayer@chromium.org  global->Set(v8::String::NewFromUtf8(isolate, "fail"),
2524f99be9ff2091451687891a05d99cc31990de709hpayer@chromium.org              v8::FunctionTemplate::New(isolate, Fail));
2534f99be9ff2091451687891a05d99cc31990de709hpayer@chromium.org  global->Set(v8::String::NewFromUtf8(isolate, "loop"),
2544f99be9ff2091451687891a05d99cc31990de709hpayer@chromium.org              v8::FunctionTemplate::New(isolate, LoopGetProperty));
25518ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org
25657ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org  v8::Handle<v8::Context> context =
2574f99be9ff2091451687891a05d99cc31990de709hpayer@chromium.org      v8::Context::New(isolate, NULL, global);
25818ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org  v8::Context::Scope context_scope(context);
2594f99be9ff2091451687891a05d99cc31990de709hpayer@chromium.org  CHECK(!v8::V8::IsExecutionTerminating(isolate));
26018ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org  // Run a loop that will be infinite if thread termination does not work.
261f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.org  v8::Handle<v8::String> source = v8::String::NewFromUtf8(
2624f99be9ff2091451687891a05d99cc31990de709hpayer@chromium.org      isolate, "try { loop(); fail(); } catch(e) { fail(); }");
26318ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org  call_count = 0;
26418ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org  v8::Script::Compile(source)->Run();
26518ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org  // Test that we can run the code again after thread termination.
2664f99be9ff2091451687891a05d99cc31990de709hpayer@chromium.org  CHECK(!v8::V8::IsExecutionTerminating(isolate));
26718ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org  call_count = 0;
26818ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org  v8::Script::Compile(source)->Run();
26918ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org}
2709155e252524a2bf92aecd27493feafed86702312kmillikin@chromium.org
271e0e1b0d3e70c933d36ed381d511e9fda39f2a751mstarzinger@chromium.org
2721510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.orgvoid ReenterAfterTermination(const v8::FunctionCallbackInfo<v8::Value>& args) {
2739155e252524a2bf92aecd27493feafed86702312kmillikin@chromium.org  v8::TryCatch try_catch;
274528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org  CHECK(!v8::V8::IsExecutionTerminating(args.GetIsolate()));
275f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.org  v8::Script::Compile(v8::String::NewFromUtf8(args.GetIsolate(),
276f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.org                                              "function f() {"
277f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.org                                              "  var term = true;"
278f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.org                                              "  try {"
279f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.org                                              "    while(true) {"
280f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.org                                              "      if (term) terminate();"
281f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.org                                              "      term = false;"
282f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.org                                              "    }"
283f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.org                                              "    fail();"
284f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.org                                              "  } catch(e) {"
285f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.org                                              "    fail();"
286f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.org                                              "  }"
287f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.org                                              "}"
288f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.org                                              "f()"))->Run();
2899155e252524a2bf92aecd27493feafed86702312kmillikin@chromium.org  CHECK(try_catch.HasCaught());
2909155e252524a2bf92aecd27493feafed86702312kmillikin@chromium.org  CHECK(try_catch.Exception()->IsNull());
2919155e252524a2bf92aecd27493feafed86702312kmillikin@chromium.org  CHECK(try_catch.Message().IsEmpty());
2929155e252524a2bf92aecd27493feafed86702312kmillikin@chromium.org  CHECK(!try_catch.CanContinue());
293528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org  CHECK(v8::V8::IsExecutionTerminating(args.GetIsolate()));
294f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.org  v8::Script::Compile(v8::String::NewFromUtf8(args.GetIsolate(),
295f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.org                                              "function f() { fail(); } f()"))
296f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.org      ->Run();
2979155e252524a2bf92aecd27493feafed86702312kmillikin@chromium.org}
2989155e252524a2bf92aecd27493feafed86702312kmillikin@chromium.org
299e0e1b0d3e70c933d36ed381d511e9fda39f2a751mstarzinger@chromium.org
3009155e252524a2bf92aecd27493feafed86702312kmillikin@chromium.org// Test that reentry into V8 while the termination exception is still pending
3019155e252524a2bf92aecd27493feafed86702312kmillikin@chromium.org// (has not yet unwound the 0-level JS frame) does not crash.
3029155e252524a2bf92aecd27493feafed86702312kmillikin@chromium.orgTEST(TerminateAndReenterFromThreadItself) {
3034f99be9ff2091451687891a05d99cc31990de709hpayer@chromium.org  v8::Isolate* isolate = CcTest::isolate();
3044f99be9ff2091451687891a05d99cc31990de709hpayer@chromium.org  v8::HandleScope scope(isolate);
305f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.org  v8::Handle<v8::ObjectTemplate> global = CreateGlobalTemplate(
3064f99be9ff2091451687891a05d99cc31990de709hpayer@chromium.org      isolate, TerminateCurrentThread, ReenterAfterTermination);
30757ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org  v8::Handle<v8::Context> context =
3084f99be9ff2091451687891a05d99cc31990de709hpayer@chromium.org      v8::Context::New(isolate, NULL, global);
3099155e252524a2bf92aecd27493feafed86702312kmillikin@chromium.org  v8::Context::Scope context_scope(context);
3109155e252524a2bf92aecd27493feafed86702312kmillikin@chromium.org  CHECK(!v8::V8::IsExecutionTerminating());
311f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.org  v8::Handle<v8::String> source = v8::String::NewFromUtf8(
3124f99be9ff2091451687891a05d99cc31990de709hpayer@chromium.org      isolate, "try { loop(); fail(); } catch(e) { fail(); }");
3139155e252524a2bf92aecd27493feafed86702312kmillikin@chromium.org  v8::Script::Compile(source)->Run();
3144f99be9ff2091451687891a05d99cc31990de709hpayer@chromium.org  CHECK(!v8::V8::IsExecutionTerminating(isolate));
3159155e252524a2bf92aecd27493feafed86702312kmillikin@chromium.org  // Check we can run JS again after termination.
316f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.org  CHECK(v8::Script::Compile(
3174f99be9ff2091451687891a05d99cc31990de709hpayer@chromium.org      v8::String::NewFromUtf8(isolate,
318f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.org                              "function f() { return true; }"
319f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.org                              "f()"))
320f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.org            ->Run()
321f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.org            ->IsTrue());
3229155e252524a2bf92aecd27493feafed86702312kmillikin@chromium.org}
32332d7dbafe29be06cec1edd36c31fbe2865c799f4ulan@chromium.org
324e0e1b0d3e70c933d36ed381d511e9fda39f2a751mstarzinger@chromium.org
3251510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.orgvoid DoLoopCancelTerminate(const v8::FunctionCallbackInfo<v8::Value>& args) {
32632d7dbafe29be06cec1edd36c31fbe2865c799f4ulan@chromium.org  v8::TryCatch try_catch;
32732d7dbafe29be06cec1edd36c31fbe2865c799f4ulan@chromium.org  CHECK(!v8::V8::IsExecutionTerminating());
328f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.org  v8::Script::Compile(v8::String::NewFromUtf8(args.GetIsolate(),
329f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.org                                              "var term = true;"
330f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.org                                              "while(true) {"
331f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.org                                              "  if (term) terminate();"
332f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.org                                              "  term = false;"
333f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.org                                              "}"
334f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.org                                              "fail();"))->Run();
33532d7dbafe29be06cec1edd36c31fbe2865c799f4ulan@chromium.org  CHECK(try_catch.HasCaught());
33632d7dbafe29be06cec1edd36c31fbe2865c799f4ulan@chromium.org  CHECK(try_catch.Exception()->IsNull());
33732d7dbafe29be06cec1edd36c31fbe2865c799f4ulan@chromium.org  CHECK(try_catch.Message().IsEmpty());
33832d7dbafe29be06cec1edd36c31fbe2865c799f4ulan@chromium.org  CHECK(!try_catch.CanContinue());
33932d7dbafe29be06cec1edd36c31fbe2865c799f4ulan@chromium.org  CHECK(v8::V8::IsExecutionTerminating());
34032d7dbafe29be06cec1edd36c31fbe2865c799f4ulan@chromium.org  CHECK(try_catch.HasTerminated());
341528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org  v8::V8::CancelTerminateExecution(CcTest::isolate());
34232d7dbafe29be06cec1edd36c31fbe2865c799f4ulan@chromium.org  CHECK(!v8::V8::IsExecutionTerminating());
34332d7dbafe29be06cec1edd36c31fbe2865c799f4ulan@chromium.org}
34432d7dbafe29be06cec1edd36c31fbe2865c799f4ulan@chromium.org
345e0e1b0d3e70c933d36ed381d511e9fda39f2a751mstarzinger@chromium.org
34632d7dbafe29be06cec1edd36c31fbe2865c799f4ulan@chromium.org// Test that a single thread of JavaScript execution can terminate
34732d7dbafe29be06cec1edd36c31fbe2865c799f4ulan@chromium.org// itself and then resume execution.
34832d7dbafe29be06cec1edd36c31fbe2865c799f4ulan@chromium.orgTEST(TerminateCancelTerminateFromThreadItself) {
349528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org  v8::Isolate* isolate = CcTest::isolate();
350c5d4971574b7a205fa0e788d8121dc79485e5e67hpayer@chromium.org  v8::HandleScope scope(isolate);
351f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.org  v8::Handle<v8::ObjectTemplate> global = CreateGlobalTemplate(
352f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.org      isolate, TerminateCurrentThread, DoLoopCancelTerminate);
353c5d4971574b7a205fa0e788d8121dc79485e5e67hpayer@chromium.org  v8::Handle<v8::Context> context = v8::Context::New(isolate, NULL, global);
35432d7dbafe29be06cec1edd36c31fbe2865c799f4ulan@chromium.org  v8::Context::Scope context_scope(context);
355528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org  CHECK(!v8::V8::IsExecutionTerminating(CcTest::isolate()));
356f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.org  v8::Handle<v8::String> source = v8::String::NewFromUtf8(
357f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.org      isolate, "try { doloop(); } catch(e) { fail(); } 'completed';");
35832d7dbafe29be06cec1edd36c31fbe2865c799f4ulan@chromium.org  // Check that execution completed with correct return value.
35932d7dbafe29be06cec1edd36c31fbe2865c799f4ulan@chromium.org  CHECK(v8::Script::Compile(source)->Run()->Equals(v8_str("completed")));
36032d7dbafe29be06cec1edd36c31fbe2865c799f4ulan@chromium.org}
361e31b63e9608909e17e35a3330b0075140af2fe91machenbach@chromium.org
362e31b63e9608909e17e35a3330b0075140af2fe91machenbach@chromium.org
363e31b63e9608909e17e35a3330b0075140af2fe91machenbach@chromium.orgvoid MicrotaskShouldNotRun(const v8::FunctionCallbackInfo<v8::Value>& info) {
364e31b63e9608909e17e35a3330b0075140af2fe91machenbach@chromium.org  CHECK(false);
365e31b63e9608909e17e35a3330b0075140af2fe91machenbach@chromium.org}
366e31b63e9608909e17e35a3330b0075140af2fe91machenbach@chromium.org
367e31b63e9608909e17e35a3330b0075140af2fe91machenbach@chromium.org
368e31b63e9608909e17e35a3330b0075140af2fe91machenbach@chromium.orgvoid MicrotaskLoopForever(const v8::FunctionCallbackInfo<v8::Value>& info) {
369e31b63e9608909e17e35a3330b0075140af2fe91machenbach@chromium.org  v8::Isolate* isolate = info.GetIsolate();
370e31b63e9608909e17e35a3330b0075140af2fe91machenbach@chromium.org  v8::HandleScope scope(isolate);
371e31b63e9608909e17e35a3330b0075140af2fe91machenbach@chromium.org  // Enqueue another should-not-run task to ensure we clean out the queue
372e31b63e9608909e17e35a3330b0075140af2fe91machenbach@chromium.org  // when we terminate.
373e31b63e9608909e17e35a3330b0075140af2fe91machenbach@chromium.org  isolate->EnqueueMicrotask(v8::Function::New(isolate, MicrotaskShouldNotRun));
374e31b63e9608909e17e35a3330b0075140af2fe91machenbach@chromium.org  CompileRun("terminate(); while (true) { }");
375e31b63e9608909e17e35a3330b0075140af2fe91machenbach@chromium.org  CHECK(v8::V8::IsExecutionTerminating());
376e31b63e9608909e17e35a3330b0075140af2fe91machenbach@chromium.org}
377e31b63e9608909e17e35a3330b0075140af2fe91machenbach@chromium.org
378e31b63e9608909e17e35a3330b0075140af2fe91machenbach@chromium.org
379e31b63e9608909e17e35a3330b0075140af2fe91machenbach@chromium.orgTEST(TerminateFromOtherThreadWhileMicrotaskRunning) {
380e31b63e9608909e17e35a3330b0075140af2fe91machenbach@chromium.org  semaphore = new v8::internal::Semaphore(0);
381e31b63e9608909e17e35a3330b0075140af2fe91machenbach@chromium.org  TerminatorThread thread(CcTest::i_isolate());
382e31b63e9608909e17e35a3330b0075140af2fe91machenbach@chromium.org  thread.Start();
383e31b63e9608909e17e35a3330b0075140af2fe91machenbach@chromium.org
384e31b63e9608909e17e35a3330b0075140af2fe91machenbach@chromium.org  v8::Isolate* isolate = CcTest::isolate();
385e31b63e9608909e17e35a3330b0075140af2fe91machenbach@chromium.org  isolate->SetAutorunMicrotasks(false);
386e31b63e9608909e17e35a3330b0075140af2fe91machenbach@chromium.org  v8::HandleScope scope(isolate);
387e31b63e9608909e17e35a3330b0075140af2fe91machenbach@chromium.org  v8::Handle<v8::ObjectTemplate> global =
388e31b63e9608909e17e35a3330b0075140af2fe91machenbach@chromium.org      CreateGlobalTemplate(CcTest::isolate(), Signal, DoLoop);
389e31b63e9608909e17e35a3330b0075140af2fe91machenbach@chromium.org  v8::Handle<v8::Context> context =
390e31b63e9608909e17e35a3330b0075140af2fe91machenbach@chromium.org      v8::Context::New(CcTest::isolate(), NULL, global);
391e31b63e9608909e17e35a3330b0075140af2fe91machenbach@chromium.org  v8::Context::Scope context_scope(context);
392e31b63e9608909e17e35a3330b0075140af2fe91machenbach@chromium.org  isolate->EnqueueMicrotask(v8::Function::New(isolate, MicrotaskLoopForever));
393e31b63e9608909e17e35a3330b0075140af2fe91machenbach@chromium.org  // The second task should never be run because we bail out if we're
394e31b63e9608909e17e35a3330b0075140af2fe91machenbach@chromium.org  // terminating.
395e31b63e9608909e17e35a3330b0075140af2fe91machenbach@chromium.org  isolate->EnqueueMicrotask(v8::Function::New(isolate, MicrotaskShouldNotRun));
396e31b63e9608909e17e35a3330b0075140af2fe91machenbach@chromium.org  isolate->RunMicrotasks();
397e31b63e9608909e17e35a3330b0075140af2fe91machenbach@chromium.org
398e31b63e9608909e17e35a3330b0075140af2fe91machenbach@chromium.org  v8::V8::CancelTerminateExecution(isolate);
399e31b63e9608909e17e35a3330b0075140af2fe91machenbach@chromium.org  isolate->RunMicrotasks();  // should not run MicrotaskShouldNotRun
400e31b63e9608909e17e35a3330b0075140af2fe91machenbach@chromium.org
401e31b63e9608909e17e35a3330b0075140af2fe91machenbach@chromium.org  thread.Join();
402e31b63e9608909e17e35a3330b0075140af2fe91machenbach@chromium.org  delete semaphore;
403e31b63e9608909e17e35a3330b0075140af2fe91machenbach@chromium.org  semaphore = NULL;
404e31b63e9608909e17e35a3330b0075140af2fe91machenbach@chromium.org}
405