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 Error& error) { | |
siva
2012/01/31 00:52:34
We need an assertion here that this is called only
turnidge
2012/01/31 21:56:31
Added.
| |
134 if (error.IsUnhandledException()) { | |
135 // If the error object represents an unhandled exception, then | |
136 // rethrow the exception in the normal fashion. | |
137 UnhandledException& uhe = UnhandledException::Handle(); | |
138 uhe ^= error.raw(); | |
139 const Instance& exc = Instance::Handle(uhe.exception()); | |
140 const Instance& stk = Instance::Handle(uhe.stacktrace()); | |
141 Exceptions::ReThrow(exc, stk); | |
142 } else { | |
143 // Return to the invocation stub and return this error object. The | |
144 // C++ code which invoked this dart sequence can check and do the | |
145 // appropriate thing. | |
146 uword handler_pc = 0; | |
147 uword handler_sp = 0; | |
148 uword handler_fp = 0; | |
149 FindErrorHandler(&handler_pc, &handler_sp, &handler_fp); | |
150 CPU::JumpToErrorHandler(handler_pc, handler_sp, handler_fp, error); | |
siva
2012/01/31 00:52:34
Will we get a stack trace for these error cases, p
turnidge
2012/01/31 21:56:31
It might be helpful to have a stack trace in these
siva
2012/02/01 19:09:38
Yes I agree we should plan on any enhancements to
| |
151 } | |
152 UNREACHABLE(); | |
153 } | |
154 | |
155 | |
115 void Exceptions::ThrowByType( | 156 void Exceptions::ThrowByType( |
116 ExceptionType type, const GrowableArray<const Object*>& arguments) { | 157 ExceptionType type, const GrowableArray<const Object*>& arguments) { |
117 const Instance& exception = Instance::Handle(Create(type, arguments)); | 158 const Object& result = Object::Handle(Create(type, arguments)); |
118 Throw(exception); | 159 if (result.IsError()) { |
160 // We got an error while constructing the exception object. | |
161 // Propagate the error instead of throwing the exception. | |
162 Error& error = Error::Handle(); | |
163 error ^= result.raw(); | |
164 PropagateError(error); | |
165 } else { | |
166 ASSERT(result.IsInstance()); | |
167 Instance& exception = Instance::Handle(); | |
168 exception ^= result.raw(); | |
169 Throw(exception); | |
170 } | |
119 } | 171 } |
120 | 172 |
121 | 173 |
122 RawInstance* Exceptions::Create( | 174 RawObject* Exceptions::Create( |
123 ExceptionType type, const GrowableArray<const Object*>& arguments) { | 175 ExceptionType type, const GrowableArray<const Object*>& arguments) { |
124 String& class_name = String::Handle(); | 176 String& class_name = String::Handle(); |
125 switch (type) { | 177 switch (type) { |
126 case kIndexOutOfRange: | 178 case kIndexOutOfRange: |
127 class_name = String::NewSymbol("IndexOutOfRangeException"); | 179 class_name = String::NewSymbol("IndexOutOfRangeException"); |
128 break; | 180 break; |
129 case kIllegalArgument: | 181 case kIllegalArgument: |
130 class_name = String::NewSymbol("IllegalArgumentException"); | 182 class_name = String::NewSymbol("IllegalArgumentException"); |
131 break; | 183 break; |
132 case kNoSuchMethod: | 184 case kNoSuchMethod: |
(...skipping 25 matching lines...) Expand all Loading... | |
158 break; | 210 break; |
159 case kIllegalJSRegExp: | 211 case kIllegalJSRegExp: |
160 class_name = String::NewSymbol("IllegalJSRegExpException"); | 212 class_name = String::NewSymbol("IllegalJSRegExpException"); |
161 break; | 213 break; |
162 } | 214 } |
163 | 215 |
164 return DartLibraryCalls::ExceptionCreate(class_name, arguments); | 216 return DartLibraryCalls::ExceptionCreate(class_name, arguments); |
165 } | 217 } |
166 | 218 |
167 } // namespace dart | 219 } // namespace dart |
OLD | NEW |