| 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" | 7 #include "vm/cpu.h" |
| 8 #include "vm/dart_entry.h" | 8 #include "vm/dart_entry.h" |
| 9 #include "vm/flags.h" | 9 #include "vm/flags.h" |
| 10 #include "vm/object.h" | 10 #include "vm/object.h" |
| (...skipping 28 matching lines...) Expand all Loading... |
| 39 ASSERT(frame != NULL); | 39 ASSERT(frame != NULL); |
| 40 } | 40 } |
| 41 ASSERT(frame->IsEntryFrame()); | 41 ASSERT(frame->IsEntryFrame()); |
| 42 *handler_pc = frame->pc(); | 42 *handler_pc = frame->pc(); |
| 43 *handler_sp = frame->sp(); | 43 *handler_sp = frame->sp(); |
| 44 *handler_fp = frame->fp(); | 44 *handler_fp = frame->fp(); |
| 45 return false; | 45 return false; |
| 46 } | 46 } |
| 47 | 47 |
| 48 | 48 |
| 49 static void FindErrorHandler(uword* handler_pc, |
| 50 uword* handler_sp, |
| 51 uword* handler_fp) { |
| 52 // TODO(turnidge): Is there a faster way to get the next entry frame? |
| 53 StackFrameIterator frames(StackFrameIterator::kDontValidateFrames); |
| 54 StackFrame* frame = frames.NextFrame(); |
| 55 ASSERT(frame != NULL); |
| 56 while (!frame->IsEntryFrame()) { |
| 57 frame = frames.NextFrame(); |
| 58 ASSERT(frame != NULL); |
| 59 } |
| 60 ASSERT(frame->IsEntryFrame()); |
| 61 *handler_pc = frame->pc(); |
| 62 *handler_sp = frame->sp(); |
| 63 *handler_fp = frame->fp(); |
| 64 } |
| 65 |
| 66 |
| 49 static void ThrowExceptionHelper(const Instance& exception, | 67 static void ThrowExceptionHelper(const Instance& exception, |
| 50 const Instance& existing_stacktrace) { | 68 const Instance& existing_stacktrace) { |
| 51 uword handler_pc = 0; | 69 uword handler_pc = 0; |
| 52 uword handler_sp = 0; | 70 uword handler_sp = 0; |
| 53 uword handler_fp = 0; | 71 uword handler_fp = 0; |
| 54 GrowableArray<uword> stack_frame_pcs; | 72 GrowableArray<uword> stack_frame_pcs; |
| 55 bool handler_exists = FindExceptionHandler(&handler_pc, | 73 bool handler_exists = FindExceptionHandler(&handler_pc, |
| 56 &handler_sp, | 74 &handler_sp, |
| 57 &handler_fp, | 75 &handler_fp, |
| 58 &stack_frame_pcs); | 76 &stack_frame_pcs); |
| (...skipping 25 matching lines...) Expand all Loading... |
| 84 } else { | 102 } else { |
| 85 // No dart exception handler found in this invocation sequence, | 103 // No dart exception handler found in this invocation sequence, |
| 86 // so we create an unhandled exception object and return to the | 104 // so we create an unhandled exception object and return to the |
| 87 // invocation stub so that it returns this unhandled exception | 105 // invocation stub so that it returns this unhandled exception |
| 88 // object. The C++ code which invoked this dart sequence can check | 106 // object. The C++ code which invoked this dart sequence can check |
| 89 // and do the appropriate thing (rethrow the exception to the | 107 // and do the appropriate thing (rethrow the exception to the |
| 90 // dart invocation sequence above it, print diagnostics and terminate | 108 // dart invocation sequence above it, print diagnostics and terminate |
| 91 // the isolate etc.). | 109 // the isolate etc.). |
| 92 const UnhandledException& unhandled_exception = UnhandledException::Handle( | 110 const UnhandledException& unhandled_exception = UnhandledException::Handle( |
| 93 UnhandledException::New(exception, stacktrace)); | 111 UnhandledException::New(exception, stacktrace)); |
| 94 CPU::JumpToUnhandledExceptionHandler(handler_pc, | 112 CPU::JumpToErrorHandler(handler_pc, |
| 95 handler_sp, | 113 handler_sp, |
| 96 handler_fp, | 114 handler_fp, |
| 97 unhandled_exception); | 115 unhandled_exception); |
| 98 } | 116 } |
| 99 UNREACHABLE(); | 117 UNREACHABLE(); |
| 100 } | 118 } |
| 101 | 119 |
| 102 | 120 |
| 103 void Exceptions::Throw(const Instance& exception) { | 121 void Exceptions::Throw(const Instance& exception) { |
| 104 ThrowExceptionHelper(exception, Instance::Handle()); | 122 ThrowExceptionHelper(exception, Instance::Handle()); |
| 105 } | 123 } |
| 106 | 124 |
| 107 | 125 |
| 108 void Exceptions::ReThrow(const Instance& exception, | 126 void Exceptions::ReThrow(const Instance& exception, |
| 109 const Instance& stacktrace) { | 127 const Instance& stacktrace) { |
| 110 ASSERT(!exception.IsNull()); | 128 ASSERT(!exception.IsNull()); |
| 111 ThrowExceptionHelper(exception, stacktrace); | 129 ThrowExceptionHelper(exception, stacktrace); |
| 112 } | 130 } |
| 113 | 131 |
| 114 | 132 |
| 133 void Exceptions::PropagateError(const Object& obj) { |
| 134 ASSERT(Isolate::Current()->top_exit_frame_info() != 0); |
| 135 Error& error = Error::Handle(); |
| 136 error ^= obj.raw(); |
| 137 if (error.IsUnhandledException()) { |
| 138 // If the error object represents an unhandled exception, then |
| 139 // rethrow the exception in the normal fashion. |
| 140 UnhandledException& uhe = UnhandledException::Handle(); |
| 141 uhe ^= error.raw(); |
| 142 const Instance& exc = Instance::Handle(uhe.exception()); |
| 143 const Instance& stk = Instance::Handle(uhe.stacktrace()); |
| 144 Exceptions::ReThrow(exc, stk); |
| 145 } else { |
| 146 // Return to the invocation stub and return this error object. The |
| 147 // C++ code which invoked this dart sequence can check and do the |
| 148 // appropriate thing. |
| 149 uword handler_pc = 0; |
| 150 uword handler_sp = 0; |
| 151 uword handler_fp = 0; |
| 152 FindErrorHandler(&handler_pc, &handler_sp, &handler_fp); |
| 153 CPU::JumpToErrorHandler(handler_pc, handler_sp, handler_fp, error); |
| 154 } |
| 155 UNREACHABLE(); |
| 156 } |
| 157 |
| 158 |
| 115 void Exceptions::ThrowByType( | 159 void Exceptions::ThrowByType( |
| 116 ExceptionType type, const GrowableArray<const Object*>& arguments) { | 160 ExceptionType type, const GrowableArray<const Object*>& arguments) { |
| 117 const Instance& exception = Instance::Handle(Create(type, arguments)); | 161 const Object& result = Object::Handle(Create(type, arguments)); |
| 118 Throw(exception); | 162 if (result.IsError()) { |
| 163 // We got an error while constructing the exception object. |
| 164 // Propagate the error instead of throwing the exception. |
| 165 Error& error = Error::Handle(); |
| 166 error ^= result.raw(); |
| 167 PropagateError(error); |
| 168 } else { |
| 169 ASSERT(result.IsInstance()); |
| 170 Instance& exception = Instance::Handle(); |
| 171 exception ^= result.raw(); |
| 172 Throw(exception); |
| 173 } |
| 119 } | 174 } |
| 120 | 175 |
| 121 | 176 |
| 122 RawInstance* Exceptions::Create( | 177 RawObject* Exceptions::Create( |
| 123 ExceptionType type, const GrowableArray<const Object*>& arguments) { | 178 ExceptionType type, const GrowableArray<const Object*>& arguments) { |
| 124 String& class_name = String::Handle(); | 179 String& class_name = String::Handle(); |
| 125 switch (type) { | 180 switch (type) { |
| 126 case kIndexOutOfRange: | 181 case kIndexOutOfRange: |
| 127 class_name = String::NewSymbol("IndexOutOfRangeException"); | 182 class_name = String::NewSymbol("IndexOutOfRangeException"); |
| 128 break; | 183 break; |
| 129 case kIllegalArgument: | 184 case kIllegalArgument: |
| 130 class_name = String::NewSymbol("IllegalArgumentException"); | 185 class_name = String::NewSymbol("IllegalArgumentException"); |
| 131 break; | 186 break; |
| 132 case kNoSuchMethod: | 187 case kNoSuchMethod: |
| (...skipping 25 matching lines...) Expand all Loading... |
| 158 break; | 213 break; |
| 159 case kIllegalJSRegExp: | 214 case kIllegalJSRegExp: |
| 160 class_name = String::NewSymbol("IllegalJSRegExpException"); | 215 class_name = String::NewSymbol("IllegalJSRegExpException"); |
| 161 break; | 216 break; |
| 162 } | 217 } |
| 163 | 218 |
| 164 return DartLibraryCalls::ExceptionCreate(class_name, arguments); | 219 return DartLibraryCalls::ExceptionCreate(class_name, arguments); |
| 165 } | 220 } |
| 166 | 221 |
| 167 } // namespace dart | 222 } // namespace dart |
| OLD | NEW |