1 /* src/native/vm/gnu/java_lang_VMThrowable.c
3 Copyright (C) 1996-2005, 2006, 2007 R. Grafl, A. Krall, C. Kruegel,
4 C. Oates, R. Obermaisser, M. Platter, M. Probst, S. Ring,
5 E. Steiner, C. Thalinger, D. Thuernbeck, P. Tomsich, C. Ullrich,
6 J. Wenninger, Institut f. Computersprachen - TU Wien
8 This file is part of CACAO.
10 This program is free software; you can redistribute it and/or
11 modify it under the terms of the GNU General Public License as
12 published by the Free Software Foundation; either version 2, or (at
13 your option) any later version.
15 This program is distributed in the hope that it will be useful, but
16 WITHOUT ANY WARRANTY; without even the implied warranty of
17 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
18 General Public License for more details.
20 You should have received a copy of the GNU General Public License
21 along with this program; if not, write to the Free Software
22 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
25 $Id: java_lang_VMThrowable.c 8284 2007-08-10 08:58:39Z michi $
36 #include "native/jni.h"
37 #include "native/llni.h"
38 #include "native/native.h"
40 #include "native/include/gnu_classpath_Pointer.h"
41 #include "native/include/java_lang_Class.h"
42 #include "native/include/java_lang_StackTraceElement.h"
43 #include "native/include/java_lang_Throwable.h"
45 #include "native/include/java_lang_VMThrowable.h"
47 #include "native/vm/java_lang_Class.h"
49 #include "vm/builtin.h"
50 #include "vm/exceptions.h"
51 #include "vm/stringlocal.h"
53 #include "vm/jit/stacktrace.h"
55 #include "vmcore/class.h"
56 #include "vmcore/loader.h"
59 /* native methods implemented by this file ************************************/
61 static JNINativeMethod methods[] = {
62 { "fillInStackTrace", "(Ljava/lang/Throwable;)Ljava/lang/VMThrowable;", (void *) (ptrint) &Java_java_lang_VMThrowable_fillInStackTrace },
63 { "getStackTrace", "(Ljava/lang/Throwable;)[Ljava/lang/StackTraceElement;", (void *) (ptrint) &Java_java_lang_VMThrowable_getStackTrace },
67 /* _Jv_java_lang_VMThrowable_init **********************************************
69 Register native functions.
71 *******************************************************************************/
73 void _Jv_java_lang_VMThrowable_init(void)
77 u = utf_new_char("java/lang/VMThrowable");
79 native_method_register(u, methods, NATIVE_METHODS_COUNT);
84 * Class: java/lang/VMThrowable
85 * Method: fillInStackTrace
86 * Signature: (Ljava/lang/Throwable;)Ljava/lang/VMThrowable;
88 JNIEXPORT java_lang_VMThrowable* JNICALL Java_java_lang_VMThrowable_fillInStackTrace(JNIEnv *env, jclass clazz, java_lang_Throwable *t)
90 java_lang_VMThrowable *o;
91 stacktracecontainer *stc;
93 o = (java_lang_VMThrowable *)
94 native_new_and_init(class_java_lang_VMThrowable);
99 stc = stacktrace_fillInStackTrace();
104 LLNI_field_set_ref(o, vmData, (gnu_classpath_Pointer *) stc);
111 * Class: java/lang/VMThrowable
112 * Method: getStackTrace
113 * Signature: (Ljava/lang/Throwable;)[Ljava/lang/StackTraceElement;
115 JNIEXPORT java_objectarray* JNICALL Java_java_lang_VMThrowable_getStackTrace(JNIEnv *env, java_lang_VMThrowable *this, java_lang_Throwable *t)
117 stacktracecontainer *stc;
118 stacktracebuffer *stb;
119 stacktrace_entry *ste;
120 stacktrace_entry *tmpste;
124 bool inexceptionclass;
125 bool leftexceptionclass;
128 java_objectarray *oa;
130 java_lang_StackTraceElement *o;
131 java_lang_String *filename;
133 java_lang_String *declaringclass;
135 /* get the stacktrace buffer from the VMThrowable object */
137 /*XXX stc = (stacktracecontainer *) this->vmData;*/
138 LLNI_field_get_ref(this, vmData, stc);
141 /* get the class of the Throwable object */
143 LLNI_class_get(t, c);
151 /* skip first 2 elements in stacktrace buffer: */
152 /* 0: VMThrowable.fillInStackTrace */
153 /* 1: Throwable.fillInStackTrace */
155 ste = &(stb->entries[2]);
158 if ((size > 0) && (ste->method != 0)) {
159 /* not a builtin native wrapper*/
161 if ((ste->method->class->name == utf_java_lang_Throwable) &&
162 (ste->method->name == utf_init)) {
163 /* We assume that we are within the initializer of the
164 exception object, the exception object itself should
165 not appear in the stack trace, so we skip till we reach
166 the first function, which is not an init function. */
168 inexceptionclass = false;
169 leftexceptionclass = false;
172 /* check if we are in the exception class */
174 if (ste->method->class == c)
175 inexceptionclass = true;
177 /* check if we left the exception class */
179 if (inexceptionclass && (ste->method->class != c))
180 leftexceptionclass = true;
182 /* Found exception start point if we left the
183 initalizers or we left the exception class. */
185 if ((ste->method->name != utf_init) || leftexceptionclass)
188 /* go to next stacktrace element */
197 /* now fill the stacktrace into java objects */
199 m = class_findmethod(class_java_lang_StackTraceElement,
201 utf_new_char("(Ljava/lang/String;ILjava/lang/String;Ljava/lang/String;Z)V"));
206 /* count entries with a method name */
208 for (oalength = 0, i = size, tmpste = ste; i > 0; i--, tmpste++)
212 /* create the stacktrace element array */
214 oa = builtin_anewarray(oalength, class_java_lang_StackTraceElement);
219 for (i = 0; size > 0; size--, ste++, i++) {
220 /* skip entries without a method name */
222 if (ste->method == NULL) {
227 /* allocate a new stacktrace element */
229 o = (java_lang_StackTraceElement *)
230 builtin_new(class_java_lang_StackTraceElement);
237 if (!(ste->method->flags & ACC_NATIVE)) {
238 if (ste->method->class->sourcefile)
239 filename = (java_lang_String *) javastring_new(ste->method->class->sourcefile);
246 /* get line number */
248 if (ste->method->flags & ACC_NATIVE)
251 linenumber = (ste->linenumber == 0) ? -1 : ste->linenumber;
253 /* get declaring class name */
256 _Jv_java_lang_Class_getName((java_lang_Class *) ste->method->class);
258 /* fill the java.lang.StackTraceElement element */
260 LLNI_field_set_ref(o, fileName , filename);
261 LLNI_field_set_val(o, lineNumber , linenumber);
262 LLNI_field_set_ref(o, declaringClass, declaringclass);
263 LLNI_field_set_ref(o, methodName , (java_lang_String *) javastring_new(ste->method->name));
264 LLNI_field_set_val(o, isNative , (ste->method->flags & ACC_NATIVE) ? 1 : 0);
266 oa->data[i] = (java_objectheader *) o;
274 * These are local overrides for various environment variables in Emacs.
275 * Please do not remove this and leave it at the end of the file, where
276 * Emacs will automagically detect them.
277 * ---------------------------------------------------------------------
280 * indent-tabs-mode: t