Chromium Code Reviews| Index: test/cctest/test-thread-termination.cc |
| diff --git a/test/cctest/test-thread-termination.cc b/test/cctest/test-thread-termination.cc |
| index d31b4131dfcd2e4cf789469416c187ca7c3739a5..64524b80daaa8fbac75758c3b7a0a554656c173a 100644 |
| --- a/test/cctest/test-thread-termination.cc |
| +++ b/test/cctest/test-thread-termination.cc |
| @@ -228,6 +228,7 @@ void LoopGetProperty(const v8::FunctionCallbackInfo<v8::Value>& args) { |
| " }" |
| " fail();" |
| " } catch(e) {" |
| + " (function() {})();" // trigger stack check. |
| " fail();" |
| " }" |
| "}" |
| @@ -474,3 +475,65 @@ TEST(ErrorObjectAfterTermination) { |
| // TODO(yangguo): crbug/403509. Check for empty handle instead. |
| CHECK(error->IsUndefined()); |
| } |
| + |
| + |
| +void InnerTryCallTerminate(const v8::FunctionCallbackInfo<v8::Value>& args) { |
| + CHECK(!v8::V8::IsExecutionTerminating(args.GetIsolate())); |
| + v8::Handle<v8::Object> global = CcTest::global(); |
| + v8::Handle<v8::Function> loop = |
| + v8::Handle<v8::Function>::Cast(global->Get(v8_str("loop"))); |
| + i::MaybeHandle<i::Object> result = |
| + i::Execution::TryCall(v8::Utils::OpenHandle((*loop)), |
| + v8::Utils::OpenHandle((*global)), 0, NULL, NULL); |
| + CHECK(result.is_null()); |
| + // TryCall ignores terminate execution, but rerequests the interrupt. |
| + CHECK(!v8::V8::IsExecutionTerminating(CcTest::isolate())); |
| + CHECK(CompileRun("1+1;").IsEmpty()); |
|
Jakob Kummerow
2015/02/23 15:24:45
nit: spaces around '+'
(I guess strictly speaking
|
| +} |
| + |
| + |
| +TEST(TerminationInInnerTryCall) { |
| + v8::Isolate* isolate = CcTest::isolate(); |
| + v8::HandleScope scope(isolate); |
| + v8::Handle<v8::ObjectTemplate> global_template = CreateGlobalTemplate( |
| + CcTest::isolate(), TerminateCurrentThread, DoLoopNoCall); |
| + global_template->Set( |
| + v8_str("inner_try_call_terminate"), |
| + v8::FunctionTemplate::New(isolate, InnerTryCallTerminate)); |
| + v8::Handle<v8::Context> context = |
| + v8::Context::New(CcTest::isolate(), NULL, global_template); |
| + v8::Context::Scope context_scope(context); |
| + { |
| + v8::TryCatch try_catch; |
| + CompileRun("inner_try_call_terminate()"); |
| + CHECK(try_catch.HasTerminated()); |
| + } |
| + CHECK_EQ(4, CompileRun("2 + 2")->ToInt32()->Int32Value()); |
| + CHECK(!v8::V8::IsExecutionTerminating()); |
| +} |
| + |
| + |
| +TEST(TerminateAndTryCall) { |
| + i::FLAG_allow_natives_syntax = true; |
| + v8::Isolate* isolate = CcTest::isolate(); |
| + v8::HandleScope scope(isolate); |
| + v8::Handle<v8::ObjectTemplate> global = CreateGlobalTemplate( |
| + isolate, TerminateCurrentThread, DoLoopCancelTerminate); |
| + v8::Handle<v8::Context> context = v8::Context::New(isolate, NULL, global); |
| + v8::Context::Scope context_scope(context); |
| + CHECK(!v8::V8::IsExecutionTerminating(CcTest::isolate())); |
|
Jakob Kummerow
2015/02/23 15:24:45
nit: s/CcTest::isolate()/isolate/, it's cleaner
|
| + v8::TryCatch try_catch; |
| + CHECK(!v8::V8::IsExecutionTerminating()); |
|
Jakob Kummerow
2015/02/23 15:24:45
nit: pass in the isolate, here and below (I'm kind
|
| + // Terminate execution has been triggered inside TryCall, but re-requested |
| + // to trigger later. |
| + CHECK(CompileRun("terminate(); reference_error();").IsEmpty()); |
| + CHECK(try_catch.HasCaught()); |
| + CHECK(!v8::V8::IsExecutionTerminating()); |
| + CHECK(CcTest::global()->Get(v8_str("terminate"))->IsFunction()); |
| + // The first stack check after terminate has been re-requested fails. |
| + CHECK(CompileRun("1 + 1").IsEmpty()); |
| + CHECK(!v8::V8::IsExecutionTerminating()); |
| + // V8 then recovers. |
| + CHECK_EQ(4, CompileRun("2 + 2")->ToInt32()->Int32Value()); |
| + CHECK(!v8::V8::IsExecutionTerminating()); |
| +} |