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 |