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
34 #include "native/jni.h"
35 #include "native/llni.h"
36 #include "native/native.h"
38 #include "native/include/gnu_classpath_Pointer.h"
39 #include "native/include/java_lang_Class.h"
40 #include "native/include/java_lang_StackTraceElement.h"
41 #include "native/include/java_lang_Throwable.h"
43 #include "native/include/java_lang_VMThrowable.h"
45 #include "native/vm/java_lang_Class.h"
47 #include "vm/builtin.h"
48 #include "vm/exceptions.h"
49 #include "vm/stringlocal.h"
51 #include "vm/jit/stacktrace.h"
53 #include "vmcore/class.h"
54 #include "vmcore/loader.h"
57 /* native methods implemented by this file ************************************/
59 static JNINativeMethod methods[] = {
60 { "fillInStackTrace", "(Ljava/lang/Throwable;)Ljava/lang/VMThrowable;", (void *) (ptrint) &Java_java_lang_VMThrowable_fillInStackTrace },
61 { "getStackTrace", "(Ljava/lang/Throwable;)[Ljava/lang/StackTraceElement;", (void *) (ptrint) &Java_java_lang_VMThrowable_getStackTrace },
65 /* _Jv_java_lang_VMThrowable_init **********************************************
67 Register native functions.
69 *******************************************************************************/
71 void _Jv_java_lang_VMThrowable_init(void)
75 u = utf_new_char("java/lang/VMThrowable");
77 native_method_register(u, methods, NATIVE_METHODS_COUNT);
82 * Class: java/lang/VMThrowable
83 * Method: fillInStackTrace
84 * Signature: (Ljava/lang/Throwable;)Ljava/lang/VMThrowable;
86 JNIEXPORT java_lang_VMThrowable* JNICALL Java_java_lang_VMThrowable_fillInStackTrace(JNIEnv *env, jclass clazz, java_lang_Throwable *t)
88 java_lang_VMThrowable *o;
89 stacktracecontainer *stc;
91 o = (java_lang_VMThrowable *)
92 native_new_and_init(class_java_lang_VMThrowable);
97 stc = stacktrace_fillInStackTrace();
102 LLNI_field_set_ref(o, vmData, (gnu_classpath_Pointer *) stc);
109 * Class: java/lang/VMThrowable
110 * Method: getStackTrace
111 * Signature: (Ljava/lang/Throwable;)[Ljava/lang/StackTraceElement;
113 JNIEXPORT java_handle_objectarray_t* JNICALL Java_java_lang_VMThrowable_getStackTrace(JNIEnv *env, java_lang_VMThrowable *this, java_lang_Throwable *t)
115 stacktracecontainer *stc;
116 stacktracebuffer *stb;
117 stacktrace_entry *ste;
118 stacktrace_entry *tmpste;
122 bool inexceptionclass;
123 bool leftexceptionclass;
126 java_handle_objectarray_t *oa;
128 java_lang_StackTraceElement *o;
129 java_lang_String *filename;
131 java_lang_String *declaringclass;
133 /* get the stacktrace buffer from the VMThrowable object */
135 /*XXX stc = (stacktracecontainer *) this->vmData;*/
136 LLNI_field_get_ref(this, vmData, stc);
139 /* get the class of the Throwable object */
141 LLNI_class_get(t, c);
149 /* skip first 2 elements in stacktrace buffer: */
150 /* 0: VMThrowable.fillInStackTrace */
151 /* 1: Throwable.fillInStackTrace */
153 ste = &(stb->entries[2]);
156 if ((size > 0) && (ste->method != 0)) {
157 /* not a builtin native wrapper*/
159 if ((ste->method->class->name == utf_java_lang_Throwable) &&
160 (ste->method->name == utf_init)) {
161 /* We assume that we are within the initializer of the
162 exception object, the exception object itself should
163 not appear in the stack trace, so we skip till we reach
164 the first function, which is not an init function. */
166 inexceptionclass = false;
167 leftexceptionclass = false;
170 /* check if we are in the exception class */
172 if (ste->method->class == c)
173 inexceptionclass = true;
175 /* check if we left the exception class */
177 if (inexceptionclass && (ste->method->class != c))
178 leftexceptionclass = true;
180 /* Found exception start point if we left the
181 initalizers or we left the exception class. */
183 if ((ste->method->name != utf_init) || leftexceptionclass)
186 /* go to next stacktrace element */
195 /* now fill the stacktrace into java objects */
197 m = class_findmethod(class_java_lang_StackTraceElement,
199 utf_new_char("(Ljava/lang/String;ILjava/lang/String;Ljava/lang/String;Z)V"));
204 /* count entries with a method name */
206 for (oalength = 0, i = size, tmpste = ste; i > 0; i--, tmpste++)
210 /* create the stacktrace element array */
212 oa = builtin_anewarray(oalength, class_java_lang_StackTraceElement);
217 for (i = 0; size > 0; size--, ste++, i++) {
218 /* skip entries without a method name */
220 if (ste->method == NULL) {
225 /* allocate a new stacktrace element */
227 o = (java_lang_StackTraceElement *)
228 builtin_new(class_java_lang_StackTraceElement);
235 if (!(ste->method->flags & ACC_NATIVE)) {
236 if (ste->method->class->sourcefile)
237 filename = (java_lang_String *) javastring_new(ste->method->class->sourcefile);
244 /* get line number */
246 if (ste->method->flags & ACC_NATIVE)
249 linenumber = (ste->linenumber == 0) ? -1 : ste->linenumber;
251 /* get declaring class name */
254 _Jv_java_lang_Class_getName(LLNI_classinfo_wrap(ste->method->class));
256 /* fill the java.lang.StackTraceElement element */
258 LLNI_field_set_ref(o, fileName , filename);
259 LLNI_field_set_val(o, lineNumber , linenumber);
260 LLNI_field_set_ref(o, declaringClass, declaringclass);
261 LLNI_field_set_ref(o, methodName , (java_lang_String *) javastring_new(ste->method->name));
262 LLNI_field_set_val(o, isNative , (ste->method->flags & ACC_NATIVE) ? 1 : 0);
264 LLNI_objectarray_element_set(oa, i, o);
272 * These are local overrides for various environment variables in Emacs.
273 * Please do not remove this and leave it at the end of the file, where
274 * Emacs will automagically detect them.
275 * ---------------------------------------------------------------------
278 * indent-tabs-mode: t