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 |