Index: vm/exceptions.cc |
=================================================================== |
--- vm/exceptions.cc (revision 9040) |
+++ vm/exceptions.cc (working copy) |
@@ -4,12 +4,12 @@ |
#include "vm/exceptions.h" |
-#include "vm/cpu.h" |
#include "vm/dart_entry.h" |
#include "vm/debugger.h" |
#include "vm/flags.h" |
#include "vm/object.h" |
#include "vm/stack_frame.h" |
+#include "vm/stub_code.h" |
namespace dart { |
@@ -64,6 +64,62 @@ |
} |
+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(); |
+ |
+ // 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(); |
+ } |
+ |
+ // 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); |
+ UNREACHABLE(); |
+} |
+ |
+ |
+void JumpToErrorHandler(uword program_counter, |
+ uword stack_pointer, |
+ uword frame_pointer, |
+ const Error& error) { |
+ // 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(); |
+ |
+ // 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(); |
+ } |
+ |
+ // 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(); |
+} |
+ |
+ |
static void ThrowExceptionHelper(const Instance& incoming_exception, |
const Instance& existing_stacktrace) { |
Instance& exception = Instance::Handle(incoming_exception.raw()); |
@@ -99,11 +155,11 @@ |
} |
if (handler_exists) { |
// Found a dart handler for the exception, jump to it. |
- CPU::JumpToExceptionHandler(handler_pc, |
- handler_sp, |
- handler_fp, |
- exception, |
- stacktrace); |
+ JumpToExceptionHandler(handler_pc, |
+ handler_sp, |
+ handler_fp, |
+ exception, |
+ stacktrace); |
} else { |
// No dart exception handler found in this invocation sequence, |
// so we create an unhandled exception object and return to the |
@@ -114,10 +170,7 @@ |
// the isolate etc.). |
const UnhandledException& unhandled_exception = UnhandledException::Handle( |
UnhandledException::New(exception, stacktrace)); |
- CPU::JumpToErrorHandler(handler_pc, |
- handler_sp, |
- handler_fp, |
- unhandled_exception); |
+ JumpToErrorHandler(handler_pc, handler_sp, handler_fp, unhandled_exception); |
} |
UNREACHABLE(); |
} |
@@ -279,7 +332,7 @@ |
uword handler_sp = 0; |
uword handler_fp = 0; |
FindErrorHandler(&handler_pc, &handler_sp, &handler_fp); |
- CPU::JumpToErrorHandler(handler_pc, handler_sp, handler_fp, error); |
+ JumpToErrorHandler(handler_pc, handler_sp, handler_fp, error); |
} |
UNREACHABLE(); |
} |