Exception.h revision 74501e600dcb5634aa26aee0a3f57f2b45b213f2
1/*
2 * Copyright (C) 2008 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 *      http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17/*
18 * Exception handling.
19 */
20#ifndef _DALVIK_EXCEPTION
21#define _DALVIK_EXCEPTION
22
23/* initialization */
24bool dvmExceptionStartup(void);
25void dvmExceptionShutdown(void);
26
27/*
28 * Throw an exception in the current thread, by class descriptor.
29 */
30void dvmThrowChainedException(const char* exceptionDescriptor, const char* msg,
31    Object* cause);
32INLINE void dvmThrowException(const char* exceptionDescriptor,
33    const char* msg)
34{
35    dvmThrowChainedException(exceptionDescriptor, msg, NULL);
36}
37
38/*
39 * Like dvmThrowChainedException, but takes printf-style args for the message.
40 */
41void dvmThrowExceptionFmtV(const char* exceptionDescriptor, const char* fmt,
42    va_list args);
43void dvmThrowExceptionFmt(const char* exceptionDescriptor, const char* fmt, ...)
44#if defined(__GNUC__)
45    __attribute__ ((format(printf, 2, 3)))
46#endif
47    ;
48INLINE void dvmThrowExceptionFmt(const char* exceptionDescriptor,
49    const char* fmt, ...)
50{
51    va_list args;
52    va_start(args, fmt);
53    dvmThrowExceptionFmtV(exceptionDescriptor, fmt, args);
54    va_end(args);
55}
56
57/*
58 * Throw an exception in the current thread, by class object.
59 */
60void dvmThrowChainedExceptionByClass(ClassObject* exceptionClass,
61    const char* msg, Object* cause);
62INLINE void dvmThrowExceptionByClass(ClassObject* exceptionClass,
63    const char* msg)
64{
65    dvmThrowChainedExceptionByClass(exceptionClass, msg, NULL);
66}
67
68/*
69 * Throw the named exception using the human-readable form of the class
70 * descriptor as the exception message, and with the specified cause.
71 */
72void dvmThrowChainedExceptionWithClassMessage(const char* exceptionDescriptor,
73    const char* messageDescriptor, Object* cause);
74INLINE void dvmThrowExceptionWithClassMessage(const char* exceptionDescriptor,
75    const char* messageDescriptor)
76{
77    dvmThrowChainedExceptionWithClassMessage(exceptionDescriptor,
78        messageDescriptor, NULL);
79}
80
81/*
82 * Like dvmThrowException, but take a class object instead of a name
83 * and turn the given message into the human-readable form for a descriptor.
84 */
85void dvmThrowExceptionByClassWithClassMessage(ClassObject* exceptionClass,
86    const char* messageDescriptor);
87
88/*
89 * Return the exception being thrown in the current thread, or NULL if
90 * no exception is pending.
91 */
92INLINE Object* dvmGetException(Thread* self) {
93    return self->exception;
94}
95
96/*
97 * Set the exception being thrown in the current thread.
98 */
99INLINE void dvmSetException(Thread* self, Object* exception)
100{
101    assert(exception != NULL);
102    self->exception = exception;
103}
104
105/*
106 * Clear the pending exception.
107 *
108 * (We use this rather than "set(null)" because we may need to have special
109 * fixups here for StackOverflowError stuff.  Calling "clear" in the code
110 * makes it obvious.)
111 */
112INLINE void dvmClearException(Thread* self) {
113    self->exception = NULL;
114}
115
116/*
117 * Clear the pending exception.  Used by the optimization and verification
118 * code, which has to run with "initializing" set to avoid going into a
119 * death-spin if the "class not found" exception can't be found.
120 */
121void dvmClearOptException(Thread* self);
122
123/*
124 * Returns "true" if an exception is pending.  Use this if you have a
125 * "self" pointer.
126 */
127INLINE bool dvmCheckException(Thread* self) {
128    return (self->exception != NULL);
129}
130
131/*
132 * Returns "true" if this is a "checked" exception, i.e. it's a subclass
133 * of Throwable (assumed) but not a subclass of RuntimeException or Error.
134 */
135bool dvmIsCheckedException(const Object* exception);
136
137/*
138 * Wrap the now-pending exception in a different exception.
139 *
140 * If something fails, an (unchecked) exception related to that failure
141 * will be pending instead.
142 */
143void dvmWrapException(const char* newExcepStr);
144
145/*
146 * Get the "cause" field from an exception.
147 *
148 * Returns NULL if the field is null or uninitialized.
149 */
150Object* dvmGetExceptionCause(const Object* exception);
151
152/*
153 * Print the exception stack trace on stderr.  Calls the exception's
154 * print function.
155 */
156void dvmPrintExceptionStackTrace(void);
157
158/*
159 * Print the exception stack trace to the log file.  The exception stack
160 * trace is computed within the VM.
161 */
162void dvmLogExceptionStackTrace(void);
163
164/*
165 * Search for a catch block that matches "exception".
166 *
167 * "*newFrame" gets a copy of the new frame pointer.
168 *
169 * If "doUnroll" is set, we unroll "thread"s stack as we go (and update
170 * self->curFrame with the same value as in *newFrame).
171 *
172 * Returns the offset to the catch code on success, or -1 if we couldn't
173 * find a catcher.
174 */
175int dvmFindCatchBlock(Thread* self, int relPc, Object* exception,
176    bool doUnroll, void** newFrame);
177
178/*
179 * Support for saving exception stack traces and converting them to
180 * usable form.  Use the "FillIn" function to generate a compact array
181 * that represents the stack frames, then "GetStackTrace" to convert it
182 * to an array of StackTraceElement objects.
183 *
184 * Don't call the "Internal" form of the function directly.
185 */
186void* dvmFillInStackTraceInternal(Thread* thread, bool wantObject, int* pCount);
187/* return an [I for use by interpreted code */
188INLINE Object* dvmFillInStackTrace(Thread* thread) {
189    return (Object*) dvmFillInStackTraceInternal(thread, true, NULL);
190}
191ArrayObject* dvmGetStackTrace(const Object* stackState);
192/* return an int* and array count; caller must free() the return value */
193INLINE int* dvmFillInStackTraceRaw(Thread* thread, int* pCount) {
194    return (int*) dvmFillInStackTraceInternal(thread, false, pCount);
195}
196ArrayObject* dvmGetStackTraceRaw(const int* intVals, int stackDepth);
197
198/*
199 * Print a formatted version of a raw stack trace to the log file.
200 */
201void dvmLogRawStackTrace(const int* intVals, int stackDepth);
202
203/**
204 * Throw an AbstractMethodError in the current thread, with the given detail
205 * message.
206 */
207void dvmThrowAbstractMethodError(const char* msg);
208
209/**
210 * Throw an ArithmeticException in the current thread, with the given detail
211 * message.
212 */
213void dvmThrowArithmeticException(const char* msg);
214
215/*
216 * Throw an ArrayIndexOutOfBoundsException in the current thread,
217 * using the given index and array length in the detail message.
218 */
219void dvmThrowArrayIndexOutOfBoundsException(int index, int length);
220
221/*
222 * Throw an ArrayStoreException in the current thread, using the given classes'
223 * names in the detail message.
224 */
225void dvmThrowArrayStoreException(ClassObject* actual, ClassObject* desired);
226
227/**
228 * Throw a ClassCastException in the current thread, using the given classes'
229 * names in the detail message.
230 */
231void dvmThrowClassCastException(ClassObject* actual, ClassObject* desired);
232
233/**
234 * Throw a ClassCircularityError in the current thread, with the
235 * human-readable form of the given descriptor as the detail message.
236 */
237void dvmThrowClassCircularityError(const char* descriptor);
238
239/**
240 * Throw a ClassFormatError in the current thread, with the given
241 * detail message.
242 */
243void dvmThrowClassFormatError(const char* msg);
244
245/**
246 * Throw a ClassNotFoundException in the current thread, with the given
247 * detail message.
248 */
249void dvmThrowClassNotFoundException(const char* msg);
250
251/**
252 * Throw a FileNotFoundException in the current thread, with the given
253 * detail message.
254 */
255void dvmThrowFileNotFoundException(const char* msg);
256
257/**
258 * Throw an IOException in the current thread, with the given
259 * detail message.
260 */
261void dvmThrowIOException(const char* msg);
262
263/**
264 * Throw an IllegalAccessError in the current thread, with the
265 * given detail message.
266 */
267void dvmThrowIllegalAccessError(const char* msg);
268
269/**
270 * Throw an IllegalAccessException in the current thread, with the
271 * given detail message.
272 */
273void dvmThrowIllegalAccessException(const char* msg);
274
275/**
276 * Throw an IllegalArgumentException in the current thread, with the
277 * given detail message.
278 */
279void dvmThrowIllegalArgumentException(const char* msg);
280
281/**
282 * Throw an IllegalMonitorStateException in the current thread, with
283 * the given detail message.
284 */
285void dvmThrowIllegalMonitorStateException(const char* msg);
286
287/**
288 * Throw an IllegalStateException in the current thread, with
289 * the given detail message.
290 */
291void dvmThrowIllegalStateException(const char* msg);
292
293/**
294 * Throw an IllegalThreadStateException in the current thread, with
295 * the given detail message.
296 */
297void dvmThrowIllegalThreadStateException(const char* msg);
298
299/**
300 * Throw an IncompatibleClassChangeError in the current thread,
301 * the given detail message.
302 */
303void dvmThrowIncompatibleClassChangeError(const char* msg);
304
305/**
306 * Throw an IncompatibleClassChangeError in the current thread, with the
307 * human-readable form of the given descriptor as the detail message.
308 */
309void dvmThrowIncompatibleClassChangeErrorWithClassMessage(
310        const char* descriptor);
311
312/**
313 * Throw an InternalError in the current thread, with the given
314 * detail message.
315 */
316void dvmThrowInternalError(const char* msg);
317
318/**
319 * Throw an InterruptedException in the current thread, with the given
320 * detail message.
321 */
322void dvmThrowInterruptedException(const char* msg);
323
324/**
325 * Throw a LinkageError in the current thread, with the
326 * given detail message.
327 */
328void dvmThrowLinkageError(const char* msg);
329
330/**
331 * Throw a NegativeArraySizeException in the current thread, with the
332 * given detail message.
333 */
334void dvmThrowNegativeArraySizeException(const char* msg);
335
336/**
337 * Throw a NoClassDefFoundError in the current thread, with the
338 * human-readable form of the given descriptor as the detail message.
339 */
340void dvmThrowNoClassDefFoundError(const char* descriptor);
341
342/**
343 * Throw a NoSuchFieldError in the current thread, with the given
344 * detail message.
345 */
346void dvmThrowNoSuchFieldError(const char* msg);
347
348/**
349 * Throw a NoSuchFieldException in the current thread, with the given
350 * detail message.
351 */
352void dvmThrowNoSuchFieldException(const char* msg);
353
354/**
355 * Throw a NoSuchMethodError in the current thread, with the given
356 * detail message.
357 */
358void dvmThrowNoSuchMethodError(const char* msg);
359
360/**
361 * Throw a NullPointerException in the current thread, with the given
362 * detail message.
363 */
364void dvmThrowNullPointerException(const char* msg);
365
366/**
367 * Throw an OutOfMemoryError in the current thread, with the given
368 * detail message.
369 */
370void dvmThrowOutOfMemoryError(const char* msg);
371
372/**
373 * Throw a RuntimeException in the current thread, with the given detail
374 * message.
375 */
376void dvmThrowRuntimeException(const char* msg);
377
378/**
379 * Throw a StaleDexCacheError in the current thread, with
380 * the given detail message.
381 */
382void dvmThrowStaleDexCacheError(const char* msg);
383
384/**
385 * Throw a StringIndexOutOfBoundsException in the current thread, with
386 * the given detail message.
387 */
388void dvmThrowStringIndexOutOfBoundsException(const char* msg);
389
390/**
391 * Throw an UnsatisfiedLinkError in the current thread, with
392 * the given detail message.
393 */
394void dvmThrowUnsatisfiedLinkError(const char* msg);
395
396/**
397 * Throw an UnsupportedOperationException in the current thread, with
398 * the given detail message.
399 */
400void dvmThrowUnsupportedOperationException(const char* msg);
401
402/**
403 * Throw a VirtualMachineError in the current thread, with
404 * the given detail message.
405 */
406void dvmThrowVirtualMachineError(const char* msg);
407
408#endif /*_DALVIK_EXCEPTION*/
409