Reviewers: mstarzinger,

Description:
v8::TryCatch should cancel the scheduled exception on Reset.

v8::TryCatch cancels the scheduled exception on destruction if |Rethrow|
was never called.
It is reasonable to do the same in |Reset|.

BUG=362388, 359386

Please review this at https://codereview.chromium.org/443853002/

SVN Base: git://github.com/v8/v8.git@master

Affected files (+39, -1 lines):
  M include/v8.h
  M src/api.cc
  M test/cctest/test-api.cc


Index: include/v8.h
diff --git a/include/v8.h b/include/v8.h
index f702166cd4d281965f2caba33a616888eb7cb0fb..820ccd658da2df855d55fc47c1b71f51369c4c22 100644
--- a/include/v8.h
+++ b/include/v8.h
@@ -5163,6 +5163,8 @@ class V8_EXPORT TryCatch {
   void* operator new(size_t size);
   void operator delete(void*, size_t);

+  void ResetInternal();
+
   v8::internal::Isolate* isolate_;
   v8::TryCatch* next_;
   void* exception_;
Index: src/api.cc
diff --git a/src/api.cc b/src/api.cc
index bd49c84630b23748a747c13a867ef04d15ad5ee4..7098859de3cfa9fa85d786b29cf8eef56846f086 100644
--- a/src/api.cc
+++ b/src/api.cc
@@ -1823,7 +1823,7 @@ v8::TryCatch::TryCatch()
       capture_message_(true),
       rethrow_(false),
       has_terminated_(false) {
-  Reset();
+  ResetInternal();
   // Special handling for simulators which have a separate JS stack.
   js_stack_comparable_address_ =
reinterpret_cast<void*>(v8::internal::SimulatorStack::RegisterCTryCatch( @@ -1935,6 +1935,17 @@ v8::Local<v8::Message> v8::TryCatch::Message() const {

 void v8::TryCatch::Reset() {
   DCHECK(isolate_ == i::Isolate::Current());
+  if (!rethrow_ && HasCaught() && isolate_->has_scheduled_exception()) {
+ // If an exception was caught but is still scheduled because no API call + // promoted it, then it is canceled to prevent it from being propagated.
+    // Note that this will not cancel termination exceptions.
+    isolate_->CancelScheduledExceptionFromTryCatch(this);
+  }
+  ResetInternal();
+}
+
+
+void v8::TryCatch::ResetInternal() {
   i::Object* the_hole = isolate_->heap()->the_hole_value();
   exception_ = the_hole;
   message_obj_ = the_hole;
Index: test/cctest/test-api.cc
diff --git a/test/cctest/test-api.cc b/test/cctest/test-api.cc
index 5fb99c68b0b46d7a93eaa7a743dd53c905d2e7b9..45c5d467d3143420408f858c91e6baa7e0d304ea 100644
--- a/test/cctest/test-api.cc
+++ b/test/cctest/test-api.cc
@@ -5421,6 +5421,31 @@ TEST(TryCatchNative) {
 }


+void TryCatchNativeResetHelper(
+    const v8::FunctionCallbackInfo<v8::Value>& args) {
+  ApiTestFuzzer::Fuzz();
+  v8::TryCatch try_catch;
+  args.GetIsolate()->ThrowException(v8_str("boom"));
+  CHECK(try_catch.HasCaught());
+  try_catch.Reset();
+  CHECK(!try_catch.HasCaught());
+}
+
+
+TEST(TryCatchNativeReset) {
+  v8::Isolate* isolate = CcTest::isolate();
+  v8::HandleScope scope(isolate);
+  v8::V8::Initialize();
+  v8::TryCatch try_catch;
+  Local<ObjectTemplate> templ = ObjectTemplate::New(isolate);
+  templ->Set(v8_str("TryCatchNativeResetHelper"),
+ v8::FunctionTemplate::New(isolate, TryCatchNativeResetHelper));
+  LocalContext context(0, templ);
+  CompileRun("TryCatchNativeResetHelper();");
+  CHECK(!try_catch.HasCaught());
+}
+
+
 THREADED_TEST(Equality) {
   LocalContext context;
   v8::Isolate* isolate = context->GetIsolate();


--
--
v8-dev mailing list
[email protected]
http://groups.google.com/group/v8-dev
--- You received this message because you are subscribed to the Google Groups "v8-dev" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to [email protected].
For more options, visit https://groups.google.com/d/optout.

Reply via email to