From ccf388fc642b91607716deed2133b7c9a079d142 Mon Sep 17 00:00:00 2001 From: olehougaard Date: Tue, 9 Dec 2008 10:16:38 +0000 Subject: [PATCH] Fixing a bug where a try-finally block obscured a try-catch block when registering an external try-catch handler. Review URL: http://codereview.chromium.org/13658 git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@945 ce2b1a6d-e550-0410-aec6-3dcde31c8c00 --- src/top.cc | 10 +++++++++- test/cctest/test-api.cc | 28 ++++++++++++++++++++++++++++ 2 files changed, 37 insertions(+), 1 deletion(-) diff --git a/src/top.cc b/src/top.cc index 6c096daf8..9dd536194 100644 --- a/src/top.cc +++ b/src/top.cc @@ -280,7 +280,15 @@ void Top::TearDown() { // is on the top. Otherwise, it means the C try-catch handler is on the top. // void Top::RegisterTryCatchHandler(v8::TryCatch* that) { - that->js_handler_ = thread_local_.handler_; // casted to void* + StackHandler* handler = + reinterpret_cast(thread_local_.handler_); + + // Find the top-most try-catch handler. + while (handler != NULL && !handler->is_try_catch()) { + handler = handler->next(); + } + + that->js_handler_ = handler; // casted to void* thread_local_.try_catch_handler_ = that; } diff --git a/test/cctest/test-api.cc b/test/cctest/test-api.cc index b69debc12..7e1d464ad 100644 --- a/test/cctest/test-api.cc +++ b/test/cctest/test-api.cc @@ -1648,6 +1648,15 @@ v8::Handle ThrowFromC(const v8::Arguments& args) { } +v8::Handle CCatcher(const v8::Arguments& args) { + if (args.Length() < 1) return v8::Boolean::New(false); + v8::HandleScope scope; + v8::TryCatch try_catch; + v8::Script::Compile(args[0]->ToString())->Run(); + return v8::Boolean::New(try_catch.HasCaught()); +} + + THREADED_TEST(APICatch) { v8::HandleScope scope; Local templ = ObjectTemplate::New(); @@ -1678,6 +1687,25 @@ THREADED_TEST(APIThrowTryCatch) { } +// Test that a try-finally block doesn't shadow a try-catch block +// when setting up an external handler. +THREADED_TEST(TryCatchInTryFinally) { + v8::HandleScope scope; + Local templ = ObjectTemplate::New(); + templ->Set(v8_str("CCatcher"), + v8::FunctionTemplate::New(CCatcher)); + LocalContext context(0, templ); + Local result = CompileRun("try {" + " try {" + " CCatcher('throw 7;');" + " } finally {" + " }" + "} catch (e) {" + "}"); + CHECK(result->IsTrue()); +} + + static void receive_message(v8::Handle message, v8::Handle data) { message_received = true; -- 2.34.1