Revision: 4705
Author: [email protected]
Date: Fri May 21 13:52:19 2010
Log: 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
http://code.google.com/p/v8/source/detail?r=4705

Modified:
 /branches/bleeding_edge/src/api.cc
 /branches/bleeding_edge/test/cctest/test-thread-termination.cc

=======================================
--- /branches/bleeding_edge/src/api.cc  Fri May 21 02:01:19 2010
+++ /branches/bleeding_edge/src/api.cc  Fri May 21 13:52:19 2010
@@ -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();                                                 \
   }


=======================================
--- /branches/bleeding_edge/test/cctest/test-thread-termination.cc Thu Mar 4 04:13:04 2010 +++ /branches/bleeding_edge/test/cctest/test-thread-termination.cc Fri May 21 13:52:19 2010
@@ -308,3 +308,48 @@
   v8::Script::Compile(source)->Run();
   context.Dispose();
 }
+
+v8::Handle<v8::Value> 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<v8::ObjectTemplate> global =
+ CreateGlobalTemplate(TerminateCurrentThread, ReenterAfterTermination);
+  v8::Persistent<v8::Context> context = v8::Context::New(NULL, global);
+  v8::Context::Scope context_scope(context);
+  CHECK(!v8::V8::IsExecutionTerminating());
+  v8::Handle<v8::String> 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();
+}
+

--
v8-dev mailing list
[email protected]
http://groups.google.com/group/v8-dev

Reply via email to