* src/native/jni.h: Removed.
[cacao.git] / src / native / vm / gnuclasspath / java_lang_VMThrowable.cpp
1 /* src/native/vm/gnuclasspath/java_lang_VMThrowable.cpp
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 <stdint.h>
29 #include <assert.h>
30
31 #include "vm/types.h"
32
33 #include "native/jni.hpp"
34 #include "native/llni.h"
35 #include "native/native.h"
36
37 #if defined(ENABLE_JNI_HEADERS)
38 # include "native/vm/include/java_lang_VMThrowable.h"
39 #endif
40
41 #include "vm/array.h"
42 #include "vm/builtin.h"
43 #include "vm/exceptions.hpp"
44 #include "vm/globals.hpp"
45 #include "vm/javaobjects.hpp"
46 #include "vm/loader.h"
47 #include "vm/string.hpp"
48
49 #include "vm/jit/code.h"
50 #include "vm/jit/linenumbertable.h"
51 #include "vm/jit/stacktrace.hpp"
52
53
54
55 // Native functions are exported as C functions.
56 extern "C" {
57
58 /*
59  * Class:     java/lang/VMThrowable
60  * Method:    fillInStackTrace
61  * Signature: (Ljava/lang/Throwable;)Ljava/lang/VMThrowable;
62  */
63 JNIEXPORT jobject JNICALL Java_java_lang_VMThrowable_fillInStackTrace(JNIEnv *env, jclass clazz, jobject t)
64 {
65         java_handle_t* h;
66         java_handle_bytearray_t* ba;
67
68         h = native_new_and_init(class_java_lang_VMThrowable);
69
70         if (h == NULL)
71                 return NULL;
72
73         java_lang_VMThrowable vmt(h);
74
75         ba = stacktrace_get_current();
76
77         if (ba == NULL)
78                 return NULL;
79
80         vmt.set_vmdata(ba);
81
82         return (jobject) vmt.get_handle();
83 }
84
85
86 /*
87  * Class:     java/lang/VMThrowable
88  * Method:    getStackTrace
89  * Signature: (Ljava/lang/Throwable;)[Ljava/lang/StackTraceElement;
90  */
91 JNIEXPORT jobjectArray JNICALL Java_java_lang_VMThrowable_getStackTrace(JNIEnv *env, jobject _this, jobject t)
92 {
93         java_lang_VMThrowable vmt(_this);
94
95         // Get the stacktrace from the VMThrowable object.
96
97         java_handle_bytearray_t* ba = vmt.get_vmdata();
98
99         // XXX Critical GC section?
100         stacktrace_t* st = (stacktrace_t*) LLNI_array_data(ba);
101
102         assert(st != NULL);
103
104         stacktrace_entry_t* ste = st->entries;
105
106         /* Create the stacktrace element array. */
107
108         java_handle_objectarray_t* oa = builtin_anewarray(st->length, class_java_lang_StackTraceElement);
109
110         if (oa == NULL)
111                 return NULL;
112
113         for (int i = 0; i < st->length; i++, ste++) {
114                 /* Get the codeinfo and methodinfo. */
115
116                 codeinfo*   code = ste->code;
117                 methodinfo* m    = code->m;
118
119                 /* Get filename. */
120
121                 java_handle_t* filename;
122
123                 if (!(m->flags & ACC_NATIVE)) {
124                         if (m->clazz->sourcefile)
125                                 filename = javastring_new(m->clazz->sourcefile);
126                         else
127                                 filename = NULL;
128                 }
129                 else
130                         filename = NULL;
131
132                 /* get line number */
133
134                 int32_t linenumber;
135
136                 if (m->flags & ACC_NATIVE) {
137                         linenumber = -1;
138                 }
139                 else {
140                         /* FIXME The linenumbertable_linenumber_for_pc could
141                            change the methodinfo pointer when hitting an inlined
142                            method. */
143
144                         linenumber = linenumbertable_linenumber_for_pc(&m, code, ste->pc);
145                         linenumber = (linenumber == 0) ? -1 : linenumber;
146                 }
147
148                 /* get declaring class name */
149
150                 java_handle_t* declaringclass = class_get_classname(m->clazz);
151
152                 /* allocate a new stacktrace element */
153
154                 java_handle_t* h = builtin_new(class_java_lang_StackTraceElement);
155
156                 if (h == NULL)
157                         return NULL;
158
159                 java_lang_StackTraceElement ste(h, filename, linenumber, declaringclass, javastring_new(m->name), ((m->flags & ACC_NATIVE) ? 1 : 0));
160
161                 array_objectarray_element_set(oa, i, ste.get_handle());
162         }
163
164         return (jobjectArray) oa;
165 }
166
167 } // extern "C"
168
169
170 /* native methods implemented by this file ************************************/
171
172 static JNINativeMethod methods[] = {
173         { (char*) "fillInStackTrace", (char*) "(Ljava/lang/Throwable;)Ljava/lang/VMThrowable;",        (void*) (uintptr_t) &Java_java_lang_VMThrowable_fillInStackTrace },
174         { (char*) "getStackTrace",    (char*) "(Ljava/lang/Throwable;)[Ljava/lang/StackTraceElement;", (void*) (uintptr_t) &Java_java_lang_VMThrowable_getStackTrace    },
175 };
176
177
178 /* _Jv_java_lang_VMThrowable_init **********************************************
179
180    Register native functions.
181
182 *******************************************************************************/
183
184 extern "C" {
185 void _Jv_java_lang_VMThrowable_init(void)
186 {
187         utf *u;
188
189         u = utf_new_char("java/lang/VMThrowable");
190
191         native_method_register(u, methods, NATIVE_METHODS_COUNT);
192 }
193 }
194
195
196 /*
197  * These are local overrides for various environment variables in Emacs.
198  * Please do not remove this and leave it at the end of the file, where
199  * Emacs will automagically detect them.
200  * ---------------------------------------------------------------------
201  * Local variables:
202  * mode: c++
203  * indent-tabs-mode: t
204  * c-basic-offset: 4
205  * tab-width: 4
206  * End:
207  */