Revision: 12768
Author:   [email protected]
Date:     Fri Oct 19 01:45:24 2012
Log:      Pass pending exception to the message listener.

BUG=

Review URL: https://chromiumcodereview.appspot.com/11014017
http://code.google.com/p/v8/source/detail?r=12768

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

=======================================
--- /branches/bleeding_edge/include/v8.h        Wed Oct 17 23:52:37 2012
+++ /branches/bleeding_edge/include/v8.h        Fri Oct 19 01:45:24 2012
@@ -2658,7 +2658,7 @@
typedef void (*FatalErrorCallback)(const char* location, const char* message);


-typedef void (*MessageCallback)(Handle<Message> message, Handle<Value> data); +typedef void (*MessageCallback)(Handle<Message> message, Handle<Value> error);


 /**
@@ -3101,8 +3101,7 @@
    * The same message listener can be added more than once and in that
    * case it will be called more than once for each message.
    */
-  static bool AddMessageListener(MessageCallback that,
-                                 Handle<Value> data = Handle<Value>());
+  static bool AddMessageListener(MessageCallback that);

   /**
    * Remove all message listeners from the specified callback function.
=======================================
--- /branches/bleeding_edge/src/api.cc  Wed Oct 17 23:52:37 2012
+++ /branches/bleeding_edge/src/api.cc  Fri Oct 19 01:45:24 2012
@@ -5255,19 +5255,14 @@
 }


-bool V8::AddMessageListener(MessageCallback that, Handle<Value> data) {
+bool V8::AddMessageListener(MessageCallback that) {
   i::Isolate* isolate = i::Isolate::Current();
   EnsureInitializedForIsolate(isolate, "v8::V8::AddMessageListener()");
   ON_BAILOUT(isolate, "v8::V8::AddMessageListener()", return false);
   ENTER_V8(isolate);
   i::HandleScope scope(isolate);
   NeanderArray listeners(isolate->factory()->message_listeners());
-  NeanderObject obj(2);
-  obj.set(0, *isolate->factory()->NewForeign(FUNCTION_ADDR(that)));
-  obj.set(1, data.IsEmpty() ?
-             isolate->heap()->undefined_value() :
-             *Utils::OpenHandle(*data));
-  listeners.add(obj.value());
+  listeners.add(isolate->factory()->NewForeign(FUNCTION_ADDR(that)));
   return true;
 }

@@ -5282,8 +5277,7 @@
   for (int i = 0; i < listeners.length(); i++) {
     if (listeners.get(i)->IsUndefined()) continue;  // skip deleted ones

-    NeanderObject listener(i::JSObject::cast(listeners.get(i)));
-    i::Handle<i::Foreign> callback_obj(i::Foreign::cast(listener.get(0)));
+    i::Handle<i::Foreign> callback_obj(i::Foreign::cast(listeners.get(i)));
     if (callback_obj->foreign_address() == FUNCTION_ADDR(that)) {
       listeners.set(i, isolate->heap()->undefined_value());
     }
=======================================
--- /branches/bleeding_edge/src/messages.cc     Fri Oct 28 05:37:29 2011
+++ /branches/bleeding_edge/src/messages.cc     Fri Oct 19 01:45:24 2012
@@ -106,11 +106,20 @@
   // We are calling into embedder's code which can throw exceptions.
// Thus we need to save current exception state, reset it to the clean one
   // and ignore scheduled exceptions callbacks can throw.
+
+  // We pass the exception object into the message handler callback though.
+  Object* exception_object = isolate->heap()->undefined_value();
+  if (isolate->has_pending_exception()) {
+    isolate->pending_exception()->ToObject(&exception_object);
+  }
+  Handle<Object> exception_handle(exception_object);
+
   Isolate::ExceptionScope exception_scope(isolate);
   isolate->clear_pending_exception();
   isolate->set_external_caught_exception(false);

v8::Local<v8::Message> api_message_obj = v8::Utils::MessageToLocal(message); + v8::Local<v8::Value> api_exception_obj = v8::Utils::ToLocal(exception_handle);

   v8::NeanderArray global_listeners(FACTORY->message_listeners());
   int global_length = global_listeners.length();
@@ -123,15 +132,13 @@
     for (int i = 0; i < global_length; i++) {
       HandleScope scope;
       if (global_listeners.get(i)->IsUndefined()) continue;
-      v8::NeanderObject listener(JSObject::cast(global_listeners.get(i)));
-      Handle<Foreign> callback_obj(Foreign::cast(listener.get(0)));
+      Handle<Foreign> callback_obj(Foreign::cast(global_listeners.get(i)));
       v8::MessageCallback callback =
FUNCTION_CAST<v8::MessageCallback>(callback_obj->foreign_address());
-      Handle<Object> callback_data(listener.get(1));
       {
         // Do not allow exceptions to propagate.
         v8::TryCatch try_catch;
-        callback(api_message_obj, v8::Utils::ToLocal(callback_data));
+        callback(api_message_obj, api_exception_obj);
       }
       if (isolate->has_scheduled_exception()) {
         isolate->clear_scheduled_exception();
=======================================
--- /branches/bleeding_edge/test/cctest/test-api.cc     Thu Oct 18 00:22:24 2012
+++ /branches/bleeding_edge/test/cctest/test-api.cc     Fri Oct 19 01:45:24 2012
@@ -2414,20 +2414,19 @@
 bool message_received;


-static void check_message(v8::Handle<v8::Message> message,
-                          v8::Handle<Value> data) {
-  CHECK_EQ(5.76, data->NumberValue());
+static void check_message_0(v8::Handle<v8::Message> message,
+                            v8::Handle<Value> data) {
   CHECK_EQ(6.75, message->GetScriptResourceName()->NumberValue());
   CHECK_EQ(7.56, message->GetScriptData()->NumberValue());
   message_received = true;
 }


-THREADED_TEST(MessageHandlerData) {
+THREADED_TEST(MessageHandler0) {
   message_received = false;
   v8::HandleScope scope;
   CHECK(!message_received);
-  v8::V8::AddMessageListener(check_message, v8_num(5.76));
+  v8::V8::AddMessageListener(check_message_0);
   LocalContext context;
   v8::ScriptOrigin origin =
       v8::ScriptOrigin(v8_str("6.75"));
@@ -2437,7 +2436,56 @@
   script->Run();
   CHECK(message_received);
   // clear out the message listener
-  v8::V8::RemoveMessageListeners(check_message);
+  v8::V8::RemoveMessageListeners(check_message_0);
+}
+
+
+static void check_message_1(v8::Handle<v8::Message> message,
+                            v8::Handle<Value> data) {
+  CHECK(data->IsNumber());
+  CHECK_EQ(1337, data->Int32Value());
+  message_received = true;
+}
+
+
+TEST(MessageHandler1) {
+  message_received = false;
+  v8::HandleScope scope;
+  CHECK(!message_received);
+  v8::V8::AddMessageListener(check_message_1);
+  LocalContext context;
+  CompileRun("throw 1337;");
+  CHECK(message_received);
+  // clear out the message listener
+  v8::V8::RemoveMessageListeners(check_message_1);
+}
+
+
+static void check_message_2(v8::Handle<v8::Message> message,
+                            v8::Handle<Value> data) {
+  LocalContext context;
+  CHECK(data->IsObject());
+  v8::Local<v8::Value> hidden_property =
+      v8::Object::Cast(*data)->GetHiddenValue(v8_str("hidden key"));
+  CHECK(v8_str("hidden value")->Equals(hidden_property));
+  message_received = true;
+}
+
+
+TEST(MessageHandler2) {
+  message_received = false;
+  v8::HandleScope scope;
+  CHECK(!message_received);
+  v8::V8::AddMessageListener(check_message_2);
+  LocalContext context;
+ v8::Local<v8::Value> error = v8::Exception::Error(v8_str("custom error"));
+  v8::Object::Cast(*error)->SetHiddenValue(v8_str("hidden key"),
+                                           v8_str("hidden value"));
+  context->Global()->Set(v8_str("error"), error);
+  CompileRun("throw error;");
+  CHECK(message_received);
+  // clear out the message listener
+  v8::V8::RemoveMessageListeners(check_message_2);
 }


@@ -3078,7 +3126,7 @@
              "Number.prototype.toString = function() { return 'Whoops'; };"
"ReferenceError.prototype.toString = Object.prototype.toString;");
   CompileRun("asdf;");
-  v8::V8::RemoveMessageListeners(check_message);
+  v8::V8::RemoveMessageListeners(check_reference_error_message);
 }


@@ -3125,7 +3173,7 @@
   LocalContext context(0, templ);
   CompileRun("ThrowFromC();");
   CHECK(message_received);
-  v8::V8::RemoveMessageListeners(check_message);
+  v8::V8::RemoveMessageListeners(receive_message);
 }


@@ -3143,7 +3191,7 @@
   CHECK(try_catch.HasCaught());
   CHECK(result.IsEmpty());
   CHECK(message_received);
-  v8::V8::RemoveMessageListeners(check_message);
+  v8::V8::RemoveMessageListeners(receive_message);
 }


@@ -5108,7 +5156,6 @@

static void MissingScriptInfoMessageListener(v8::Handle<v8::Message> message,
                                              v8::Handle<Value> data) {
-  CHECK_EQ(v8::Undefined(), data);
   CHECK(message->GetScriptResourceName()->IsUndefined());
   CHECK_EQ(v8::Undefined(), message->GetScriptResourceName());
   message->GetLineNumber();

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

Reply via email to