| 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 | |
| 67 static void ThrowExceptionHelper(const Instance& exception, | 49 static void ThrowExceptionHelper(const Instance& exception, |
| 68 const Instance& existing_stacktrace) { | 50 const Instance& existing_stacktrace) { |
| 69 uword handler_pc = 0; | 51 uword handler_pc = 0; |
| 70 uword handler_sp = 0; | 52 uword handler_sp = 0; |
| 71 uword handler_fp = 0; | 53 uword handler_fp = 0; |
| 72 GrowableArray<uword> stack_frame_pcs; | 54 GrowableArray<uword> stack_frame_pcs; |
| 73 bool handler_exists = FindExceptionHandler(&handler_pc, | 55 bool handler_exists = FindExceptionHandler(&handler_pc, |
| 74 &handler_sp, | 56 &handler_sp, |
| 75 &handler_fp, | 57 &handler_fp, |
| 76 &stack_frame_pcs); | 58 &stack_frame_pcs); |
| (...skipping 25 matching lines...) Expand all Loading... |
| 102 } else { | 84 } else { |
| 103 // No dart exception handler found in this invocation sequence, | 85 // No dart exception handler found in this invocation sequence, |
| 104 // so we create an unhandled exception object and return to the | 86 // so we create an unhandled exception object and return to the |
| 105 // invocation stub so that it returns this unhandled exception | 87 // invocation stub so that it returns this unhandled exception |
| 106 // object. The C++ code which invoked this dart sequence can check | 88 // object. The C++ code which invoked this dart sequence can check |
| 107 // and do the appropriate thing (rethrow the exception to the | 89 // and do the appropriate thing (rethrow the exception to the |
| 108 // dart invocation sequence above it, print diagnostics and terminate | 90 // dart invocation sequence above it, print diagnostics and terminate |
| 109 // the isolate etc.). | 91 // the isolate etc.). |
| 110 const UnhandledException& unhandled_exception = UnhandledException::Handle( | 92 const UnhandledException& unhandled_exception = UnhandledException::Handle( |
| 111 UnhandledException::New(exception, stacktrace)); | 93 UnhandledException::New(exception, stacktrace)); |
| 112 CPU::JumpToErrorHandler(handler_pc, | 94 CPU::JumpToUnhandledExceptionHandler(handler_pc, |
| 113 handler_sp, | 95 handler_sp, |
| 114 handler_fp, | 96 handler_fp, |
| 115 unhandled_exception); | 97 unhandled_exception); |
| 116 } | 98 } |
| 117 UNREACHABLE(); | 99 UNREACHABLE(); |
| 118 } | 100 } |
| 119 | 101 |
| 120 | 102 |
| 121 void Exceptions::Throw(const Instance& exception) { | 103 void Exceptions::Throw(const Instance& exception) { |
| 122 ThrowExceptionHelper(exception, Instance::Handle()); | 104 ThrowExceptionHelper(exception, Instance::Handle()); |
| 123 } | 105 } |
| 124 | 106 |
| 125 | 107 |
| 126 void Exceptions::ReThrow(const Instance& exception, | 108 void Exceptions::ReThrow(const Instance& exception, |
| 127 const Instance& stacktrace) { | 109 const Instance& stacktrace) { |
| 128 ASSERT(!exception.IsNull()); | 110 ASSERT(!exception.IsNull()); |
| 129 ThrowExceptionHelper(exception, stacktrace); | 111 ThrowExceptionHelper(exception, stacktrace); |
| 130 } | 112 } |
| 131 | 113 |
| 132 | 114 |
| 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 | |
| 159 void Exceptions::ThrowByType( | 115 void Exceptions::ThrowByType( |
| 160 ExceptionType type, const GrowableArray<const Object*>& arguments) { | 116 ExceptionType type, const GrowableArray<const Object*>& arguments) { |
| 161 const Object& result = Object::Handle(Create(type, arguments)); | 117 const Instance& exception = Instance::Handle(Create(type, arguments)); |
| 162 if (result.IsError()) { | 118 Throw(exception); |
| 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 } | |
| 174 } | 119 } |
| 175 | 120 |
| 176 | 121 |
| 177 RawObject* Exceptions::Create( | 122 RawInstance* Exceptions::Create( |
| 178 ExceptionType type, const GrowableArray<const Object*>& arguments) { | 123 ExceptionType type, const GrowableArray<const Object*>& arguments) { |
| 179 String& class_name = String::Handle(); | 124 String& class_name = String::Handle(); |
| 180 switch (type) { | 125 switch (type) { |
| 181 case kIndexOutOfRange: | 126 case kIndexOutOfRange: |
| 182 class_name = String::NewSymbol("IndexOutOfRangeException"); | 127 class_name = String::NewSymbol("IndexOutOfRangeException"); |
| 183 break; | 128 break; |
| 184 case kIllegalArgument: | 129 case kIllegalArgument: |
| 185 class_name = String::NewSymbol("IllegalArgumentException"); | 130 class_name = String::NewSymbol("IllegalArgumentException"); |
| 186 break; | 131 break; |
| 187 case kNoSuchMethod: | 132 case kNoSuchMethod: |
| (...skipping 25 matching lines...) Expand all Loading... |
| 213 break; | 158 break; |
| 214 case kIllegalJSRegExp: | 159 case kIllegalJSRegExp: |
| 215 class_name = String::NewSymbol("IllegalJSRegExpException"); | 160 class_name = String::NewSymbol("IllegalJSRegExpException"); |
| 216 break; | 161 break; |
| 217 } | 162 } |
| 218 | 163 |
| 219 return DartLibraryCalls::ExceptionCreate(class_name, arguments); | 164 return DartLibraryCalls::ExceptionCreate(class_name, arguments); |
| 220 } | 165 } |
| 221 | 166 |
| 222 } // namespace dart | 167 } // namespace dart |
| OLD | NEW |