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