From 2c4828318550abace456c440996be71c6095b00f Mon Sep 17 00:00:00 2001 From: "dimich@chromium.org" Date: Fri, 21 May 2010 20:52:19 +0000 Subject: [PATCH] Include check for execution termination into bailout check. This prevents re-entry into JS during stack unwinding caused by TerminateExecution(). Review URL: http://codereview.chromium.org/2123005 git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@4705 ce2b1a6d-e550-0410-aec6-3dcde31c8c00 --- src/api.cc | 9 +++---- test/cctest/test-thread-termination.cc | 45 ++++++++++++++++++++++++++++++++++ 2 files changed, 49 insertions(+), 5 deletions(-) diff --git a/src/api.cc b/src/api.cc index cf940c6..5560cf4 100644 --- a/src/api.cc +++ b/src/api.cc @@ -58,11 +58,10 @@ namespace v8 { - -#define ON_BAILOUT(location, code) \ - if (IsDeadCheck(location)) { \ - code; \ - UNREACHABLE(); \ +#define ON_BAILOUT(location, code) \ + if (IsDeadCheck(location) || v8::V8::IsExecutionTerminating()) { \ + code; \ + UNREACHABLE(); \ } diff --git a/test/cctest/test-thread-termination.cc b/test/cctest/test-thread-termination.cc index 83a1e19..aed7466 100644 --- a/test/cctest/test-thread-termination.cc +++ b/test/cctest/test-thread-termination.cc @@ -308,3 +308,48 @@ TEST(TerminateLoadICException) { v8::Script::Compile(source)->Run(); context.Dispose(); } + +v8::Handle ReenterAfterTermination(const v8::Arguments& args) { + v8::TryCatch try_catch; + CHECK(!v8::V8::IsExecutionTerminating()); + v8::Script::Compile(v8::String::New("function f() {" + " var term = true;" + " try {" + " while(true) {" + " if (term) terminate();" + " term = false;" + " }" + " fail();" + " } catch(e) {" + " fail();" + " }" + "}" + "f()"))->Run(); + CHECK(try_catch.HasCaught()); + CHECK(try_catch.Exception()->IsNull()); + CHECK(try_catch.Message().IsEmpty()); + CHECK(!try_catch.CanContinue()); + CHECK(v8::V8::IsExecutionTerminating()); + v8::Script::Compile(v8::String::New("function f() { fail(); } f()"))->Run(); + return v8::Undefined(); +} + +// Test that reentry into V8 while the termination exception is still pending +// (has not yet unwound the 0-level JS frame) does not crash. +TEST(TerminateAndReenterFromThreadItself) { + v8::HandleScope scope; + v8::Handle global = + CreateGlobalTemplate(TerminateCurrentThread, ReenterAfterTermination); + v8::Persistent context = v8::Context::New(NULL, global); + v8::Context::Scope context_scope(context); + CHECK(!v8::V8::IsExecutionTerminating()); + v8::Handle source = + v8::String::New("try { loop(); fail(); } catch(e) { fail(); }"); + v8::Script::Compile(source)->Run(); + CHECK(!v8::V8::IsExecutionTerminating()); + // Check we can run JS again after termination. + CHECK(v8::Script::Compile(v8::String::New("function f() { return true; }" + "f()"))->Run()->IsTrue()); + context.Dispose(); +} + -- 2.7.4