Forgot to add INSTALL_PREFIX in CFLAGS.
[cacao.git] / src / native / vm / VMThrowable.c
1 /* native/vm/VMThrowable.c - java/lang/VMThrowable
2
3    Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003
4    R. Grafl, A. Krall, C. Kruegel, C. Oates, R. Obermaisser,
5    M. Probst, S. Ring, E. Steiner, C. Thalinger, D. Thuernbeck,
6    P. Tomsich, J. Wenninger
7
8    This file is part of CACAO.
9
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.
14
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.
19
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., 59 Temple Place - Suite 330, Boston, MA
23    02111-1307, USA.
24
25    Contact: cacao@complang.tuwien.ac.at
26
27    Authors: Joseph Wenninger
28
29    $Id: VMThrowable.c 1621 2004-11-30 13:06:55Z twisti $
30
31 */
32
33
34 #include "native/jni.h"
35 #include "native/native.h"
36 #include "native/include/java_lang_Class.h"
37 #include "native/include/java_lang_Throwable.h"
38 #include "native/include/java_lang_VMClass.h"
39 #include "native/include/java_lang_VMThrowable.h"
40 #include "vm/builtin.h"
41 #include "vm/loader.h"
42 #include "vm/tables.h"
43 #include "vm/jit/asmpart.h"
44
45
46 /*
47  * Class:     java/lang/VMThrowable
48  * Method:    fillInStackTrace
49  * Signature: (Ljava/lang/Throwable;)Ljava/lang/VMThrowable;
50  */
51 JNIEXPORT java_lang_VMThrowable* JNICALL Java_java_lang_VMThrowable_fillInStackTrace(JNIEnv *env, jclass clazz, java_lang_Throwable *par1)
52 {
53         classinfo *class_java_lang_VMThrowable = NULL;
54         java_lang_VMThrowable *vmthrow;
55
56         if (!class_java_lang_VMThrowable)
57                 class_java_lang_VMThrowable = class_new(utf_new_char("java/lang/VMThrowable"));
58
59         if (class_java_lang_VMThrowable == NULL)
60                 panic("Needed class java.lang.VMThrowable missing");
61
62         vmthrow = (java_lang_VMThrowable *) native_new_and_init(class_java_lang_VMThrowable);
63
64         if (vmthrow == NULL)
65                 panic("Needed instance of class  java.lang.VMThrowable could not be created");
66
67 #if defined(__I386__)
68         (void) asm_get_stackTrace(&(vmthrow->vmData));
69 #else
70         vmthrow->vmData=0;
71 #endif
72
73         return vmthrow;
74 }
75
76
77
78 java_objectarray* generateStackTraceArray(JNIEnv *env,stacktraceelement *source,long pos,long size)
79 {
80         long resultPos;
81         methodinfo *m;
82         classinfo *c;
83         java_objectarray *oa;
84
85         c = class_new(utf_new_char("java/lang/StackTraceElement"));
86
87         if (!c->loaded)
88                 class_load(c);
89
90         if (!c->linked)
91                 class_link(c);
92
93         m = class_findmethod(c,
94                                                  utf_new_char("<init>"),
95                                                  utf_new_char("(Ljava/lang/String;ILjava/lang/String;Ljava/lang/String;Z)V"));
96
97         if (!m)
98                 panic("java.lang.StackTraceElement misses needed constructor"); 
99
100         oa = builtin_anewarray(size, c);
101
102         if (!oa)
103                 return 0;
104
105 /*      printf("Should return an array with %ld element(s)\n",size);*/
106         pos--;
107         
108         
109         for(resultPos=0;pos>=0;resultPos++,pos--) {
110                 java_objectheader *element;
111
112                 if (source[pos].method==0) {
113                         resultPos--;
114                         continue;
115                 }
116
117                 element=builtin_new(c);
118                 if (!element) {
119                         panic("Memory for stack trace element could not be allocated");
120                 }
121 #ifdef __GNUC__
122 #warning call constructor once jni is fixed to allow more than three parameters
123 #endif
124 #if 0
125                 (*env)->CallVoidMethod(env,element,m,
126                         javastring_new(source[pos].method->class->sourcefile),
127                         source[size].linenumber,
128                         javastring_new(source[pos].method->class->name),
129                         javastring_new(source[pos].method->name),
130                         source[pos].method->flags & ACC_NATIVE);
131 #else
132                 if (!(source[pos].method->flags & ACC_NATIVE))setfield_critical(c,element,"fileName",          
133                 "Ljava/lang/String;",  jobject, 
134                 (jobject) javastring_new(source[pos].method->class->sourcefile));
135 /*              setfield_critical(c,element,"className",          "Ljava/lang/String;",  jobject,  */
136 /*              (jobject) javastring_new(source[pos].method->class->name)); */
137                 setfield_critical(c,element,"declaringClass",      "Ljava/lang/String;",  jobject, 
138                 (jobject) Java_java_lang_VMClass_getName(env, NULL, (java_lang_Class *) source[pos].method->class));
139                 setfield_critical(c,element,"methodName",          "Ljava/lang/String;",  jobject, 
140                 (jobject) javastring_new(source[pos].method->name));
141                 setfield_critical(c,element,"lineNumber",          "I",  jint, 
142                 (jint) ((source[pos].method->flags & ACC_NATIVE) ? -1:(source[pos].linenumber)));
143                 setfield_critical(c,element,"isNative",          "Z",  jboolean, 
144                 (jboolean) ((source[pos].method->flags & ACC_NATIVE) ? 1:0));
145
146
147 #endif                  
148
149                 oa->data[resultPos]=element;
150         }
151
152         return oa;
153
154 }
155
156
157 /*
158  * Class:     java/lang/VMThrowable
159  * Method:    getStackTrace
160  * Signature: (Ljava/lang/Throwable;)[Ljava/lang/StackTraceElement;
161  */
162 JNIEXPORT java_objectarray* JNICALL Java_java_lang_VMThrowable_getStackTrace(JNIEnv *env, java_lang_VMThrowable *this, java_lang_Throwable *par1)
163 {
164         long  pos;
165         long  maxpos;
166         long  sizediff;
167         utf*  classname=par1->header.vftbl->class->name;
168         utf*  init=utf_new_char("<init>");
169         utf*  throwable=utf_new_char("java/lang/Throwable");
170         stacktraceelement *el=(stacktraceelement*)this->vmData;
171
172         /*      log_text("Java_java_lang_VMThrowable_getStackTrace");
173         utf_display(par1->header.vftbl->class->name);
174         printf("\n----------------------------------------------\n");*/
175
176         sizediff=0;
177         if (el == 0) {
178                 return generateStackTraceArray(env, el, 0,0);
179         }       
180
181         for (pos = 0; !((el[pos].method == 0) && (el[pos].linenumber ==-1)); pos++) {
182                 if (el[pos].method==0) sizediff++;
183         }
184
185         if (pos == 0) {
186                 panic("Stacktrace cannot have zero length");
187         }
188
189         pos--;
190         pos--;
191         maxpos = pos;
192         if (el[pos].method!=0) { /* if == 0 -> some builtin native */
193                 if (el[pos].method->class->name == throwable && el[pos].method->name == init) {
194                         for (; pos >= 0 && el[pos].method->name == init && el[pos].method->class->name != classname; pos--) {
195 /*                              log_text("ignoring:");
196                                 utf_display(el[pos].method->name);
197                                 log_text("");
198                                 utf_display(el[pos].method->class->name);
199                                 log_text("");*/
200
201                         };
202                         pos--;
203                         if (pos < 0) {
204                                 log_text("Invalid stack trace for Throwable.getStackTrace()");
205
206                         }
207                 }
208         }
209         
210         /* build the result array*/
211         pos++; /*arraysize*/
212
213         return generateStackTraceArray(env,el,pos,pos-sizediff);        
214 }
215
216
217 /*
218  * These are local overrides for various environment variables in Emacs.
219  * Please do not remove this and leave it at the end of the file, where
220  * Emacs will automagically detect them.
221  * ---------------------------------------------------------------------
222  * Local variables:
223  * mode: c
224  * indent-tabs-mode: t
225  * c-basic-offset: 4
226  * tab-width: 4
227  * End:
228  */