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
This commit is contained in:
parent
76c87c1cf2
commit
159cc8ddf2
@ -5114,7 +5114,8 @@ class V8_EXPORT TryCatch {
|
||||
|
||||
/**
|
||||
* 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
|
||||
* another exception is thrown the previously caught exception will just be
|
||||
@ -5157,6 +5158,8 @@ class V8_EXPORT TryCatch {
|
||||
}
|
||||
|
||||
private:
|
||||
void ResetInternal();
|
||||
|
||||
// Make it hard to create heap-allocated TryCatch blocks.
|
||||
TryCatch(const TryCatch&);
|
||||
void operator=(const TryCatch&);
|
||||
|
13
src/api.cc
13
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;
|
||||
|
@ -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();
|
||||
|
Loading…
Reference in New Issue
Block a user