Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file |
| 2 // for details. All rights reserved. Use of this source code is governed by a | 2 // for details. All rights reserved. Use of this source code is governed by a |
| 3 // BSD-style license that can be found in the LICENSE file. | 3 // BSD-style license that can be found in the LICENSE file. |
| 4 | 4 |
| 5 #include "vm/isolate.h" | 5 #include "vm/isolate.h" |
| 6 | 6 |
| 7 #include "include/dart_api.h" | 7 #include "include/dart_api.h" |
| 8 #include "platform/assert.h" | 8 #include "platform/assert.h" |
| 9 #include "lib/mirrors.h" | 9 #include "lib/mirrors.h" |
| 10 #include "vm/compiler_stats.h" | 10 #include "vm/compiler_stats.h" |
| (...skipping 30 matching lines...) Expand all Loading... | |
| 41 const char* name() const; | 41 const char* name() const; |
| 42 void MessageNotify(Message::Priority priority); | 42 void MessageNotify(Message::Priority priority); |
| 43 bool HandleMessage(Message* message); | 43 bool HandleMessage(Message* message); |
| 44 | 44 |
| 45 #if defined(DEBUG) | 45 #if defined(DEBUG) |
| 46 // Check that it is safe to access this handler. | 46 // Check that it is safe to access this handler. |
| 47 void CheckAccess(); | 47 void CheckAccess(); |
| 48 #endif | 48 #endif |
| 49 bool IsCurrentIsolate() const; | 49 bool IsCurrentIsolate() const; |
| 50 virtual Isolate* GetIsolate() const { return isolate_; } | 50 virtual Isolate* GetIsolate() const { return isolate_; } |
| 51 bool UnhandledExceptionCallbackHandler(const Object& message, | |
| 52 const UnhandledException& error); | |
| 51 | 53 |
| 52 private: | 54 private: |
| 53 bool ProcessUnhandledException(const Object& result); | 55 bool ProcessUnhandledException(const Object& message, const Error& result); |
| 54 | 56 RawObject* ResolveCallbackFunction(); |
| 55 Isolate* isolate_; | 57 Isolate* isolate_; |
| 56 }; | 58 }; |
| 57 | 59 |
| 58 | 60 |
| 59 IsolateMessageHandler::IsolateMessageHandler(Isolate* isolate) | 61 IsolateMessageHandler::IsolateMessageHandler(Isolate* isolate) |
| 60 : isolate_(isolate) { | 62 : isolate_(isolate) { |
| 61 } | 63 } |
| 62 | 64 |
| 63 | 65 |
| 64 IsolateMessageHandler::~IsolateMessageHandler() { | 66 IsolateMessageHandler::~IsolateMessageHandler() { |
| (...skipping 21 matching lines...) Expand all Loading... | |
| 86 StartIsolateScope start_scope(isolate_); | 88 StartIsolateScope start_scope(isolate_); |
| 87 StackZone zone(isolate_); | 89 StackZone zone(isolate_); |
| 88 HandleScope handle_scope(isolate_); | 90 HandleScope handle_scope(isolate_); |
| 89 | 91 |
| 90 // Parse the message. | 92 // Parse the message. |
| 91 SnapshotReader reader(message->data(), message->len(), | 93 SnapshotReader reader(message->data(), message->len(), |
| 92 Snapshot::kMessage, Isolate::Current()); | 94 Snapshot::kMessage, Isolate::Current()); |
| 93 const Object& msg_obj = Object::Handle(reader.ReadObject()); | 95 const Object& msg_obj = Object::Handle(reader.ReadObject()); |
| 94 if (msg_obj.IsError()) { | 96 if (msg_obj.IsError()) { |
| 95 // An error occurred while reading the message. | 97 // An error occurred while reading the message. |
| 96 return ProcessUnhandledException(msg_obj); | 98 return ProcessUnhandledException(Instance::Handle(), Error::Cast(msg_obj)); |
| 97 } | 99 } |
| 98 if (!msg_obj.IsNull() && !msg_obj.IsInstance()) { | 100 if (!msg_obj.IsNull() && !msg_obj.IsInstance()) { |
| 99 // TODO(turnidge): We need to decide what an isolate does with | 101 // TODO(turnidge): We need to decide what an isolate does with |
| 100 // malformed messages. If they (eventually) come from a remote | 102 // malformed messages. If they (eventually) come from a remote |
| 101 // machine, then it might make sense to drop the message entirely. | 103 // machine, then it might make sense to drop the message entirely. |
| 102 // In the case that the message originated locally, which is | 104 // In the case that the message originated locally, which is |
| 103 // always true for now, then this should never occur. | 105 // always true for now, then this should never occur. |
| 104 UNREACHABLE(); | 106 UNREACHABLE(); |
| 105 } | 107 } |
| 106 | 108 |
| 107 Instance& msg = Instance::Handle(); | 109 Instance& msg = Instance::Handle(); |
| 108 msg ^= msg_obj.raw(); // Can't use Instance::Cast because may be null. | 110 msg ^= msg_obj.raw(); // Can't use Instance::Cast because may be null. |
| 109 | 111 |
| 112 bool success = true; | |
| 110 if (message->IsOOB()) { | 113 if (message->IsOOB()) { |
| 111 // For now the only OOB messages are Mirrors messages. | 114 // For now the only OOB messages are Mirrors messages. |
| 112 HandleMirrorsMessage(isolate_, message->reply_port(), msg); | 115 HandleMirrorsMessage(isolate_, message->reply_port(), msg); |
| 113 delete message; | |
| 114 } else { | 116 } else { |
| 115 const Object& result = Object::Handle( | 117 const Object& result = Object::Handle( |
| 116 DartLibraryCalls::HandleMessage( | 118 DartLibraryCalls::HandleMessage( |
| 117 message->dest_port(), message->reply_port(), msg)); | 119 message->dest_port(), message->reply_port(), msg)); |
| 118 delete message; | |
| 119 if (result.IsError()) { | 120 if (result.IsError()) { |
| 120 return ProcessUnhandledException(result); | 121 success = ProcessUnhandledException(msg, Error::Cast(result)); |
| 122 } else { | |
| 123 ASSERT(result.IsNull()); | |
| 121 } | 124 } |
| 122 ASSERT(result.IsNull()); | |
| 123 } | 125 } |
| 124 return true; | 126 delete message; |
| 127 return success; | |
| 125 } | 128 } |
| 126 | 129 |
| 130 RawObject* IsolateMessageHandler::ResolveCallbackFunction() { | |
| 131 ASSERT(isolate_->object_store()->unhandled_exception_handler() != NULL); | |
| 132 Library& lib = Library::Handle(); | |
| 133 RawString* raw_uri = isolate_->object_store()->isolate_library_uri(); | |
| 134 if (raw_uri != String::null()) { | |
| 135 String& uri = String::Handle(isolate_, raw_uri); | |
| 136 lib = Library::LookupLibrary(uri); | |
| 137 if (lib.IsNull() || lib.IsError()) { | |
| 138 const String& msg = String::Handle(String::NewFormatted( | |
| 139 "Unable to find library '%s'.", uri.ToCString())); | |
| 140 return LanguageError::New(msg); | |
| 141 } | |
| 142 } else { | |
| 143 lib = isolate_->object_store()->root_library(); | |
| 144 raw_uri = lib.url(); | |
| 145 } | |
| 146 ASSERT(!lib.IsNull()); | |
| 147 | |
| 148 // Resolve the unhandled exceptions callback function. | |
| 149 const String& callback_name = | |
| 150 String::Handle(isolate_, | |
| 151 isolate_->object_store()->unhandled_exception_handler()); | |
| 152 const Function& func = | |
| 153 Function::Handle(isolate_, lib.LookupLocalFunction(callback_name)); | |
| 154 if (func.IsNull()) { | |
| 155 String& library_uri = String::Handle(isolate_, raw_uri); | |
| 156 const String& msg = String::Handle(isolate_, String::NewFormatted( | |
| 157 "Unable to resolve function '%s' in library '%s'.", | |
| 158 callback_name.ToCString(), library_uri.ToCString())); | |
| 159 return LanguageError::New(msg); | |
| 160 } | |
| 161 return func.raw(); | |
| 162 } | |
| 163 | |
| 164 | |
| 165 bool IsolateMessageHandler::UnhandledExceptionCallbackHandler( | |
| 166 const Object& message, const UnhandledException& error) { | |
| 167 const Instance& cause = Instance::Handle(isolate_, error.exception()); | |
| 168 const Instance& stacktrace = | |
| 169 Instance::Handle(isolate_, error.stacktrace()); | |
| 170 | |
| 171 // Wrap these args into an IsolateUncaughtException object. | |
| 172 GrowableArray<const Object*> exception_args(3); | |
| 173 exception_args.Add(&message); | |
| 174 exception_args.Add(&cause); | |
| 175 exception_args.Add(&stacktrace); | |
| 176 Object& exception = Object::Handle(); | |
| 177 exception = Exceptions::Create(Exceptions::kIsolateUnhandledException, | |
| 178 exception_args); | |
| 179 if (exception.IsError()) { | |
| 180 return false; | |
| 181 } | |
| 182 ASSERT(exception.IsInstance()); | |
| 183 | |
| 184 // Invoke script's callback function. | |
| 185 GrowableArray<const Object*> callback_args(0); | |
| 186 callback_args.Add(&exception); | |
| 187 const Array& kNoArgumentNames = Array::Handle(isolate_); | |
| 188 Object& function = Object::Handle(isolate_, ResolveCallbackFunction()); | |
| 189 if (function.IsError()) { | |
| 190 const Error& err = Error::Cast(function); | |
| 191 OS::PrintErr("failed resolving unhandled exception callback: %s\n", | |
| 192 err.ToErrorCString()); | |
| 193 return false; | |
| 194 } | |
| 195 RawObject* response = DartEntry::InvokeStatic(Function::Cast(function), | |
| 196 callback_args, | |
| 197 kNoArgumentNames); | |
| 198 const Object& result = Object::Handle(response); | |
|
siva
2012/12/13 18:30:38
We try not to keep these raw pointers in local var
| |
| 199 if (result.IsError()) { | |
| 200 const Error& err = Error::Cast(result); | |
| 201 OS::PrintErr("failed calling unhandled exception callback: %s\n", | |
| 202 err.ToErrorCString()); | |
| 203 return false; | |
| 204 } | |
| 205 | |
| 206 ASSERT(result.IsBool()); | |
| 207 bool continue_from_exception = (response == Bool::True()); | |
|
siva
2012/12/13 18:30:38
bool continue_from_exception = result.value();
| |
| 208 if (continue_from_exception) { | |
| 209 isolate_->object_store()->clear_sticky_error(); | |
| 210 } | |
| 211 return continue_from_exception; | |
| 212 } | |
| 127 | 213 |
| 128 #if defined(DEBUG) | 214 #if defined(DEBUG) |
| 129 void IsolateMessageHandler::CheckAccess() { | 215 void IsolateMessageHandler::CheckAccess() { |
| 130 ASSERT(IsCurrentIsolate()); | 216 ASSERT(IsCurrentIsolate()); |
| 131 } | 217 } |
| 132 #endif | 218 #endif |
| 133 | 219 |
| 134 | 220 |
| 135 bool IsolateMessageHandler::IsCurrentIsolate() const { | 221 bool IsolateMessageHandler::IsCurrentIsolate() const { |
| 136 return (isolate_ == Isolate::Current()); | 222 return (isolate_ == Isolate::Current()); |
| 137 } | 223 } |
| 138 | 224 |
| 139 | 225 |
| 140 bool IsolateMessageHandler::ProcessUnhandledException(const Object& result) { | 226 bool IsolateMessageHandler::ProcessUnhandledException( |
| 141 isolate_->object_store()->set_sticky_error(Error::Cast(result)); | 227 const Object& message, const Error& result) { |
| 142 // Invoke the dart unhandled exception callback if there is one. | 228 if (result.IsUnhandledException()) { |
| 229 // Invoke the isolate's uncaught exception handler, if it exists. | |
| 230 const UnhandledException& error = UnhandledException::Cast(result); | |
| 231 RawInstance* exception = error.exception(); | |
| 232 if ((exception != isolate_->object_store()->out_of_memory()) && | |
| 233 (exception != isolate_->object_store()->stack_overflow())) { | |
| 234 if (UnhandledExceptionCallbackHandler(message, error)) { | |
| 235 return true; | |
| 236 } | |
| 237 } | |
| 238 } | |
| 239 | |
| 240 // Invoke the isolate's unhandled exception callback if there is one. | |
| 143 if (Isolate::UnhandledExceptionCallback() != NULL) { | 241 if (Isolate::UnhandledExceptionCallback() != NULL) { |
| 144 Dart_EnterScope(); | 242 Dart_EnterScope(); |
| 145 Dart_Handle error = Api::NewHandle(isolate_, result.raw()); | 243 Dart_Handle error = Api::NewHandle(isolate_, result.raw()); |
| 146 (Isolate::UnhandledExceptionCallback())(error); | 244 (Isolate::UnhandledExceptionCallback())(error); |
| 147 Dart_ExitScope(); | 245 Dart_ExitScope(); |
| 148 } | 246 } |
| 247 | |
| 248 isolate_->object_store()->set_sticky_error(result); | |
| 149 return false; | 249 return false; |
| 150 } | 250 } |
| 151 | 251 |
| 152 | 252 |
| 153 #if defined(DEBUG) | 253 #if defined(DEBUG) |
| 154 // static | 254 // static |
| 155 void BaseIsolate::AssertCurrent(BaseIsolate* isolate) { | 255 void BaseIsolate::AssertCurrent(BaseIsolate* isolate) { |
| 156 ASSERT(isolate == Isolate::Current()); | 256 ASSERT(isolate == Isolate::Current()); |
| 157 } | 257 } |
| 158 #endif | 258 #endif |
| (...skipping 360 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 519 | 619 |
| 520 | 620 |
| 521 void Isolate::VisitWeakPersistentHandles(HandleVisitor* visitor, | 621 void Isolate::VisitWeakPersistentHandles(HandleVisitor* visitor, |
| 522 bool visit_prologue_weak_handles) { | 622 bool visit_prologue_weak_handles) { |
| 523 if (api_state() != NULL) { | 623 if (api_state() != NULL) { |
| 524 api_state()->VisitWeakHandles(visitor, visit_prologue_weak_handles); | 624 api_state()->VisitWeakHandles(visitor, visit_prologue_weak_handles); |
| 525 } | 625 } |
| 526 } | 626 } |
| 527 | 627 |
| 528 } // namespace dart | 628 } // namespace dart |
| OLD | NEW |