| 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 | 
|---|