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
LOG=
R=mstarzinger@chromium.org

Review URL: https://codereview.chromium.org/443853002

Patch from Yutaka Hirano <yhirano@chromium.org>.

git-svn-id: https://v8.googlecode.com/svn/branches/bleeding_edge@22963 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
parent 76c87c1c
...@@ -5114,7 +5114,8 @@ class V8_EXPORT TryCatch { ...@@ -5114,7 +5114,8 @@ class V8_EXPORT TryCatch {
/** /**
* Clears any exceptions that may have been caught by this try/catch block. * Clears any exceptions that may have been caught by this try/catch block.
* After this method has been called, HasCaught() will return false. * After this method has been called, HasCaught() will return false. Cancels
* the scheduled exception if it is caught and ReThrow() is not called before.
* *
* It is not necessary to clear a try/catch block before using it again; if * It is not necessary to clear a try/catch block before using it again; if
* another exception is thrown the previously caught exception will just be * another exception is thrown the previously caught exception will just be
...@@ -5157,6 +5158,8 @@ class V8_EXPORT TryCatch { ...@@ -5157,6 +5158,8 @@ class V8_EXPORT TryCatch {
} }
private: private:
void ResetInternal();
// Make it hard to create heap-allocated TryCatch blocks. // Make it hard to create heap-allocated TryCatch blocks.
TryCatch(const TryCatch&); TryCatch(const TryCatch&);
void operator=(const TryCatch&); void operator=(const TryCatch&);
......
...@@ -1823,7 +1823,7 @@ v8::TryCatch::TryCatch() ...@@ -1823,7 +1823,7 @@ v8::TryCatch::TryCatch()
capture_message_(true), capture_message_(true),
rethrow_(false), rethrow_(false),
has_terminated_(false) { has_terminated_(false) {
Reset(); ResetInternal();
// Special handling for simulators which have a separate JS stack. // Special handling for simulators which have a separate JS stack.
js_stack_comparable_address_ = js_stack_comparable_address_ =
reinterpret_cast<void*>(v8::internal::SimulatorStack::RegisterCTryCatch( reinterpret_cast<void*>(v8::internal::SimulatorStack::RegisterCTryCatch(
...@@ -1935,6 +1935,17 @@ v8::Local<v8::Message> v8::TryCatch::Message() const { ...@@ -1935,6 +1935,17 @@ v8::Local<v8::Message> v8::TryCatch::Message() const {
void v8::TryCatch::Reset() { void v8::TryCatch::Reset() {
DCHECK(isolate_ == i::Isolate::Current()); 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(); i::Object* the_hole = isolate_->heap()->the_hole_value();
exception_ = the_hole; exception_ = the_hole;
message_obj_ = the_hole; message_obj_ = the_hole;
......
...@@ -5421,6 +5421,31 @@ TEST(TryCatchNative) { ...@@ -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) { THREADED_TEST(Equality) {
LocalContext context; LocalContext context;
v8::Isolate* isolate = context->GetIsolate(); v8::Isolate* isolate = context->GetIsolate();
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment