Chromium Code Reviews| Index: runtime/vm/isolate.cc |
| diff --git a/runtime/vm/isolate.cc b/runtime/vm/isolate.cc |
| index 6b9178d0b55bd32e7099967d285d0823738ccd6c..5ce67b375990254cbd809ba70c09e782cf420e95 100644 |
| --- a/runtime/vm/isolate.cc |
| +++ b/runtime/vm/isolate.cc |
| @@ -41,13 +41,14 @@ class IsolateMessageHandler : public MessageHandler { |
| const char* name() const; |
| void MessageNotify(Message::Priority priority); |
| bool HandleMessage(Message* message); |
| - |
| #if defined(DEBUG) |
| // Check that it is safe to access this handler. |
| void CheckAccess(); |
| #endif |
| bool IsCurrentIsolate() const; |
| virtual Isolate* GetIsolate() const { return isolate_; } |
| + bool UnhandledExceptionCallbackHandler(const Object& message, |
| + const UnhandledException& error); |
| private: |
| Isolate* isolate_; |
| @@ -101,22 +102,74 @@ bool IsolateMessageHandler::HandleMessage(Message* message) { |
| 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()) { |
| isolate_->object_store()->set_sticky_error(Error::Cast(result)); |
| - return false; |
| + if (result.IsUnhandledException()) { |
| + const UnhandledException& error = UnhandledException::Cast(result); |
| + RawInstance* exception = error.exception(); |
| + if ((exception != isolate_->object_store()->out_of_memory()) && |
| + (exception != isolate_->object_store()->stack_overflow())) { |
| + success = UnhandledExceptionCallbackHandler(msg, error); |
| + if (!success && (Isolate::UnhandledExceptionCallback() != NULL)) { |
| + // Notify embedder that an unhandled exception occurred. |
| + Dart_EnterScope(); |
| + Dart_Handle error_handle = Api::NewHandle(isolate_, error.raw()); |
| + (Isolate::UnhandledExceptionCallback())(error_handle); |
| + // TODO(tball): add some sort of blocker to ensure embedder |
| + // doesn't run any more code on this isolate. |
| + Dart_ExitScope(); |
| + } |
| + } |
| + } |
|
siva
2012/11/21 00:45:04
I presume a return of success == true would keep t
Tom Ball
2012/11/21 05:22:38
PTAL -- I refactored it and fixed when the Unhandl
|
| + } else { |
| + ASSERT(result.IsNull()); |
| } |
| - ASSERT(result.IsNull()); |
| } |
| - return true; |
| + delete message; |
| + return success; |
| +} |
| + |
| + |
| +bool IsolateMessageHandler::UnhandledExceptionCallbackHandler( |
| + const Object& message, const UnhandledException& error) { |
| + RawInstance* callback = |
| + isolate_->object_store()->unhandled_exception_closure(); |
| + Instance& closure = Instance::Handle(callback); |
| + if (closure.IsNull()) { |
| + return false; // Error wasn't handled by callback. |
| + } |
| + 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(&error); |
| + exception_args.Add(&stacktrace); |
| + Object& exception = Object::Handle(); |
| + exception = Exceptions::Create(Exceptions::kIsolateUnhandledException, |
| + exception_args); |
| + if (exception.IsError()) { |
| + return false; |
| + } |
| + |
| + // Invoke script's callback closure. |
| + GrowableArray<const Object*> callback_args(1); |
| + callback_args.Add(&exception); |
| + const Array& kNoArgumentNames = Array::Handle(isolate_); |
| + RawObject* response = DartEntry::InvokeClosure(closure, |
| + callback_args, |
| + kNoArgumentNames); |
| + // TODO(tball): log any nested exceptions. |
| + return (response == Bool::True()); |
| } |
| @@ -446,6 +499,8 @@ void Isolate::Shutdown() { |
| Dart_IsolateCreateCallback Isolate::create_callback_ = NULL; |
| Dart_IsolateInterruptCallback Isolate::interrupt_callback_ = NULL; |
| +Dart_IsolateUnhandledExceptionCallback |
| + Isolate::unhandled_exception_callback_ = NULL; |
| Dart_IsolateShutdownCallback Isolate::shutdown_callback_ = NULL; |