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

Side by Side 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 unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « runtime/vm/exceptions.cc ('k') | runtime/vm/object_store.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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
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 RawFunction* 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
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 RawFunction* IsolateMessageHandler::ResolveCallbackFunction() {
131 ASSERT(isolate_->object_store()->unhandled_exception_handler() != NULL);
132 String& callback_name = String::Handle(isolate_);
133 if (isolate_->object_store()->unhandled_exception_handler() !=
134 String::null()) {
135 callback_name = isolate_->object_store()->unhandled_exception_handler();
136 } else {
137 callback_name = String::New("_unhandledExceptionCallback");
138 }
139 Library& lib =
140 Library::Handle(isolate_, isolate_->object_store()->isolate_library());
141 Function& func =
142 Function::Handle(isolate_, lib.LookupLocalFunction(callback_name));
143 if (func.IsNull()) {
144 lib = isolate_->object_store()->root_library();
145 func = lib.LookupLocalFunction(callback_name);
146 }
147 return func.raw();
148 }
149
150
151 bool IsolateMessageHandler::UnhandledExceptionCallbackHandler(
152 const Object& message, const UnhandledException& error) {
153 const Instance& cause = Instance::Handle(isolate_, error.exception());
154 const Instance& stacktrace =
155 Instance::Handle(isolate_, error.stacktrace());
156
157 // Wrap these args into an IsolateUncaughtException object.
158 GrowableArray<const Object*> exception_args(3);
159 exception_args.Add(&message);
160 exception_args.Add(&cause);
161 exception_args.Add(&stacktrace);
162 const Object& exception =
163 Object::Handle(isolate_,
164 Exceptions::Create(Exceptions::kIsolateUnhandledException,
165 exception_args));
166 if (exception.IsError()) {
167 return false;
168 }
169 ASSERT(exception.IsInstance());
170
171 // Invoke script's callback function.
172 GrowableArray<const Object*> callback_args(0);
173 callback_args.Add(&exception);
174 const Array& kNoArgumentNames = Array::Handle(isolate_);
175 Object& function = Object::Handle(isolate_, ResolveCallbackFunction());
176 if (function.IsNull() || function.IsError()) {
177 return false;
178 }
179 const Object& result =
180 Object::Handle(DartEntry::InvokeStatic(Function::Cast(function),
181 callback_args,
182 kNoArgumentNames));
183 if (result.IsError()) {
184 const Error& err = Error::Cast(result);
185 OS::PrintErr("failed calling unhandled exception callback: %s\n",
186 err.ToErrorCString());
187 return false;
188 }
189
190 ASSERT(result.IsBool());
191 bool continue_from_exception = Bool::Cast(result).value();
192 if (continue_from_exception) {
193 isolate_->object_store()->clear_sticky_error();
194 }
195 return continue_from_exception;
196 }
127 197
128 #if defined(DEBUG) 198 #if defined(DEBUG)
129 void IsolateMessageHandler::CheckAccess() { 199 void IsolateMessageHandler::CheckAccess() {
130 ASSERT(IsCurrentIsolate()); 200 ASSERT(IsCurrentIsolate());
131 } 201 }
132 #endif 202 #endif
133 203
134 204
135 bool IsolateMessageHandler::IsCurrentIsolate() const { 205 bool IsolateMessageHandler::IsCurrentIsolate() const {
136 return (isolate_ == Isolate::Current()); 206 return (isolate_ == Isolate::Current());
137 } 207 }
138 208
139 209
140 bool IsolateMessageHandler::ProcessUnhandledException(const Object& result) { 210 bool IsolateMessageHandler::ProcessUnhandledException(
141 isolate_->object_store()->set_sticky_error(Error::Cast(result)); 211 const Object& message, const Error& result) {
142 // Invoke the dart unhandled exception callback if there is one. 212 if (result.IsUnhandledException()) {
213 // Invoke the isolate's uncaught exception handler, if it exists.
214 const UnhandledException& error = UnhandledException::Cast(result);
215 RawInstance* exception = error.exception();
216 if ((exception != isolate_->object_store()->out_of_memory()) &&
217 (exception != isolate_->object_store()->stack_overflow())) {
218 if (UnhandledExceptionCallbackHandler(message, error)) {
219 return true;
220 }
221 }
222 }
223
224 // Invoke the isolate's unhandled exception callback if there is one.
143 if (Isolate::UnhandledExceptionCallback() != NULL) { 225 if (Isolate::UnhandledExceptionCallback() != NULL) {
144 Dart_EnterScope(); 226 Dart_EnterScope();
145 Dart_Handle error = Api::NewHandle(isolate_, result.raw()); 227 Dart_Handle error = Api::NewHandle(isolate_, result.raw());
146 (Isolate::UnhandledExceptionCallback())(error); 228 (Isolate::UnhandledExceptionCallback())(error);
147 Dart_ExitScope(); 229 Dart_ExitScope();
148 } 230 }
231
232 isolate_->object_store()->set_sticky_error(result);
149 return false; 233 return false;
150 } 234 }
151 235
152 236
153 #if defined(DEBUG) 237 #if defined(DEBUG)
154 // static 238 // static
155 void BaseIsolate::AssertCurrent(BaseIsolate* isolate) { 239 void BaseIsolate::AssertCurrent(BaseIsolate* isolate) {
156 ASSERT(isolate == Isolate::Current()); 240 ASSERT(isolate == Isolate::Current());
157 } 241 }
158 #endif 242 #endif
(...skipping 360 matching lines...) Expand 10 before | Expand all | Expand 10 after
519 603
520 604
521 void Isolate::VisitWeakPersistentHandles(HandleVisitor* visitor, 605 void Isolate::VisitWeakPersistentHandles(HandleVisitor* visitor,
522 bool visit_prologue_weak_handles) { 606 bool visit_prologue_weak_handles) {
523 if (api_state() != NULL) { 607 if (api_state() != NULL) {
524 api_state()->VisitWeakHandles(visitor, visit_prologue_weak_handles); 608 api_state()->VisitWeakHandles(visitor, visit_prologue_weak_handles);
525 } 609 }
526 } 610 }
527 611
528 } // namespace dart 612 } // namespace dart
OLDNEW
« no previous file with comments | « runtime/vm/exceptions.cc ('k') | runtime/vm/object_store.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698