Revision: 3201
Author: [email protected]
Date: Tue Nov  3 00:53:34 2009
Log: Added TryCatch::ReThrow method.

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

http://code.google.com/p/v8/source/detail?r=3201

Modified:
  /branches/bleeding_edge/include/v8.h
  /branches/bleeding_edge/src/api.cc
  /branches/bleeding_edge/test/cctest/test-api.cc

=======================================
--- /branches/bleeding_edge/include/v8.h        Tue Oct 27 04:54:01 2009
+++ /branches/bleeding_edge/include/v8.h        Tue Nov  3 00:53:34 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_;
  };

=======================================
--- /branches/bleeding_edge/src/api.cc  Fri Oct 30 03:23:12 2009
+++ /branches/bleeding_edge/src/api.cc  Tue Nov  3 00:53:34 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 {
=======================================
--- /branches/bleeding_edge/test/cctest/test-api.cc     Thu Oct 29 16:06:59 2009
+++ /branches/bleeding_edge/test/cctest/test-api.cc     Tue Nov  3 00:53:34 2009
@@ -8662,3 +8662,29 @@
      }
    }
  }
+
+
+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"));
+}

--~--~---------~--~----~------------~-------~--~----~
v8-dev mailing list
[email protected]
http://groups.google.com/group/v8-dev
-~----------~----~----~----~------~----~------~--~---

Reply via email to