OSDN Git Service

am de9e2b90: Bug fixes for ld/st elimination.
[android-x86/dalvik.git] / vm / Exception.h
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 #ifdef __cplusplus
24 extern "C" {
25 #endif
26
27 /*
28  * Create a Throwable and throw an exception in the current thread (where
29  * "throwing" just means "set the thread's exception pointer").
30  *
31  * "msg" and/or "cause" may be NULL.
32  *
33  * If we have a bad exception hierarchy -- something in Throwable.<init>
34  * is missing -- then every attempt to throw an exception will result
35  * in another exception.  Exceptions are generally allowed to "chain"
36  * to other exceptions, so it's hard to auto-detect this problem.  It can
37  * only happen if the system classes are broken, so it's probably not
38  * worth spending cycles to detect it.
39  *
40  * We do have one case to worry about: if the classpath is completely
41  * wrong, we'll go into a death spin during startup because we can't find
42  * the initial class and then we can't find NoClassDefFoundError.  We have
43  * to handle this case.
44  */
45 void dvmThrowChainedException(ClassObject* exceptionClass,
46     const char* msg, Object* cause);
47 INLINE void dvmThrowException(ClassObject* exceptionClass,
48     const char* msg)
49 {
50     dvmThrowChainedException(exceptionClass, msg, NULL);
51 }
52
53 /*
54  * Like dvmThrowException, but takes printf-style args for the message.
55  */
56 void dvmThrowExceptionFmtV(ClassObject* exceptionClass,
57     const char* fmt, va_list args);
58 void dvmThrowExceptionFmt(ClassObject* exceptionClass,
59     const char* fmt, ...)
60 #if defined(__GNUC__)
61     __attribute__ ((format(printf, 2, 3)))
62 #endif
63     ;
64 INLINE void dvmThrowExceptionFmt(ClassObject* exceptionClass,
65     const char* fmt, ...)
66 {
67     va_list args;
68     va_start(args, fmt);
69     dvmThrowExceptionFmtV(exceptionClass, fmt, args);
70     va_end(args);
71 }
72
73 /*
74  * Like dvmThrowChainedException, but take a class object
75  * instead of a name and turn the given message into the
76  * human-readable form for a descriptor.
77  */
78 void dvmThrowChainedExceptionWithClassMessage(
79     ClassObject* exceptionClass, const char* messageDescriptor,
80     Object* cause);
81
82 /*
83  * Like dvmThrowException, but take a class object instead of a name
84  * and turn the given message into the human-readable form for a descriptor.
85  */
86 INLINE void dvmThrowExceptionWithClassMessage(
87     ClassObject* exceptionClass, const char* messageDescriptor)
88 {
89     dvmThrowChainedExceptionWithClassMessage(exceptionClass,
90             messageDescriptor, NULL);
91 }
92
93 /*
94  * Return the exception being thrown in the current thread, or NULL if
95  * no exception is pending.
96  */
97 INLINE Object* dvmGetException(Thread* self) {
98     return self->exception;
99 }
100
101 /*
102  * Set the exception being thrown in the current thread.
103  */
104 INLINE void dvmSetException(Thread* self, Object* exception)
105 {
106     assert(exception != NULL);
107     self->exception = exception;
108 }
109
110 /*
111  * Clear the pending exception.
112  *
113  * (We use this rather than "set(null)" because we may need to have special
114  * fixups here for StackOverflowError stuff.  Calling "clear" in the code
115  * makes it obvious.)
116  */
117 INLINE void dvmClearException(Thread* self) {
118     self->exception = NULL;
119 }
120
121 /*
122  * Clear the pending exception.  Used by the optimization and verification
123  * code, which has to run with "initializing" set to avoid going into a
124  * death-spin if the "class not found" exception can't be found.
125  */
126 void dvmClearOptException(Thread* self);
127
128 /*
129  * Returns "true" if an exception is pending.  Use this if you have a
130  * "self" pointer.
131  */
132 INLINE bool dvmCheckException(Thread* self) {
133     return (self->exception != NULL);
134 }
135
136 /*
137  * Returns "true" if this is a "checked" exception, i.e. it's a subclass
138  * of Throwable (assumed) but not a subclass of RuntimeException or Error.
139  */
140 bool dvmIsCheckedException(const Object* exception);
141
142 /*
143  * Wrap the now-pending exception in a different exception.
144  *
145  * If something fails, an (unchecked) exception related to that failure
146  * will be pending instead.
147  */
148 void dvmWrapException(const char* newExcepStr);
149
150 /*
151  * Get the "cause" field from an exception.
152  *
153  * Returns NULL if the field is null or uninitialized.
154  */
155 Object* dvmGetExceptionCause(const Object* exception);
156
157 /*
158  * Print the exception stack trace on stderr.  Calls the exception's
159  * print function.
160  */
161 void dvmPrintExceptionStackTrace(void);
162
163 /*
164  * Print the exception stack trace to the log file.  The exception stack
165  * trace is computed within the VM.
166  */
167 void dvmLogExceptionStackTrace(void);
168
169 /*
170  * Search for a catch block that matches "exception".
171  *
172  * "*newFrame" gets a copy of the new frame pointer.
173  *
174  * If "doUnroll" is set, we unroll "thread"s stack as we go (and update
175  * self->interpSave.curFrame with the same value as in *newFrame).
176  *
177  * Returns the offset to the catch code on success, or -1 if we couldn't
178  * find a catcher.
179  */
180 int dvmFindCatchBlock(Thread* self, int relPc, Object* exception,
181     bool doUnroll, void** newFrame);
182
183 /*
184  * Support for saving exception stack traces and converting them to
185  * usable form.  Use the "FillIn" function to generate a compact array
186  * that represents the stack frames, then "GetStackTrace" to convert it
187  * to an array of StackTraceElement objects.
188  *
189  * Don't call the "Internal" form of the function directly.
190  */
191 void* dvmFillInStackTraceInternal(Thread* thread, bool wantObject, size_t* pCount);
192 /* return an [I for use by interpreted code */
193 INLINE Object* dvmFillInStackTrace(Thread* thread) {
194     return (Object*) dvmFillInStackTraceInternal(thread, true, NULL);
195 }
196 ArrayObject* dvmGetStackTrace(const Object* stackState);
197 /* return an int* and array count; caller must free() the return value */
198 INLINE int* dvmFillInStackTraceRaw(Thread* thread, size_t* pCount) {
199     return (int*) dvmFillInStackTraceInternal(thread, false, pCount);
200 }
201 ArrayObject* dvmGetStackTraceRaw(const int* intVals, size_t stackDepth);
202 void dvmFillStackTraceElements(const int* intVals, size_t stackDepth, ArrayObject* steArray);
203
204 /*
205  * Print a formatted version of a raw stack trace to the log file.
206  */
207 void dvmLogRawStackTrace(const int* intVals, int stackDepth);
208
209 /**
210  * Throw an AbstractMethodError in the current thread, with the given detail
211  * message.
212  */
213 void dvmThrowAbstractMethodError(const char* msg);
214
215 /**
216  * Throw an ArithmeticException in the current thread, with the given detail
217  * message.
218  */
219 void dvmThrowArithmeticException(const char* msg);
220
221 /*
222  * Throw an ArrayIndexOutOfBoundsException in the current thread,
223  * using the given array length and index in the detail message.
224  */
225 void dvmThrowArrayIndexOutOfBoundsException(int length, int index);
226
227 /*
228  * Throw an ArrayStoreException in the current thread, using the given classes'
229  * names in the detail message, indicating that an object of the given type
230  * can't be stored into an array of the given type.
231  */
232 void dvmThrowArrayStoreExceptionIncompatibleElement(ClassObject* objectType,
233         ClassObject* arrayType);
234
235 /*
236  * Throw an ArrayStoreException in the current thread, using the given
237  * class name and argument label in the detail message, indicating
238  * that it is not an array.
239  */
240 void dvmThrowArrayStoreExceptionNotArray(ClassObject* actual, const char* label);
241
242 /*
243  * Throw an ArrayStoreException in the current thread, using the given
244  * classes' names in the detail message, indicating that the arrays
245  * aren't compatible (for copying contents).
246  */
247 void dvmThrowArrayStoreExceptionIncompatibleArrays(ClassObject* source, ClassObject* destination);
248
249 /*
250  * Throw an ArrayStoreException in the current thread, using the given
251  * index and classes' names in the detail message, indicating that the
252  * object at the given index and of the given type cannot be stored
253  * into an array of the given type.
254  */
255 void dvmThrowArrayStoreExceptionIncompatibleArrayElement(s4 index, ClassObject* objectType,
256         ClassObject* arrayType);
257
258 /**
259  * Throw a ClassCastException in the current thread, using the given classes'
260  * names in the detail message.
261  */
262 void dvmThrowClassCastException(ClassObject* actual, ClassObject* desired);
263
264 /**
265  * Throw a ClassCircularityError in the current thread, with the
266  * human-readable form of the given descriptor as the detail message.
267  */
268 void dvmThrowClassCircularityError(const char* descriptor);
269
270 /**
271  * Throw a ClassFormatError in the current thread, with the given
272  * detail message.
273  */
274 void dvmThrowClassFormatError(const char* msg);
275
276 /**
277  * Throw a ClassNotFoundException in the current thread, with the given
278  * class name as the detail message.
279  */
280 void dvmThrowClassNotFoundException(const char* name);
281
282 /**
283  * Throw a ClassNotFoundException in the current thread, with the given
284  * cause, and the given class name as the detail message.
285  */
286 void dvmThrowChainedClassNotFoundException(const char* name, Object* cause);
287
288 /*
289  * Throw the VM-spec-mandated error when an exception is thrown during
290  * class initialization. Unlike other helper functions, this automatically
291  * wraps the current thread's pending exception.
292  */
293 void dvmThrowExceptionInInitializerError(void);
294
295 /**
296  * Throw a FileNotFoundException in the current thread, with the given
297  * detail message.
298  */
299 void dvmThrowFileNotFoundException(const char* msg);
300
301 /**
302  * Throw an IOException in the current thread, with the given
303  * detail message.
304  */
305 void dvmThrowIOException(const char* msg);
306
307 /**
308  * Throw an IllegalAccessError in the current thread, with the
309  * given detail message.
310  */
311 void dvmThrowIllegalAccessError(const char* msg);
312
313 /**
314  * Throw an IllegalAccessException in the current thread, with the
315  * given detail message.
316  */
317 void dvmThrowIllegalAccessException(const char* msg);
318
319 /**
320  * Throw an IllegalArgumentException in the current thread, with the
321  * given detail message.
322  */
323 void dvmThrowIllegalArgumentException(const char* msg);
324
325 /**
326  * Throw an IllegalMonitorStateException in the current thread, with
327  * the given detail message.
328  */
329 void dvmThrowIllegalMonitorStateException(const char* msg);
330
331 /**
332  * Throw an IllegalStateException in the current thread, with
333  * the given detail message.
334  */
335 void dvmThrowIllegalStateException(const char* msg);
336
337 /**
338  * Throw an IllegalThreadStateException in the current thread, with
339  * the given detail message.
340  */
341 void dvmThrowIllegalThreadStateException(const char* msg);
342
343 /**
344  * Throw an IncompatibleClassChangeError in the current thread,
345  * the given detail message.
346  */
347 void dvmThrowIncompatibleClassChangeError(const char* msg);
348
349 /**
350  * Throw an IncompatibleClassChangeError in the current thread, with the
351  * human-readable form of the given descriptor as the detail message.
352  */
353 void dvmThrowIncompatibleClassChangeErrorWithClassMessage(
354         const char* descriptor);
355
356 /**
357  * Throw an InstantiationException in the current thread, with
358  * the human-readable form of the given class as the detail message,
359  * with optional extra detail appended to the message.
360  */
361 void dvmThrowInstantiationException(ClassObject* clazz,
362         const char* extraDetail);
363
364 /**
365  * Throw an InternalError in the current thread, with the given
366  * detail message.
367  */
368 void dvmThrowInternalError(const char* msg);
369
370 /**
371  * Throw an InterruptedException in the current thread, with the given
372  * detail message.
373  */
374 void dvmThrowInterruptedException(const char* msg);
375
376 /**
377  * Throw a LinkageError in the current thread, with the
378  * given detail message.
379  */
380 void dvmThrowLinkageError(const char* msg);
381
382 /**
383  * Throw a NegativeArraySizeException in the current thread, with the
384  * given number as the detail message.
385  */
386 void dvmThrowNegativeArraySizeException(s4 size);
387
388 /**
389  * Throw a NoClassDefFoundError in the current thread, with the
390  * human-readable form of the given descriptor as the detail message.
391  */
392 void dvmThrowNoClassDefFoundError(const char* descriptor);
393
394 /**
395  * Throw a NoClassDefFoundError in the current thread, with the given
396  * cause, and the human-readable form of the given descriptor as the
397  * detail message.
398  */
399 void dvmThrowChainedNoClassDefFoundError(const char* descriptor,
400         Object* cause);
401
402 /**
403  * Throw a NoSuchFieldError in the current thread, with the given
404  * detail message.
405  */
406 void dvmThrowNoSuchFieldError(const char* msg);
407
408 /**
409  * Throw a NoSuchFieldException in the current thread, with the given
410  * detail message.
411  */
412 void dvmThrowNoSuchFieldException(const char* msg);
413
414 /**
415  * Throw a NoSuchMethodError in the current thread, with the given
416  * detail message.
417  */
418 void dvmThrowNoSuchMethodError(const char* msg);
419
420 /**
421  * Throw a NullPointerException in the current thread, with the given
422  * detail message.
423  */
424 void dvmThrowNullPointerException(const char* msg);
425
426 /**
427  * Throw an OutOfMemoryError in the current thread, with the given
428  * detail message.
429  */
430 void dvmThrowOutOfMemoryError(const char* msg);
431
432 /**
433  * Throw a RuntimeException in the current thread, with the given detail
434  * message.
435  */
436 void dvmThrowRuntimeException(const char* msg);
437
438 /**
439  * Throw a StaleDexCacheError in the current thread, with
440  * the given detail message.
441  */
442 void dvmThrowStaleDexCacheError(const char* msg);
443
444 /**
445  * Throw a StringIndexOutOfBoundsException in the current thread, with
446  * a detail message specifying an actual length as well as a requested
447  * index.
448  */
449 void dvmThrowStringIndexOutOfBoundsExceptionWithIndex(jsize stringLength,
450         jsize requestIndex);
451
452 /**
453  * Throw a StringIndexOutOfBoundsException in the current thread, with
454  * a detail message specifying an actual length as well as a requested
455  * region.
456  */
457 void dvmThrowStringIndexOutOfBoundsExceptionWithRegion(jsize stringLength,
458         jsize requestStart, jsize requestLength);
459
460 /**
461  * Throw a TypeNotPresentException in the current thread, with the
462  * human-readable form of the given descriptor as the detail message.
463  */
464 void dvmThrowTypeNotPresentException(const char* descriptor);
465
466 /**
467  * Throw an UnsatisfiedLinkError in the current thread, with
468  * the given detail message.
469  */
470 void dvmThrowUnsatisfiedLinkError(const char* msg);
471
472 /**
473  * Throw an UnsupportedOperationException in the current thread, with
474  * the given detail message.
475  */
476 void dvmThrowUnsupportedOperationException(const char* msg);
477
478 /**
479  * Throw a VerifyError in the current thread, with the
480  * human-readable form of the given descriptor as the detail message.
481  */
482 void dvmThrowVerifyError(const char* descriptor);
483
484 /**
485  * Throw a VirtualMachineError in the current thread, with
486  * the given detail message.
487  */
488 void dvmThrowVirtualMachineError(const char* msg);
489
490 #ifdef __cplusplus
491 }
492 #endif
493
494 #endif /*_DALVIK_EXCEPTION*/