* src/vmcore/linker.c (build_display_inner): Use MNEW instead of malloc.
[cacao.git] / src / native / vm / gnuclasspath / java_lang_VMThrowable.c
1 /* src/native/vm/gnu/java_lang_VMThrowable.c
2
3    Copyright (C) 1996-2005, 2006, 2007, 2008
4    CACAOVM - Verein zur Foerderung der freien virtuellen Maschine CACAO
5
6    This file is part of CACAO.
7
8    This program is free software; you can redistribute it and/or
9    modify it under the terms of the GNU General Public License as
10    published by the Free Software Foundation; either version 2, or (at
11    your option) any later version.
12
13    This program is distributed in the hope that it will be useful, but
14    WITHOUT ANY WARRANTY; without even the implied warranty of
15    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
16    General Public License for more details.
17
18    You should have received a copy of the GNU General Public License
19    along with this program; if not, write to the Free Software
20    Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
21    02110-1301, USA.
22
23 */
24
25
26 #include "config.h"
27
28 #include <assert.h>
29
30 #include "vm/types.h"
31
32 #include "native/jni.h"
33 #include "native/llni.h"
34 #include "native/native.h"
35
36 #include "native/include/java_lang_Object.h"
37 #include "native/include/java_lang_Class.h"
38 #include "native/include/java_lang_String.h"
39 #include "native/include/java_lang_StackTraceElement.h"
40 #include "native/include/java_lang_Throwable.h"
41
42 #include "native/include/java_lang_VMThrowable.h"
43
44 #include "vm/array.h"
45 #include "vm/builtin.h"
46 #include "vm/exceptions.h"
47 #include "vm/stringlocal.h"
48
49 #include "vm/jit/code.h"
50 #include "vm/jit/linenumbertable.h"
51 #include "vm/jit/stacktrace.h"
52
53 #include "vmcore/class.h"
54 #include "vmcore/loader.h"
55
56
57 /* native methods implemented by this file ************************************/
58
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    },
62 };
63
64
65 /* _Jv_java_lang_VMThrowable_init **********************************************
66
67    Register native functions.
68
69 *******************************************************************************/
70
71 void _Jv_java_lang_VMThrowable_init(void)
72 {
73         utf *u;
74
75         u = utf_new_char("java/lang/VMThrowable");
76
77         native_method_register(u, methods, NATIVE_METHODS_COUNT);
78 }
79
80
81 /*
82  * Class:     java/lang/VMThrowable
83  * Method:    fillInStackTrace
84  * Signature: (Ljava/lang/Throwable;)Ljava/lang/VMThrowable;
85  */
86 JNIEXPORT java_lang_VMThrowable* JNICALL Java_java_lang_VMThrowable_fillInStackTrace(JNIEnv *env, jclass clazz, java_lang_Throwable *t)
87 {
88         java_lang_VMThrowable   *vmto;
89         java_handle_bytearray_t *ba;
90         java_lang_Object        *o;
91
92         vmto = (java_lang_VMThrowable *)
93                 native_new_and_init(class_java_lang_VMThrowable);
94
95         if (vmto == NULL)
96                 return NULL;
97
98         ba = stacktrace_get_current();
99
100         if (ba == NULL)
101                 return NULL;
102
103         o = (java_lang_Object *) ba;
104
105         LLNI_field_set_ref(vmto, vmdata, o);
106
107         return vmto;
108 }
109
110
111 /*
112  * Class:     java/lang/VMThrowable
113  * Method:    getStackTrace
114  * Signature: (Ljava/lang/Throwable;)[Ljava/lang/StackTraceElement;
115  */
116 JNIEXPORT java_handle_objectarray_t* JNICALL Java_java_lang_VMThrowable_getStackTrace(JNIEnv *env, java_lang_VMThrowable *this, java_lang_Throwable *t)
117 {
118         java_lang_Object            *o;
119         java_handle_bytearray_t     *ba;
120         stacktrace_t                *st;
121         stacktrace_entry_t          *ste;
122         java_handle_objectarray_t   *oa;
123         java_lang_StackTraceElement *steo;
124         codeinfo                    *code;
125         methodinfo                  *m;
126         java_lang_String            *filename;
127         s4                           linenumber;
128         java_handle_t               *declaringclass;
129         int                          i;
130
131         /* Get the stacktrace from the VMThrowable object. */
132
133         LLNI_field_get_ref(this, vmdata, o);
134
135         ba = (java_handle_bytearray_t *) o;
136
137         st = (stacktrace_t *) LLNI_array_data(ba);
138
139         assert(st != NULL);
140
141         ste = st->entries;
142
143         /* Create the stacktrace element array. */
144
145         oa = builtin_anewarray(st->length, class_java_lang_StackTraceElement);
146
147         if (oa == NULL)
148                 return NULL;
149
150         for (i = 0; i < st->length; i++, ste++) {
151                 /* allocate a new stacktrace element */
152
153                 steo = (java_lang_StackTraceElement *)
154                         builtin_new(class_java_lang_StackTraceElement);
155
156                 if (steo == NULL)
157                         return NULL;
158
159                 /* Get the codeinfo and methodinfo. */
160
161                 code = ste->code;
162                 m    = code->m;
163
164                 /* Get filename. */
165
166                 if (!(m->flags & ACC_NATIVE)) {
167                         if (m->clazz->sourcefile)
168                                 filename = (java_lang_String *) javastring_new(m->clazz->sourcefile);
169                         else
170                                 filename = NULL;
171                 }
172                 else
173                         filename = NULL;
174
175                 /* get line number */
176
177                 if (m->flags & ACC_NATIVE) {
178                         linenumber = -1;
179                 }
180                 else {
181                         /* FIXME The linenumbertable_linenumber_for_pc could
182                            change the methodinfo pointer when hitting an inlined
183                            method. */
184
185                         linenumber = linenumbertable_linenumber_for_pc(&m, code, ste->pc);
186                         linenumber = (linenumber == 0) ? -1 : linenumber;
187                 }
188
189                 /* get declaring class name */
190
191                 declaringclass = class_get_classname(m->clazz);
192
193                 /* Fill the java.lang.StackTraceElement object. */
194
195                 LLNI_field_set_ref(steo, fileName      , filename);
196                 LLNI_field_set_val(steo, lineNumber    , linenumber);
197                 LLNI_field_set_ref(steo, declaringClass, (java_lang_String*) declaringclass);
198                 LLNI_field_set_ref(steo, methodName    , (java_lang_String *) javastring_new(m->name));
199                 LLNI_field_set_val(steo, isNative      , (m->flags & ACC_NATIVE) ? 1 : 0);
200
201                 array_objectarray_element_set(oa, i, (java_handle_t *) steo);
202         }
203
204         return oa;
205 }
206
207
208 /*
209  * These are local overrides for various environment variables in Emacs.
210  * Please do not remove this and leave it at the end of the file, where
211  * Emacs will automagically detect them.
212  * ---------------------------------------------------------------------
213  * Local variables:
214  * mode: c
215  * indent-tabs-mode: t
216  * c-basic-offset: 4
217  * tab-width: 4
218  * End:
219  */