Index: runtime/vm/exceptions.cc |
=================================================================== |
--- runtime/vm/exceptions.cc (revision 21676) |
+++ runtime/vm/exceptions.cc (working copy) |
@@ -207,17 +207,22 @@ |
} |
-void JumpToExceptionHandler(uword program_counter, |
- uword stack_pointer, |
- uword frame_pointer, |
- const Instance& exception_object, |
- const Instance& stacktrace_object) { |
- // The no_gc StackResource is unwound through the tear down of |
- // stack resources below. |
- NoGCScope no_gc; |
- RawInstance* exception = exception_object.raw(); |
- RawInstance* stacktrace = stacktrace_object.raw(); |
- |
+static void JumpToHandler(uword program_counter, |
+ uword stack_pointer, |
+ uword frame_pointer, |
+ RawObject* raw_exception, |
+ RawObject* raw_stacktrace) { |
+#if defined(USING_SIMULATOR) |
+ // Unwinding of the C++ frames and destroying of their stack resources is done |
+ // by the simulator, because the target stack_pointer is a simulated stack |
+ // pointer and not the C++ stack pointer. |
+ |
+ // Continue simulating at the given pc in the given frame after setting up the |
+ // exception object in the kExceptionObjectReg register and the stacktrace |
+ // object (if not NULL) in the kStackTraceObjectReg register. |
+ Simulator::Current()->Longjmp(program_counter, stack_pointer, frame_pointer, |
+ raw_exception, raw_stacktrace); |
+#else |
// Prepare for unwinding frames by destroying all the stack resources |
// in the previous frames. |
Isolate* isolate = Isolate::Current(); |
@@ -226,39 +231,64 @@ |
isolate->top_resource()->~StackResource(); |
} |
- // Set up the appropriate register state and jump to the handler. |
- typedef void (*ExcpHandler)(uword, uword, uword, RawInstance*, RawInstance*); |
- ExcpHandler func = reinterpret_cast<ExcpHandler>( |
- StubCode::JumpToExceptionHandlerEntryPoint()); |
- func(program_counter, stack_pointer, frame_pointer, exception, stacktrace); |
+ // TODO(regis): Can we safely merge both stubs and pass NULL as |
+ // stacktrace_object in the case of an error handler? |
+ |
+ // A NULL raw_stacktrace indicates that we are jumping to an ErrorHandler, |
+ // rather than to an ExceptionHandler. TODO(regis): Merge these two cases. |
+ if (raw_stacktrace == NULL) { |
+ // Call a stub to set up the error object in kExceptionObjectReg and to |
+ // continue execution at the given pc in the given frame. |
+ typedef void (*ErrorHandler)(uword, uword, uword, RawObject*); |
+ ErrorHandler func = reinterpret_cast<ErrorHandler>( |
+ StubCode::JumpToErrorHandlerEntryPoint()); |
+ func(program_counter, stack_pointer, frame_pointer, raw_exception); |
+ } else { |
+ // Call a stub to set up the exception object in kExceptionObjectReg, |
+ // to set up the stacktrace object in kStackTraceObjectReg, and to |
+ // continue execution at the given pc in the given frame. |
+ typedef void (*ExcpHandler)(uword, uword, uword, RawObject*, RawObject*); |
+ ExcpHandler func = reinterpret_cast<ExcpHandler>( |
+ StubCode::JumpToExceptionHandlerEntryPoint()); |
+ func(program_counter, stack_pointer, frame_pointer, |
+ raw_exception, raw_stacktrace); |
+ } |
+#endif |
UNREACHABLE(); |
} |
-void JumpToErrorHandler(uword program_counter, |
- uword stack_pointer, |
- uword frame_pointer, |
- const Error& error) { |
+static void JumpToExceptionHandler(uword program_counter, |
+ uword stack_pointer, |
+ uword frame_pointer, |
+ const Instance& exception_object, |
+ const Instance& stacktrace_object) { |
// The no_gc StackResource is unwound through the tear down of |
// stack resources below. |
NoGCScope no_gc; |
- ASSERT(!error.IsNull()); |
- RawError* raw_error = error.raw(); |
+ RawObject* raw_exception = exception_object.raw(); |
+ RawObject* raw_stacktrace = stacktrace_object.raw(); |
- // Prepare for unwinding frames by destroying all the stack resources |
- // in the previous frames. |
- Isolate* isolate = Isolate::Current(); |
- while (isolate->top_resource() != NULL && |
- (reinterpret_cast<uword>(isolate->top_resource()) < stack_pointer)) { |
- isolate->top_resource()->~StackResource(); |
- } |
+ JumpToHandler(program_counter, stack_pointer, frame_pointer, |
+ raw_exception, raw_stacktrace); |
+ |
+ UNREACHABLE(); |
+} |
+ |
+ |
+static void JumpToErrorHandler(uword program_counter, |
+ uword stack_pointer, |
+ uword frame_pointer, |
+ const Error& error_object) { |
+ // The no_gc StackResource is unwound through the tear down of |
+ // stack resources below. |
+ NoGCScope no_gc; |
+ ASSERT(!error_object.IsNull()); |
+ RawObject* raw_error = error_object.raw(); |
+ |
+ JumpToHandler( |
+ program_counter, stack_pointer, frame_pointer, raw_error, NULL); |
- // Set up the error object as the return value in EAX and continue |
- // from the invocation stub. |
- typedef void (*ErrorHandler)(uword, uword, uword, RawError*); |
- ErrorHandler func = reinterpret_cast<ErrorHandler>( |
- StubCode::JumpToErrorHandlerEntryPoint()); |
- func(program_counter, stack_pointer, frame_pointer, raw_error); |
UNREACHABLE(); |
} |