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 |