Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(504)

Unified Diff: runtime/vm/isolate.cc

Issue 11558034: Second version of support for specifying an unhandled exception callback (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: Created 8 years ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: runtime/vm/isolate.cc
===================================================================
--- runtime/vm/isolate.cc (revision 16084)
+++ runtime/vm/isolate.cc (working copy)
@@ -48,10 +48,12 @@
#endif
bool IsCurrentIsolate() const;
virtual Isolate* GetIsolate() const { return isolate_; }
+ bool UnhandledExceptionCallbackHandler(const Object& message,
+ const UnhandledException& error);
private:
- bool ProcessUnhandledException(const Object& result);
-
+ bool ProcessUnhandledException(const Object& message, const Error& result);
+ RawFunction* ResolveCallbackFunction();
Isolate* isolate_;
};
@@ -93,7 +95,7 @@
const Object& msg_obj = Object::Handle(reader.ReadObject());
if (msg_obj.IsError()) {
// An error occurred while reading the message.
- return ProcessUnhandledException(msg_obj);
+ return ProcessUnhandledException(Instance::Handle(), Error::Cast(msg_obj));
}
if (!msg_obj.IsNull() && !msg_obj.IsInstance()) {
// TODO(turnidge): We need to decide what an isolate does with
@@ -107,24 +109,94 @@
Instance& msg = Instance::Handle();
msg ^= msg_obj.raw(); // Can't use Instance::Cast because may be null.
+ bool success = true;
if (message->IsOOB()) {
// For now the only OOB messages are Mirrors messages.
HandleMirrorsMessage(isolate_, message->reply_port(), msg);
- delete message;
} else {
const Object& result = Object::Handle(
DartLibraryCalls::HandleMessage(
message->dest_port(), message->reply_port(), msg));
- delete message;
if (result.IsError()) {
- return ProcessUnhandledException(result);
+ success = ProcessUnhandledException(msg, Error::Cast(result));
+ } else {
+ ASSERT(result.IsNull());
}
- ASSERT(result.IsNull());
}
- return true;
+ delete message;
+ return success;
}
+RawFunction* IsolateMessageHandler::ResolveCallbackFunction() {
+ ASSERT(isolate_->object_store()->unhandled_exception_handler() != NULL);
+ Library& lib = Library::Handle(isolate_);
+ String& callback_name = String::Handle(isolate_);
+ if (isolate_->object_store()->unhandled_exception_handler() !=
+ String::null()) {
+ callback_name = isolate_->object_store()->unhandled_exception_handler();
+ } else {
+ callback_name = String::New("_unhandledExceptionCallback");
+ }
+ const GrowableObjectArray& libs =
+ GrowableObjectArray::Handle(isolate_->object_store()->libraries());
+ Function& func = Function::Handle(isolate_);
+ for (int i = 0; i < libs.Length(); i++) {
+ lib ^= libs.At(i);
+ func = lib.LookupLocalFunction(callback_name);
+ if (!func.IsNull()) {
+ return func.raw();
+ }
+ }
siva 2012/12/13 18:30:38 How does this work if we have multiple libraries w
Tom Ball 2012/12/13 19:33:22 As we discussed, the function is now just looked u
+ return Function::null();
+}
+
+bool IsolateMessageHandler::UnhandledExceptionCallbackHandler(
+ const Object& message, const UnhandledException& error) {
+ const Instance& cause = Instance::Handle(isolate_, error.exception());
+ const Instance& stacktrace =
+ Instance::Handle(isolate_, error.stacktrace());
+
+ // Wrap these args into an IsolateUncaughtException object.
+ GrowableArray<const Object*> exception_args(3);
+ exception_args.Add(&message);
+ exception_args.Add(&cause);
+ exception_args.Add(&stacktrace);
+ Object& exception = Object::Handle();
+ exception = Exceptions::Create(Exceptions::kIsolateUnhandledException,
+ exception_args);
+ if (exception.IsError()) {
+ return false;
+ }
+ ASSERT(exception.IsInstance());
+
+ // Invoke script's callback function.
+ GrowableArray<const Object*> callback_args(0);
+ callback_args.Add(&exception);
+ const Array& kNoArgumentNames = Array::Handle(isolate_);
+ Object& function = Object::Handle(isolate_, ResolveCallbackFunction());
+ if (function.IsNull()) {
+ return false;
+ }
+ RawObject* response = DartEntry::InvokeStatic(Function::Cast(function),
+ callback_args,
+ kNoArgumentNames);
+ const Object& result = Object::Handle(response);
+ if (result.IsError()) {
+ const Error& err = Error::Cast(result);
+ OS::PrintErr("failed calling unhandled exception callback: %s\n",
+ err.ToErrorCString());
+ return false;
+ }
+
+ ASSERT(result.IsBool());
+ bool continue_from_exception = (response == Bool::True());
+ if (continue_from_exception) {
+ isolate_->object_store()->clear_sticky_error();
+ }
+ return continue_from_exception;
+}
+
#if defined(DEBUG)
void IsolateMessageHandler::CheckAccess() {
ASSERT(IsCurrentIsolate());
@@ -137,15 +209,29 @@
}
-bool IsolateMessageHandler::ProcessUnhandledException(const Object& result) {
- isolate_->object_store()->set_sticky_error(Error::Cast(result));
- // Invoke the dart unhandled exception callback if there is one.
+bool IsolateMessageHandler::ProcessUnhandledException(
+ const Object& message, const Error& result) {
+ if (result.IsUnhandledException()) {
+ // Invoke the isolate's uncaught exception handler, if it exists.
+ const UnhandledException& error = UnhandledException::Cast(result);
+ RawInstance* exception = error.exception();
+ if ((exception != isolate_->object_store()->out_of_memory()) &&
+ (exception != isolate_->object_store()->stack_overflow())) {
+ if (UnhandledExceptionCallbackHandler(message, error)) {
+ return true;
+ }
+ }
+ }
+
+ // Invoke the isolate's unhandled exception callback if there is one.
if (Isolate::UnhandledExceptionCallback() != NULL) {
Dart_EnterScope();
Dart_Handle error = Api::NewHandle(isolate_, result.raw());
(Isolate::UnhandledExceptionCallback())(error);
Dart_ExitScope();
}
+
+ isolate_->object_store()->set_sticky_error(result);
return false;
}

Powered by Google App Engine
This is Rietveld 408576698