| OLD | NEW |
| 1 // Copyright (c) 2011, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2011, 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/exceptions.h" | 5 #include "vm/exceptions.h" |
| 6 | 6 |
| 7 #include "vm/cpu.h" | |
| 8 #include "vm/dart_entry.h" | 7 #include "vm/dart_entry.h" |
| 9 #include "vm/debugger.h" | 8 #include "vm/debugger.h" |
| 10 #include "vm/flags.h" | 9 #include "vm/flags.h" |
| 11 #include "vm/object.h" | 10 #include "vm/object.h" |
| 12 #include "vm/stack_frame.h" | 11 #include "vm/stack_frame.h" |
| 12 #include "vm/stub_code.h" |
| 13 | 13 |
| 14 namespace dart { | 14 namespace dart { |
| 15 | 15 |
| 16 DEFINE_FLAG(bool, print_stack_trace_at_throw, false, | 16 DEFINE_FLAG(bool, print_stack_trace_at_throw, false, |
| 17 "Prints a stack trace everytime a throw occurs."); | 17 "Prints a stack trace everytime a throw occurs."); |
| 18 | 18 |
| 19 // Iterate through the stack frames and try to find a frame with an | 19 // Iterate through the stack frames and try to find a frame with an |
| 20 // exception handler. Once found, set the pc, sp and fp so that execution | 20 // exception handler. Once found, set the pc, sp and fp so that execution |
| 21 // can continue in that frame. | 21 // can continue in that frame. |
| 22 static bool FindExceptionHandler(uword* handler_pc, | 22 static bool FindExceptionHandler(uword* handler_pc, |
| (...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 57 frame = frames.NextFrame(); | 57 frame = frames.NextFrame(); |
| 58 ASSERT(frame != NULL); | 58 ASSERT(frame != NULL); |
| 59 } | 59 } |
| 60 ASSERT(frame->IsEntryFrame()); | 60 ASSERT(frame->IsEntryFrame()); |
| 61 *handler_pc = frame->pc(); | 61 *handler_pc = frame->pc(); |
| 62 *handler_sp = frame->sp(); | 62 *handler_sp = frame->sp(); |
| 63 *handler_fp = frame->fp(); | 63 *handler_fp = frame->fp(); |
| 64 } | 64 } |
| 65 | 65 |
| 66 | 66 |
| 67 void JumpToExceptionHandler(uword program_counter, |
| 68 uword stack_pointer, |
| 69 uword frame_pointer, |
| 70 const Instance& exception_object, |
| 71 const Instance& stacktrace_object) { |
| 72 // The no_gc StackResource is unwound through the tear down of |
| 73 // stack resources below. |
| 74 NoGCScope no_gc; |
| 75 RawInstance* exception = exception_object.raw(); |
| 76 RawInstance* stacktrace = stacktrace_object.raw(); |
| 77 |
| 78 // Prepare for unwinding frames by destroying all the stack resources |
| 79 // in the previous frames. |
| 80 Isolate* isolate = Isolate::Current(); |
| 81 while (isolate->top_resource() != NULL && |
| 82 (reinterpret_cast<uword>(isolate->top_resource()) < stack_pointer)) { |
| 83 isolate->top_resource()->~StackResource(); |
| 84 } |
| 85 |
| 86 // Set up the appropriate register state and jump to the handler. |
| 87 typedef void (*ExcpHandler)(uword, uword, uword, RawInstance*, RawInstance*); |
| 88 ExcpHandler func = reinterpret_cast<ExcpHandler>( |
| 89 StubCode::JumpToExceptionHandlerEntryPoint()); |
| 90 func(program_counter, stack_pointer, frame_pointer, exception, stacktrace); |
| 91 UNREACHABLE(); |
| 92 } |
| 93 |
| 94 |
| 95 void JumpToErrorHandler(uword program_counter, |
| 96 uword stack_pointer, |
| 97 uword frame_pointer, |
| 98 const Error& error) { |
| 99 // The no_gc StackResource is unwound through the tear down of |
| 100 // stack resources below. |
| 101 NoGCScope no_gc; |
| 102 ASSERT(!error.IsNull()); |
| 103 RawError* raw_error = error.raw(); |
| 104 |
| 105 // Prepare for unwinding frames by destroying all the stack resources |
| 106 // in the previous frames. |
| 107 Isolate* isolate = Isolate::Current(); |
| 108 while (isolate->top_resource() != NULL && |
| 109 (reinterpret_cast<uword>(isolate->top_resource()) < stack_pointer)) { |
| 110 isolate->top_resource()->~StackResource(); |
| 111 } |
| 112 |
| 113 // Set up the error object as the return value in EAX and continue |
| 114 // from the invocation stub. |
| 115 typedef void (*ErrorHandler)(uword, uword, uword, RawError*); |
| 116 ErrorHandler func = reinterpret_cast<ErrorHandler>( |
| 117 StubCode::JumpToErrorHandlerEntryPoint()); |
| 118 func(program_counter, stack_pointer, frame_pointer, raw_error); |
| 119 UNREACHABLE(); |
| 120 } |
| 121 |
| 122 |
| 67 static void ThrowExceptionHelper(const Instance& incoming_exception, | 123 static void ThrowExceptionHelper(const Instance& incoming_exception, |
| 68 const Instance& existing_stacktrace) { | 124 const Instance& existing_stacktrace) { |
| 69 Instance& exception = Instance::Handle(incoming_exception.raw()); | 125 Instance& exception = Instance::Handle(incoming_exception.raw()); |
| 70 if (exception.IsNull()) { | 126 if (exception.IsNull()) { |
| 71 GrowableArray<const Object*> arguments; | 127 GrowableArray<const Object*> arguments; |
| 72 exception ^= Exceptions::Create(Exceptions::kNullPointer, arguments); | 128 exception ^= Exceptions::Create(Exceptions::kNullPointer, arguments); |
| 73 } | 129 } |
| 74 uword handler_pc = 0; | 130 uword handler_pc = 0; |
| 75 uword handler_sp = 0; | 131 uword handler_sp = 0; |
| 76 uword handler_fp = 0; | 132 uword handler_fp = 0; |
| (...skipping 15 matching lines...) Expand all Loading... |
| 92 } | 148 } |
| 93 } else { | 149 } else { |
| 94 stacktrace ^= existing_stacktrace.raw(); | 150 stacktrace ^= existing_stacktrace.raw(); |
| 95 } | 151 } |
| 96 if (FLAG_print_stack_trace_at_throw) { | 152 if (FLAG_print_stack_trace_at_throw) { |
| 97 OS::Print("Exception '%s' thrown:\n", exception.ToCString()); | 153 OS::Print("Exception '%s' thrown:\n", exception.ToCString()); |
| 98 OS::Print("%s\n", stacktrace.ToCString()); | 154 OS::Print("%s\n", stacktrace.ToCString()); |
| 99 } | 155 } |
| 100 if (handler_exists) { | 156 if (handler_exists) { |
| 101 // Found a dart handler for the exception, jump to it. | 157 // Found a dart handler for the exception, jump to it. |
| 102 CPU::JumpToExceptionHandler(handler_pc, | 158 JumpToExceptionHandler(handler_pc, |
| 103 handler_sp, | 159 handler_sp, |
| 104 handler_fp, | 160 handler_fp, |
| 105 exception, | 161 exception, |
| 106 stacktrace); | 162 stacktrace); |
| 107 } else { | 163 } else { |
| 108 // No dart exception handler found in this invocation sequence, | 164 // No dart exception handler found in this invocation sequence, |
| 109 // so we create an unhandled exception object and return to the | 165 // so we create an unhandled exception object and return to the |
| 110 // invocation stub so that it returns this unhandled exception | 166 // invocation stub so that it returns this unhandled exception |
| 111 // object. The C++ code which invoked this dart sequence can check | 167 // object. The C++ code which invoked this dart sequence can check |
| 112 // and do the appropriate thing (rethrow the exception to the | 168 // and do the appropriate thing (rethrow the exception to the |
| 113 // dart invocation sequence above it, print diagnostics and terminate | 169 // dart invocation sequence above it, print diagnostics and terminate |
| 114 // the isolate etc.). | 170 // the isolate etc.). |
| 115 const UnhandledException& unhandled_exception = UnhandledException::Handle( | 171 const UnhandledException& unhandled_exception = UnhandledException::Handle( |
| 116 UnhandledException::New(exception, stacktrace)); | 172 UnhandledException::New(exception, stacktrace)); |
| 117 CPU::JumpToErrorHandler(handler_pc, | 173 JumpToErrorHandler(handler_pc, handler_sp, handler_fp, unhandled_exception); |
| 118 handler_sp, | |
| 119 handler_fp, | |
| 120 unhandled_exception); | |
| 121 } | 174 } |
| 122 UNREACHABLE(); | 175 UNREACHABLE(); |
| 123 } | 176 } |
| 124 | 177 |
| 125 | 178 |
| 126 // Static helpers for allocating, initializing, and throwing an error instance. | 179 // Static helpers for allocating, initializing, and throwing an error instance. |
| 127 | 180 |
| 128 // Return the script of the Dart function that called the native entry or the | 181 // Return the script of the Dart function that called the native entry or the |
| 129 // runtime entry. The frame iterator points to the callee. | 182 // runtime entry. The frame iterator points to the callee. |
| 130 RawScript* Exceptions::GetCallerScript(DartFrameIterator* iterator) { | 183 RawScript* Exceptions::GetCallerScript(DartFrameIterator* iterator) { |
| (...skipping 141 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 272 const Instance& stk = Instance::Handle(uhe.stacktrace()); | 325 const Instance& stk = Instance::Handle(uhe.stacktrace()); |
| 273 Exceptions::ReThrow(exc, stk); | 326 Exceptions::ReThrow(exc, stk); |
| 274 } else { | 327 } else { |
| 275 // Return to the invocation stub and return this error object. The | 328 // Return to the invocation stub and return this error object. The |
| 276 // C++ code which invoked this dart sequence can check and do the | 329 // C++ code which invoked this dart sequence can check and do the |
| 277 // appropriate thing. | 330 // appropriate thing. |
| 278 uword handler_pc = 0; | 331 uword handler_pc = 0; |
| 279 uword handler_sp = 0; | 332 uword handler_sp = 0; |
| 280 uword handler_fp = 0; | 333 uword handler_fp = 0; |
| 281 FindErrorHandler(&handler_pc, &handler_sp, &handler_fp); | 334 FindErrorHandler(&handler_pc, &handler_sp, &handler_fp); |
| 282 CPU::JumpToErrorHandler(handler_pc, handler_sp, handler_fp, error); | 335 JumpToErrorHandler(handler_pc, handler_sp, handler_fp, error); |
| 283 } | 336 } |
| 284 UNREACHABLE(); | 337 UNREACHABLE(); |
| 285 } | 338 } |
| 286 | 339 |
| 287 | 340 |
| 288 void Exceptions::ThrowByType( | 341 void Exceptions::ThrowByType( |
| 289 ExceptionType type, const GrowableArray<const Object*>& arguments) { | 342 ExceptionType type, const GrowableArray<const Object*>& arguments) { |
| 290 const Object& result = Object::Handle(Create(type, arguments)); | 343 const Object& result = Object::Handle(Create(type, arguments)); |
| 291 if (result.IsError()) { | 344 if (result.IsError()) { |
| 292 // We got an error while constructing the exception object. | 345 // We got an error while constructing the exception object. |
| (...skipping 66 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 359 case kIsolateSpawn: | 412 case kIsolateSpawn: |
| 360 library = Library::IsolateLibrary(); | 413 library = Library::IsolateLibrary(); |
| 361 class_name = String::NewSymbol("IsolateSpawnException"); | 414 class_name = String::NewSymbol("IsolateSpawnException"); |
| 362 break; | 415 break; |
| 363 } | 416 } |
| 364 | 417 |
| 365 return DartLibraryCalls::ExceptionCreate(library, class_name, arguments); | 418 return DartLibraryCalls::ExceptionCreate(library, class_name, arguments); |
| 366 } | 419 } |
| 367 | 420 |
| 368 } // namespace dart | 421 } // namespace dart |
| OLD | NEW |