2 * Copyright (C) 2008 The Android Open Source Project
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
8 * http://www.apache.org/licenses/LICENSE-2.0
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.
20 #ifndef _DALVIK_EXCEPTION
21 #define _DALVIK_EXCEPTION
28 * Create a Throwable and throw an exception in the current thread (where
29 * "throwing" just means "set the thread's exception pointer").
31 * "msg" and/or "cause" may be NULL.
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.
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.
45 void dvmThrowChainedException(ClassObject* exceptionClass,
46 const char* msg, Object* cause);
47 INLINE void dvmThrowException(ClassObject* exceptionClass,
50 dvmThrowChainedException(exceptionClass, msg, NULL);
54 * Like dvmThrowException, but takes printf-style args for the message.
56 void dvmThrowExceptionFmtV(ClassObject* exceptionClass,
57 const char* fmt, va_list args);
58 void dvmThrowExceptionFmt(ClassObject* exceptionClass,
61 __attribute__ ((format(printf, 2, 3)))
64 INLINE void dvmThrowExceptionFmt(ClassObject* exceptionClass,
69 dvmThrowExceptionFmtV(exceptionClass, fmt, args);
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.
78 void dvmThrowChainedExceptionWithClassMessage(
79 ClassObject* exceptionClass, const char* messageDescriptor,
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.
86 INLINE void dvmThrowExceptionWithClassMessage(
87 ClassObject* exceptionClass, const char* messageDescriptor)
89 dvmThrowChainedExceptionWithClassMessage(exceptionClass,
90 messageDescriptor, NULL);
94 * Return the exception being thrown in the current thread, or NULL if
95 * no exception is pending.
97 INLINE Object* dvmGetException(Thread* self) {
98 return self->exception;
102 * Set the exception being thrown in the current thread.
104 INLINE void dvmSetException(Thread* self, Object* exception)
106 assert(exception != NULL);
107 self->exception = exception;
111 * Clear the pending exception.
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
117 INLINE void dvmClearException(Thread* self) {
118 self->exception = NULL;
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.
126 void dvmClearOptException(Thread* self);
129 * Returns "true" if an exception is pending. Use this if you have a
132 INLINE bool dvmCheckException(Thread* self) {
133 return (self->exception != NULL);
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.
140 bool dvmIsCheckedException(const Object* exception);
143 * Wrap the now-pending exception in a different exception.
145 * If something fails, an (unchecked) exception related to that failure
146 * will be pending instead.
148 void dvmWrapException(const char* newExcepStr);
151 * Get the "cause" field from an exception.
153 * Returns NULL if the field is null or uninitialized.
155 Object* dvmGetExceptionCause(const Object* exception);
158 * Print the exception stack trace on stderr. Calls the exception's
161 void dvmPrintExceptionStackTrace(void);
164 * Print the exception stack trace to the log file. The exception stack
165 * trace is computed within the VM.
167 void dvmLogExceptionStackTrace(void);
170 * Search for a catch block that matches "exception".
172 * "*newFrame" gets a copy of the new frame pointer.
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).
177 * Returns the offset to the catch code on success, or -1 if we couldn't
180 int dvmFindCatchBlock(Thread* self, int relPc, Object* exception,
181 bool doUnroll, void** newFrame);
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.
189 * Don't call the "Internal" form of the function directly.
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);
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);
201 ArrayObject* dvmGetStackTraceRaw(const int* intVals, size_t stackDepth);
202 void dvmFillStackTraceElements(const int* intVals, size_t stackDepth, ArrayObject* steArray);
205 * Print a formatted version of a raw stack trace to the log file.
207 void dvmLogRawStackTrace(const int* intVals, int stackDepth);
210 * Throw an AbstractMethodError in the current thread, with the given detail
213 void dvmThrowAbstractMethodError(const char* msg);
216 * Throw an ArithmeticException in the current thread, with the given detail
219 void dvmThrowArithmeticException(const char* msg);
222 * Throw an ArrayIndexOutOfBoundsException in the current thread,
223 * using the given array length and index in the detail message.
225 void dvmThrowArrayIndexOutOfBoundsException(int length, int index);
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.
232 void dvmThrowArrayStoreExceptionIncompatibleElement(ClassObject* objectType,
233 ClassObject* arrayType);
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.
240 void dvmThrowArrayStoreExceptionNotArray(ClassObject* actual, const char* label);
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).
247 void dvmThrowArrayStoreExceptionIncompatibleArrays(ClassObject* source, ClassObject* destination);
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.
255 void dvmThrowArrayStoreExceptionIncompatibleArrayElement(s4 index, ClassObject* objectType,
256 ClassObject* arrayType);
259 * Throw a ClassCastException in the current thread, using the given classes'
260 * names in the detail message.
262 void dvmThrowClassCastException(ClassObject* actual, ClassObject* desired);
265 * Throw a ClassCircularityError in the current thread, with the
266 * human-readable form of the given descriptor as the detail message.
268 void dvmThrowClassCircularityError(const char* descriptor);
271 * Throw a ClassFormatError in the current thread, with the given
274 void dvmThrowClassFormatError(const char* msg);
277 * Throw a ClassNotFoundException in the current thread, with the given
278 * class name as the detail message.
280 void dvmThrowClassNotFoundException(const char* name);
283 * Throw a ClassNotFoundException in the current thread, with the given
284 * cause, and the given class name as the detail message.
286 void dvmThrowChainedClassNotFoundException(const char* name, Object* cause);
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.
293 void dvmThrowExceptionInInitializerError(void);
296 * Throw a FileNotFoundException in the current thread, with the given
299 void dvmThrowFileNotFoundException(const char* msg);
302 * Throw an IOException in the current thread, with the given
305 void dvmThrowIOException(const char* msg);
308 * Throw an IllegalAccessError in the current thread, with the
309 * given detail message.
311 void dvmThrowIllegalAccessError(const char* msg);
314 * Throw an IllegalAccessException in the current thread, with the
315 * given detail message.
317 void dvmThrowIllegalAccessException(const char* msg);
320 * Throw an IllegalArgumentException in the current thread, with the
321 * given detail message.
323 void dvmThrowIllegalArgumentException(const char* msg);
326 * Throw an IllegalMonitorStateException in the current thread, with
327 * the given detail message.
329 void dvmThrowIllegalMonitorStateException(const char* msg);
332 * Throw an IllegalStateException in the current thread, with
333 * the given detail message.
335 void dvmThrowIllegalStateException(const char* msg);
338 * Throw an IllegalThreadStateException in the current thread, with
339 * the given detail message.
341 void dvmThrowIllegalThreadStateException(const char* msg);
344 * Throw an IncompatibleClassChangeError in the current thread,
345 * the given detail message.
347 void dvmThrowIncompatibleClassChangeError(const char* msg);
350 * Throw an IncompatibleClassChangeError in the current thread, with the
351 * human-readable form of the given descriptor as the detail message.
353 void dvmThrowIncompatibleClassChangeErrorWithClassMessage(
354 const char* descriptor);
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.
361 void dvmThrowInstantiationException(ClassObject* clazz,
362 const char* extraDetail);
365 * Throw an InternalError in the current thread, with the given
368 void dvmThrowInternalError(const char* msg);
371 * Throw an InterruptedException in the current thread, with the given
374 void dvmThrowInterruptedException(const char* msg);
377 * Throw a LinkageError in the current thread, with the
378 * given detail message.
380 void dvmThrowLinkageError(const char* msg);
383 * Throw a NegativeArraySizeException in the current thread, with the
384 * given number as the detail message.
386 void dvmThrowNegativeArraySizeException(s4 size);
389 * Throw a NoClassDefFoundError in the current thread, with the
390 * human-readable form of the given descriptor as the detail message.
392 void dvmThrowNoClassDefFoundError(const char* descriptor);
395 * Throw a NoClassDefFoundError in the current thread, with the given
396 * cause, and the human-readable form of the given descriptor as the
399 void dvmThrowChainedNoClassDefFoundError(const char* descriptor,
403 * Throw a NoSuchFieldError in the current thread, with the given
406 void dvmThrowNoSuchFieldError(const char* msg);
409 * Throw a NoSuchFieldException in the current thread, with the given
412 void dvmThrowNoSuchFieldException(const char* msg);
415 * Throw a NoSuchMethodError in the current thread, with the given
418 void dvmThrowNoSuchMethodError(const char* msg);
421 * Throw a NullPointerException in the current thread, with the given
424 void dvmThrowNullPointerException(const char* msg);
427 * Throw an OutOfMemoryError in the current thread, with the given
430 void dvmThrowOutOfMemoryError(const char* msg);
433 * Throw a RuntimeException in the current thread, with the given detail
436 void dvmThrowRuntimeException(const char* msg);
439 * Throw a StaleDexCacheError in the current thread, with
440 * the given detail message.
442 void dvmThrowStaleDexCacheError(const char* msg);
445 * Throw a StringIndexOutOfBoundsException in the current thread, with
446 * a detail message specifying an actual length as well as a requested
449 void dvmThrowStringIndexOutOfBoundsExceptionWithIndex(jsize stringLength,
453 * Throw a StringIndexOutOfBoundsException in the current thread, with
454 * a detail message specifying an actual length as well as a requested
457 void dvmThrowStringIndexOutOfBoundsExceptionWithRegion(jsize stringLength,
458 jsize requestStart, jsize requestLength);
461 * Throw a TypeNotPresentException in the current thread, with the
462 * human-readable form of the given descriptor as the detail message.
464 void dvmThrowTypeNotPresentException(const char* descriptor);
467 * Throw an UnsatisfiedLinkError in the current thread, with
468 * the given detail message.
470 void dvmThrowUnsatisfiedLinkError(const char* msg);
473 * Throw an UnsupportedOperationException in the current thread, with
474 * the given detail message.
476 void dvmThrowUnsupportedOperationException(const char* msg);
479 * Throw a VerifyError in the current thread, with the
480 * human-readable form of the given descriptor as the detail message.
482 void dvmThrowVerifyError(const char* descriptor);
485 * Throw a VirtualMachineError in the current thread, with
486 * the given detail message.
488 void dvmThrowVirtualMachineError(const char* msg);
494 #endif /*_DALVIK_EXCEPTION*/