* src/native/jni.h: Removed.
[cacao.git] / src / native / vm / gnuclasspath / gnu_classpath_jdwp_VMMethod.c
1 /* src/native/vm/gnu/gnu_classpath_jdwp_VMMethod.c - jdwp->jvmti interface
2
3    Copyright (C) 1996-2005, 2006, 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
30 #include "native/jni.hpp"
31
32 #include "native/include/gnu_classpath_jdwp_VMMethod.h"
33
34 #include "native/jvmti/jvmti.h"
35 #include "native/jvmti/VMjdwp.h"
36
37
38 void printjvmtierror(char *desc, jvmtiError err) {
39     char* errdesc;
40         
41         if (err == JVMTI_ERROR_NONE) return;
42         (*jvmtienv)->GetErrorName(jvmtienv,err, &errdesc);
43         fprintf(stderr,"%s: jvmti error %s\n",desc, errdesc);
44         fflush(stderr);
45         (*jvmtienv)->Deallocate(jvmtienv,(unsigned char*)errdesc);
46 }
47
48
49
50 /*
51  * Class:     gnu/classpath/jdwp/VMMethod
52  * Method:    getName
53  * Signature: ()Ljava/lang/String;
54  */
55 JNIEXPORT struct java_lang_String* JNICALL Java_gnu_classpath_jdwp_VMMethod_getName(JNIEnv *env, gnu_classpath_jdwp_VMMethod* this) 
56 {
57     jvmtiError err;
58     char *name;
59     jstring stringname;
60     
61     if (JVMTI_ERROR_NONE != (err= (*jvmtienv)->
62                              GetMethodName(jvmtienv, 
63                                                                                    (jmethodID)(long)this->_methodId,
64                                            &name,NULL, NULL))) {
65                 printjvmtierror("VMMethod.getName GetMethodName",err);
66         return NULL;
67     }
68     
69     stringname = (*env)->NewStringUTF(env,name);
70     (*jvmtienv)->Deallocate(jvmtienv,(unsigned char*)name);
71
72     return stringname;
73 }
74
75
76 /*
77  * Class:     gnu/classpath/jdwp/VMMethod
78  * Method:    getSignature
79  * Signature: ()Ljava/lang/String;
80  */
81 JNIEXPORT struct java_lang_String* JNICALL Java_gnu_classpath_jdwp_VMMethod_getSignature(JNIEnv *env, gnu_classpath_jdwp_VMMethod* this) 
82 {
83     jvmtiError err;
84     char *signature;
85     jstring stringsignature;
86     
87     if (JVMTI_ERROR_NONE != (err= (*jvmtienv)->
88                              GetMethodName(jvmtienv, 
89                                                                                    (jmethodID)(long)this->_methodId,
90                                            NULL, &signature, NULL))) {
91                 printjvmtierror("VMMethod.getSignature GetMethodName",err);
92         return NULL;
93     }
94     
95     stringsignature = (*env)->NewStringUTF(env,signature);
96     (*jvmtienv)->Deallocate(jvmtienv,(unsigned char*)signature);
97     
98     return stringsignature;
99 }
100
101
102 /*
103  * Class:     gnu/classpath/jdwp/VMMethod
104  * Method:    getModifiers
105  * Signature: ()I
106  */
107 JNIEXPORT int32_t JNICALL Java_gnu_classpath_jdwp_VMMethod_getModifiers(JNIEnv *env, gnu_classpath_jdwp_VMMethod* this) 
108 {
109     jvmtiError err;
110     jint modifiers;
111         
112     if (JVMTI_ERROR_NONE!=(err= (*jvmtienv)->
113                                                    GetMethodModifiers(jvmtienv, 
114                                                                                           (jmethodID)(long)this->_methodId,
115                                                                                           &modifiers))) {
116                 printjvmtierror("VMMethod.getModifiers GetMethodModifiers",err);
117         return 0;
118     }
119     
120     return modifiers;
121 }
122
123
124 /*
125  * Class:     gnu/classpath/jdwp/VMMethod
126  * Method:    getLineTable
127  * Signature: ()Lgnu/classpath/jdwp/util/LineTable;
128  */
129 JNIEXPORT struct gnu_classpath_jdwp_util_LineTable* JNICALL Java_gnu_classpath_jdwp_VMMethod_getLineTable(JNIEnv *env, struct gnu_classpath_jdwp_VMMethod* this) 
130 {
131     jclass cl;
132     jmethodID m;
133     jobject ol;
134     jlongArray jlineCI;
135     jintArray jlineNum;
136     jint count = 0, i;
137     int *lineNum;
138     long *lineCI;
139     jvmtiLineNumberEntry *lne;
140     jlocation start,end;
141     
142     jvmtiError err;
143
144     if (JVMTI_ERROR_NONE!=(err= (*jvmtienv)->
145                                                    GetLineNumberTable(jvmtienv, 
146                                                                                           (jmethodID)(long)this->_methodId,
147                                                                                           &count, &lne))) {
148                 printjvmtierror("VMMethod.getlinetable GetLineNumberTable",err);
149         return NULL;
150     }
151
152     cl = (*env)->FindClass(env,"gnu.classpath.jdwp.util.LineTable");
153     if (!cl) return NULL;
154
155     m = (*env)->GetMethodID(env, cl, "<init>", "(JJ[I[J)V");
156     if (!m) return NULL;
157         
158     jlineNum = (*env)->NewIntArray(env, count);
159     if (!jlineNum) return NULL;
160     jlineCI = (*env)->NewLongArray(env, count);
161     if (!jlineCI) return NULL;
162     lineNum = (*env)->GetIntArrayElements(env, jlineNum, NULL);
163     lineCI = (*env)->GetLongArrayElements(env, jlineCI, NULL);
164     for (i = 0; i < count; ++i) {
165         lineNum[i] = lne[i].line_number;
166         lineCI[i] = lne[i].start_location;
167     }
168     (*env)->ReleaseLongArrayElements(env, jlineCI, lineCI, 0);
169     (*env)->ReleaseIntArrayElements(env, jlineNum, lineNum, 0);
170     (*jvmtienv)->Deallocate(jvmtienv, lne);
171
172     if (JVMTI_ERROR_NONE!=(err= (*jvmtienv)->
173                                                    GetMethodLocation(jvmtienv, 
174                                                                                          (jmethodID)(long)this->_methodId, 
175                                                                                          &start, &end))) {
176                 printjvmtierror("VMMethod.getlinetable GetMethodLocation",err);
177         return NULL;
178     }
179
180     ol = (*env)->NewObject(env, cl, m, start, 
181                            end, jlineNum, jlineCI);
182
183     return (struct gnu_classpath_jdwp_util_LineTable*)ol;
184  
185 }
186
187 static bool fillVariableTable(JNIEnv *env, jvmtiLocalVariableEntry* entries, 
188                                                           int count, jlongArray *jlineCI, 
189                                                           jobjectArray *names, jobjectArray *sigs, 
190                                                           jintArray *jlengths, jintArray *jslot) {
191         jint *lengths, *slot,i;
192         jclass cl;
193         jlong *lineCI;
194
195         *jlineCI = (*env)->NewLongArray(env, count);
196         if (!*jlineCI) return false;
197
198         cl=(*env)->FindClass(env,"java/lang/String");
199         if (!cl) return false;
200         
201         *names = (*env)->NewObjectArray(env, count, cl, NULL);
202         if (names) return false;
203         sigs = (*env)->NewObjectArray(env, count, cl, NULL);
204         if (sigs) return false;
205         
206         jlengths = (*env)->NewIntArray(env, count);
207         if (!lengths) return false;
208         
209         jslot = (*env)->NewIntArray(env, count);
210         if (!slot) return false;
211         
212         lineCI = (*env)->GetLongArrayElements(env, *jlineCI, NULL);
213         lengths = (*env)->GetIntArrayElements(env, *jlengths, NULL);
214         slot = (*env)->GetIntArrayElements(env, jslot, NULL);
215         
216         for (i=0; i<count; i++) {
217                 (*env)->
218                         SetObjectArrayElement(env, *names, i, 
219                                                                   (*env)->NewStringUTF(env,entries[i].name));
220                 (*env)->
221                         SetObjectArrayElement(env, *sigs, i, (*env)->NewStringUTF(
222                                                                           env,entries[i].signature));
223                 lineCI[i]=entries[i].start_location;
224                 lengths[i]=entries[i].length;
225                 slot[i]=entries[i].slot;
226         }
227     (*env)->ReleaseLongArrayElements(env, jlineCI, lineCI, 0);
228     (*env)->ReleaseIntArrayElements(env, jlengths, lengths, 0);
229     (*env)->ReleaseIntArrayElements(env, jslot, slot, 0);
230         return true;
231 }
232
233
234 /*
235  * Class:     gnu/classpath/jdwp/VMMethod
236  * Method:    getVariableTable
237  * Signature: ()Lgnu/classpath/jdwp/util/VariableTable;
238  */
239 JNIEXPORT struct gnu_classpath_jdwp_util_VariableTable* JNICALL Java_gnu_classpath_jdwp_VMMethod_getVariableTable(JNIEnv *env, struct gnu_classpath_jdwp_VMMethod* this)
240 {
241         jvmtiLocalVariableEntry* localvarentries;
242         jint entry_count, argCnt, slots; 
243         jclass cl;
244         jmethodID m, vmmethodid;
245     jobject o;
246         jobjectArray names, sigs;
247     jvmtiError err;
248     jlongArray jlineCI;
249         jintArray jlengths, jslot;
250
251         vmmethodid = (jmethodID)(long)this->_methodId;
252
253         err= (*jvmtienv)->GetLocalVariableTable(jvmtienv, 
254                                                                                         vmmethodid,
255                                                                                         &entry_count, 
256                                                                                         &localvarentries);
257     if (JVMTI_ERROR_NONE != err) { 
258                 if (err == JVMTI_ERROR_ABSENT_INFORMATION) {
259                         /* no local variable table available for this method. 
260                            return an empty local variable table */
261                         argCnt = slots = 0;
262                         names = sigs = jlineCI = jlengths = jslot = NULL;
263                 } else {
264                         printjvmtierror("VMMethod.getVariableTable GetLocalVariableTable",err);
265                         return NULL;
266                 }
267         } else {
268                 if (JVMTI_ERROR_NONE != (err= 
269                                                                  (*jvmtienv)->GetArgumentsSize(jvmtienv, 
270                                                                                                                            vmmethodid, 
271                                                                                                                            &argCnt))) {
272                         printjvmtierror("VMMethod.getVariableTable GetArgumentsSize",err);
273                         return NULL;
274                 }
275
276                 if (JVMTI_ERROR_NONE != (err= (*jvmtienv)->GetMaxLocals(jvmtienv, 
277                                                                                                                                 vmmethodid,
278                                                                                                                                 &slots))) {
279                         printjvmtierror("VMMethod.getVariableTable GetMaxLocals",err);
280                         return NULL;
281                 }
282                 
283                 slots = slots - argCnt;
284                 if (!fillVariableTable(env, localvarentries, entry_count, &jlineCI, 
285                                                            &names, &sigs, &jlengths, &jslot)) 
286                         return NULL;
287                 (*jvmtienv)->
288                         Deallocate(jvmtienv, (unsigned char*)localvarentries->signature);
289                 (*jvmtienv)->
290                         Deallocate(jvmtienv, (unsigned char*)localvarentries->name);
291                 if (localvarentries->generic_signature != NULL)
292                         (*jvmtienv)-> Deallocate(jvmtienv, (unsigned char*)
293                                                                          localvarentries->generic_signature);
294
295
296                 (*jvmtienv)->Deallocate(jvmtienv,(unsigned char*)localvarentries);
297         }
298         
299     cl = (*env)->FindClass(env,"gnu.classpath.jdwp.util.VariableTable");
300     if (!cl) return NULL;
301
302     m = (*env)->
303                 GetMethodID(env, cl,"<init>", 
304                                         "(II[J[Ljava/lang/String;[Ljava/lang/String;[I[I)V");
305     if (!m) return NULL;
306
307     o = (*env)->NewObject(env, cl, m, argCnt, slots, jlineCI, 
308                                                   names, sigs, jlengths, jslot);        
309
310     return (struct gnu_classpath_jdwp_util_VariableTable*) o;
311 }
312
313 /*
314  * These are local overrides for various environment variables in Emacs.
315  * Please do not remove this and leave it at the end of the file, where
316  * Emacs will automagically detect them.
317  * ---------------------------------------------------------------------
318  * Local variables:
319  * mode: c
320  * indent-tabs-mode: t
321  * c-basic-offset: 4
322  * tab-width: 4
323  * End:
324  */