Added TryCatch::ReThrow method.

Review URL: http://codereview.chromium.org/342078


git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@3201 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
parent 84542872
......@@ -2472,6 +2472,15 @@ class V8EXPORT TryCatch {
*/
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 @@ class V8EXPORT TryCatch {
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_;
};
......
......@@ -1197,13 +1197,21 @@ v8::TryCatch::TryCatch()
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);
}
}
......@@ -1217,6 +1225,13 @@ bool v8::TryCatch::CanContinue() const {
}
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 {
if (HasCaught()) {
// Check for out of memory exception.
......
......@@ -8662,3 +8662,29 @@ THREADED_TEST(QuietSignalingNaNs) {
}
}
}
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 a stack overflow can be propagated down through a spaghetti
// stack using ReThrow.
THREADED_TEST(SpaghettiStackOverflow) {
v8::HandleScope scope;
LocalContext context;
context->Global()->Set(
v8::String::New("s"),
v8::FunctionTemplate::New(SpaghettiIncident)->GetFunction());
v8::TryCatch try_catch;
CompileRun("var o = {toString: function () {return s(o);}}; s(o);");
CHECK(try_catch.HasCaught());
v8::String::Utf8Value value(try_catch.Exception());
CHECK_NE(0, strstr(*value, "RangeError"));
}
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