Revision: 3203 Author: [email protected] Date: Tue Nov 3 03:38:18 2009 Log: Merge bleeding_edge r3201 and r3202 to trunk.
Review URL: http://codereview.chromium.org/342095 http://code.google.com/p/v8/source/detail?r=3203 Modified: /trunk/include/v8.h /trunk/src/api.cc /trunk/src/version.cc /trunk/test/cctest/test-api.cc ======================================= --- /trunk/include/v8.h Wed Oct 28 07:53:37 2009 +++ /trunk/include/v8.h Tue Nov 3 03:38:18 2009 @@ -2472,6 +2472,15 @@ */ bool CanContinue() const; + /** + * Throws the exception caught by this TryCatch in a way that avoids + * it being caught again by this same TryCatch. As with ThrowException + * it is illegal to execute any JavaScript operations after calling + * ReThrow; the caller must return immediately to where the exception + * is caught. + */ + Handle<Value> ReThrow(); + /** * Returns the exception caught by this try/catch block. If no exception has * been caught an empty handle is returned. @@ -2527,9 +2536,10 @@ TryCatch* next_; void* exception_; void* message_; - bool is_verbose_; - bool can_continue_; - bool capture_message_; + bool is_verbose_ : 1; + bool can_continue_ : 1; + bool capture_message_ : 1; + bool rethrow_ : 1; void* js_handler_; }; ======================================= --- /trunk/src/api.cc Wed Oct 28 07:53:37 2009 +++ /trunk/src/api.cc Tue Nov 3 03:38:18 2009 @@ -1197,13 +1197,21 @@ is_verbose_(false), can_continue_(true), capture_message_(true), + rethrow_(false), js_handler_(NULL) { i::Top::RegisterTryCatchHandler(this); } v8::TryCatch::~TryCatch() { - i::Top::UnregisterTryCatchHandler(this); + if (rethrow_) { + v8::HandleScope scope; + v8::Local<v8::Value> exc = v8::Local<v8::Value>::New(Exception()); + i::Top::UnregisterTryCatchHandler(this); + v8::ThrowException(exc); + } else { + i::Top::UnregisterTryCatchHandler(this); + } } @@ -1215,6 +1223,13 @@ bool v8::TryCatch::CanContinue() const { return can_continue_; } + + +v8::Handle<v8::Value> v8::TryCatch::ReThrow() { + if (!HasCaught()) return v8::Local<v8::Value>(); + rethrow_ = true; + return v8::Undefined(); +} v8::Local<Value> v8::TryCatch::Exception() const { ======================================= --- /trunk/src/version.cc Thu Oct 29 07:46:49 2009 +++ /trunk/src/version.cc Tue Nov 3 03:38:18 2009 @@ -35,7 +35,7 @@ #define MAJOR_VERSION 1 #define MINOR_VERSION 3 #define BUILD_NUMBER 18 -#define PATCH_LEVEL 0 +#define PATCH_LEVEL 1 #define CANDIDATE_VERSION false // Define SONAME to have the SCons build the put a specific SONAME into the ======================================= --- /trunk/test/cctest/test-api.cc Thu Oct 29 07:46:49 2009 +++ /trunk/test/cctest/test-api.cc Tue Nov 3 03:38:18 2009 @@ -8610,3 +8610,41 @@ } } } + + +static v8::Handle<Value> SpaghettiIncident(const v8::Arguments& args) { + v8::HandleScope scope; + v8::TryCatch tc; + v8::Handle<v8::String> str = args[0]->ToString(); + if (tc.HasCaught()) + return tc.ReThrow(); + return v8::Undefined(); +} + + +// Test that an exception can be propagated down through a spaghetti +// stack using ReThrow. +THREADED_TEST(SpaghettiStackReThrow) { + v8::HandleScope scope; + LocalContext context; + context->Global()->Set( + v8::String::New("s"), + v8::FunctionTemplate::New(SpaghettiIncident)->GetFunction()); + v8::TryCatch try_catch; + CompileRun( + "var i = 0;" + "var o = {" + " toString: function () {" + " if (i == 10) {" + " throw 'Hey!';" + " } else {" + " i++;" + " return s(o);" + " }" + " }" + "};" + "s(o);"); + CHECK(try_catch.HasCaught()); + v8::String::Utf8Value value(try_catch.Exception()); + CHECK_EQ(0, strcmp(*value, "Hey!")); +} --~--~---------~--~----~------------~-------~--~----~ v8-dev mailing list [email protected] http://groups.google.com/group/v8-dev -~----------~----~----~----~------~----~------~--~---
