src/native/jni.c: removed jvmti.h included cacaodbg.h for GetEnv - jvmti
[cacao.git] / src / native / vm / VMVirtualMachine.c
1 /* src/native/vm/VMVirtualMachine.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: Martin Platter
28
29 Changes: Samuel Vinson
30
31
32 $Id: VMVirtualMachine.c 4969 2006-05-29 09:41:02Z motse $
33
34 */
35
36 #include "toolbox/logging.h"
37 #include "native/jni.h"
38 #include "native/include/java_lang_Thread.h"
39 #include "native/include/java_nio_ByteBuffer.h"
40 #include "native/include/java_lang_Class.h"
41 #include "native/include/java_lang_ClassLoader.h"
42 #include "native/include/java_lang_reflect_Method.h"
43 #include "native/include/gnu_classpath_jdwp_event_EventRequest.h"
44 #include "native/include/gnu_classpath_jdwp_VMVirtualMachine.h"
45 #include "native/jvmti/jvmti.h"
46 #include "native/jvmti/VMjdwp.h"
47 #include <string.h>
48
49
50 /*
51  * Class:     gnu_classpath_jdwp_VMVirtualMachine
52  * Method:    suspendThread
53  * Signature: (Ljava/lang/Thread;)V
54  */
55 JNIEXPORT void JNICALL Java_gnu_classpath_jdwp_VMVirtualMachine_suspendThread(JNIEnv *env, jclass clazz, struct java_lang_Thread* par1)
56 {
57     (*jvmtienv)->SuspendThread(jvmtienv, (jthread) par1);
58 }
59
60 /*
61  * Class:     gnu_classpath_jdwp_VMVirtualMachine
62  * Method:    resumeThread
63  * Signature: (Ljava/lang/Thread;)V
64  */
65 JNIEXPORT void JNICALL Java_gnu_classpath_jdwp_VMVirtualMachine_resumeThread(JNIEnv *env, jclass clazz, struct java_lang_Thread* par1)
66 {
67     (*jvmtienv)->ResumeThread(jvmtienv, (jthread) par1);
68 }
69
70
71 /*
72  * Class:     gnu_classpath_jdwp_VMVirtualMachine
73  * Method:    getSuspendCount
74  * Signature: (Ljava/lang/Thread;)I
75  */
76 JNIEXPORT s4 JNICALL Java_gnu_classpath_jdwp_VMVirtualMachine_getSuspendCount(JNIEnv *env, jclass clazz, struct java_lang_Thread* par1) {
77     log_text ("VMVirtualMachine_getSuspendCount: not supported");
78         return 1;
79 }
80
81 /*
82  * Class:     gnu_classpath_jdwp_VMVirtualMachine
83  * Method:    getAllLoadedClassesCount
84  * Signature: ()I
85  */
86 JNIEXPORT s4 JNICALL Java_gnu_classpath_jdwp_VMVirtualMachine_getAllLoadedClassesCount(JNIEnv *env, jclass clazz) {
87     jint count;
88     jclass* classes;
89         jvmtiError err;
90         char* errdesc;
91
92         if (JVMTI_ERROR_NONE != (err= (*jvmtienv)->
93                 GetLoadedClasses(jvmtienv, &count, &classes))) {
94                 (*jvmtienv)->GetErrorName(jvmtienv,err, &errdesc);
95                 fprintf(stderr,"jvmti error: %s\n",errdesc);
96                 (*jvmtienv)->Deallocate(jvmtienv,(unsigned char*)errdesc);
97                 fflush(stderr);
98                 return 0;
99         }
100         (*jvmtienv)->Deallocate(jvmtienv,(unsigned char*)classes);
101     return count;
102 }
103
104 /*
105  * Class:     gnu_classpath_jdwp_VMVirtualMachine
106  * Method:    getAllLoadedClasses
107  * Signature: ()Ljava/util/Iterator
108  */
109 JNIEXPORT struct java_util_Iterator* JNICALL Java_gnu_classpath_jdwp_VMVirtualMachine_getAllLoadedClasses(JNIEnv *env, jclass clazz) {
110         jclass *classes, *cl;
111         jint classcount;
112         jobjectArray joa;
113 /*      jthrowable e;*/
114         jmethodID m;
115         jobject *ol,*oi;
116         int i;
117         jvmtiError err;
118         char* errdesc;
119
120         if (JVMTI_ERROR_NONE != (err= (*jvmtienv)->
121                 GetLoadedClasses(jvmtienv, &classcount, &classes))) {
122                 (*jvmtienv)->GetErrorName(jvmtienv,err, &errdesc);
123                 fprintf(stderr,"jvmti error: %s\n",errdesc);
124                 fflush(stderr);
125                 
126                 /* we should throw JDWP Exception INTERNAL = 113;*/
127 /*              env->ThrowNew(env,ec,"jvmti error occoured");  */
128                 return NULL;
129         }
130         
131         cl = (*env)->FindClass(env,"java.lang.Class");
132         if (!cl) return NULL;
133
134         /* Arrays.asList(Object[] classes)->List.Iterator()->Iterator */
135         joa = (*env)->NewObjectArray(env, (jsize)classcount, cl , NULL);
136         if (!joa) return NULL;
137
138         for (i = 0; i < classcount; i++) 
139                 (*env)->SetObjectArrayElement(env,joa,(jsize)i, (jobject)classes[i]);
140         (*jvmtienv)->Deallocate(jvmtienv, (unsigned char*)classes);
141         
142         cl = (*env)->FindClass(env,"java.util.Arrays");
143         if (!cl) return NULL;
144
145         m = (*env)->GetStaticMethodID(env, cl, "asList", "([Ljava/lang/Object;)Ljava/util/List;");
146         if (!m) return NULL;
147
148         ol = (*env)->CallStaticObjectMethod(env,(jclass)cl,m,joa);
149         if (!ol) return NULL;
150
151         cl = (*env)->FindClass(env,"java.util.List");
152         if (!cl) return NULL;
153         m = (*env)->GetMethodID(env,cl,"iterator","()Ljava/util/Iterator;");
154         if (!m) return NULL;
155         oi = (*env)->CallObjectMethod(env,ol,m);
156                 
157         return (struct java_util_Iterator*)oi;
158 }
159
160 /* Class:     gnu/classpath/jdwp/VMVirtualMachine
161  * Method:    getClassStatus
162  * Signature: (Ljava/lang/Class;)I
163  */
164 JNIEXPORT s4 JNICALL Java_gnu_classpath_jdwp_VMVirtualMachine_getClassStatus(JNIEnv *env, jclass clazz, struct java_lang_Class* par1) {
165         jint status;
166         (*jvmtienv)->GetClassStatus(jvmtienv, (jclass) par1, &status);
167         return status;
168 }
169
170 /*
171  * Class:     gnu/classpath/jdwp/VMVirtualMachine
172  * Method:    getAllClassMethods
173  * Signature: (Ljava/lang/Class;)[Lgnu/classpath/jdwp/VMMethod;
174  */
175 JNIEXPORT java_objectarray* JNICALL Java_gnu_classpath_jdwp_VMVirtualMachine_getAllClassMethods(JNIEnv *env, jclass clazz, struct java_lang_Class* par1) {
176     jint count;
177     jmethodID* methodID, m;
178         jvmtiError err;
179         char* errdesc;
180         
181         jclass *cl;
182         jobject *ol;
183         jobjectArray joa;
184         int i;
185
186     if (JVMTI_ERROR_NONE != (err= (*jvmtienv)->
187                                                          GetClassMethods(jvmtienv, (jclass) par1, 
188                                                                                          &count, &methodID))) {
189                 (*jvmtienv)->GetErrorName(jvmtienv,err, &errdesc);
190                 fprintf(stderr,"jvmti error: %s\n",errdesc);
191                 (*jvmtienv)->Deallocate(jvmtienv, (unsigned char *)errdesc);
192                 fflush(stderr);
193                 return NULL;
194         }
195         
196         m = (*env)->
197                 GetStaticMethodID(env, clazz, "getClassMethod", 
198                                                   "(Ljava/lang/Class;J)Lgnu/classpath/jdwp/VMMethod;");
199         if (!m) return NULL;
200    
201     cl = (*env)->FindClass(env,"gnu.classpath.jdwp.VMMethod");
202         if (!cl) return NULL;
203         
204         joa = (*env)->NewObjectArray(env, (jsize)count, cl , NULL);
205         if (!joa) return NULL;
206         fprintf(stderr, "VMVirtualMachine_getAllClassMethods 3\n");
207     for (i = 0; i < count; i++) {
208         ol = (*env)->
209                         CallStaticObjectMethod(env,clazz,m,(jobject)par1, methodID[i]);
210                 if (!ol) return NULL;
211         (*env)->SetObjectArrayElement(env,joa,(jsize)i, ol);
212     }
213         return joa;
214 }
215
216
217 /*
218  * Class:     gnu/classpath/jdwp/VMVirtualMachine
219  * Method:    getClassMethod
220  * Signature: (Ljava/lang/Class;J)Lgnu/classpath/jdwp/VMMethod;
221  */
222 JNIEXPORT struct gnu_classpath_jdwp_VMMethod* JNICALL Java_gnu_classpath_jdwp_VMVirtualMachine_getClassMethod(JNIEnv *env, jclass clazz, struct java_lang_Class* par1, s8 par2) {
223         jclass *cl;
224     jmethodID m;
225     jobject *ol;
226         
227     cl = (*env)->FindClass(env,"gnu.classpath.jdwp.VMMethod");
228         if (!cl) return NULL;
229         
230         m = (*env)->GetMethodID(env, cl, "<init>", "(Ljava/lang/Class;J)V");
231         if (!m) return NULL;
232         
233     ol = (*env)->NewObject(env, cl, m, par1, par2);
234         
235         return (struct gnu_classpath_jdwp_VMMethod*)ol;
236 }
237
238
239 /*
240  * Class:     gnu/classpath/jdwp/VMVirtualMachine
241  * Method:    getFrames
242  * Signature: (Ljava/lang/Thread;II)Ljava/util/ArrayList;
243  */
244 JNIEXPORT struct java_util_ArrayList* JNICALL Java_gnu_classpath_jdwp_VMVirtualMachine_getFrames(JNIEnv *env, jclass clazz, struct java_lang_Thread* par1, s4 par2, s4 par3) {
245     log_text ("VMVirtualMachine_getFrames - IMPLEMENT ME!!!");
246 /*      jclass ec = (*env)->FindClass(env,"gnu/classpath/jdwp/JdwpInternalErrorException");
247         if (JVMTI_ERROR_NONE != (*jvmtienv)->GetClassStatus(jvmtienv, par1, &status))
248         env->ThrowNew(env,ec,"jvmti error occoured");*/
249         return 0;
250 }
251
252
253 /*
254  * Class:     gnu/classpath/jdwp/VMVirtualMachine
255  * Method:    getFrame
256  * Signature: (Ljava/lang/Thread;Ljava/nio/ByteBuffer;)Lgnu/classpath/jdwp/VMFrame;
257  */
258 JNIEXPORT struct gnu_classpath_jdwp_VMFrame* JNICALL Java_gnu_classpath_jdwp_VMVirtualMachine_getFrame(JNIEnv *env, jclass clazz, struct java_lang_Thread* par1, struct java_nio_ByteBuffer* par2) {
259     log_text ("VMVirtualMachine_getFrame - IMPLEMENT ME!!!");
260         return 0;
261 }
262
263
264 /*
265  * Class:     gnu/classpath/jdwp/VMVirtualMachine
266  * Method:    getFrameCount
267  * Signature: (Ljava/lang/Thread;)I
268  */
269 JNIEXPORT s4 JNICALL Java_gnu_classpath_jdwp_VMVirtualMachine_getFrameCount(JNIEnv *env, jclass clazz, struct java_lang_Thread* par1) {
270         jint count;
271         (*jvmtienv)->GetFrameCount(jvmtienv, (jthread)par1, &count);
272         return count;
273 }
274
275
276 /*
277  * Class:     gnu/classpath/jdwp/VMVirtualMachine
278  * Method:    getThreadStatus
279  * Signature: (Ljava/lang/Thread;)I
280  */
281 JNIEXPORT s4 JNICALL Java_gnu_classpath_jdwp_VMVirtualMachine_getThreadStatus(JNIEnv *env, jclass clazz, struct java_lang_Thread* par1) {
282         jint status;
283         if (JVMTI_ERROR_NONE != (*jvmtienv)->GetThreadState(jvmtienv, (jthread)par1, &status))
284                 return 0;
285         if (status && JVMTI_THREAD_STATE_ALIVE) {
286                 if (status && JVMTI_THREAD_STATE_WAITING) {             
287                         return 4; /* WAIT - see JdwpConstants */
288                 }
289                 if (status && JVMTI_THREAD_STATE_BLOCKED_ON_MONITOR_ENTER) { 
290                         return 3; /* MONITOR - see JdwpConstants */
291                 }
292                 if (status && JVMTI_THREAD_STATE_SLEEPING) { 
293                         return 2; /* SLEEPING - see JdwpConstants */
294                 }
295                 return 1; /* RUNNING - see JdwpConstants */
296         } else 
297                 return 0; /* ZOMBIE - see JdwpConstants */
298         return -1; /* some error */
299 }
300
301
302 /*
303  * Class:     gnu/classpath/jdwp/VMVirtualMachine
304  * Method:    getLoadRequests
305  * Signature: (Ljava/lang/ClassLoader;)Ljava/util/ArrayList;
306  */
307 JNIEXPORT struct java_util_ArrayList* JNICALL Java_gnu_classpath_jdwp_VMVirtualMachine_getLoadRequests(JNIEnv *env, jclass clazz, struct java_lang_ClassLoader* par1) {
308     log_text ("VMVirtualMachine_getLoadRequests(");
309         return 0;
310 }
311
312
313 /*
314  * Class:     gnu/classpath/jdwp/VMVirtualMachine
315  * Method:    executeMethod
316  * Signature: (Ljava/lang/Object;Ljava/lang/Thread;Ljava/lang/Class;Ljava/lang/reflect/Method;[Ljava/lang/Object;Z)Lgnu/classpath/jdwp/util/MethodResult;
317  */
318 JNIEXPORT struct gnu_classpath_jdwp_util_MethodResult* JNICALL Java_gnu_classpath_jdwp_VMVirtualMachine_executeMethod(JNIEnv *env, jclass clazz, struct java_lang_Object* par1, struct java_lang_Thread* par2, struct java_lang_Class* par3, struct java_lang_reflect_Method* par4, java_objectarray* par5, s4 par6) {
319     log_text ("VMVirtualMachine_executeMethod");
320         return 0;
321 }
322
323
324 /*
325  * Class:     gnu/classpath/jdwp/VMVirtualMachine
326  * Method:    getSourceFile
327  * Signature: (Ljava/lang/Class;)Ljava/lang/String;
328  */
329 JNIEXPORT struct java_lang_String* JNICALL Java_gnu_classpath_jdwp_VMVirtualMachine_getSourceFile(JNIEnv *env, jclass clazz, struct java_lang_Class* par1) {
330         char* srcname;
331         jstring str;
332
333     (*jvmtienv)->
334                 GetSourceFileName(jvmtienv, (jclass)par1, &srcname);
335         str = (*env)->NewString(env,(jchar*)srcname,(jsize)strlen(srcname));
336
337         return (struct java_lang_String*)str;
338 }
339
340 /* match JdwpConstants.EventKind to jvmtiEvent constants */
341 static jvmtiEvent EventKind2jvmtiEvent(jbyte kind){
342         switch (kind) {
343         case /* SINGLE_STEP */ 1: return JVMTI_EVENT_SINGLE_STEP;
344         case /* BREAKPOINT */ 2: return JVMTI_EVENT_BREAKPOINT;
345     case /*  FRAME_POP */ 3: return JVMTI_EVENT_FRAME_POP;
346     case /*  EXCEPTION */ 4: return JVMTI_EVENT_EXCEPTION;
347     case /*  USER_DEFINED */ 5: return -1; /* can this be matched ? */
348     case /*  THREAD_START */ 6: return JVMTI_EVENT_THREAD_START;
349     case /*  THREAD_END */ 7: return JVMTI_EVENT_THREAD_END;
350     case /*  CLASS_PREPARE */ 8: return JVMTI_EVENT_CLASS_PREPARE;
351     case /*  CLASS_UNLOAD */ 9: return -1; /* can this be matched ? */
352     case /*  CLASS_LOAD */ 10: return JVMTI_EVENT_CLASS_LOAD;
353     case /*  FIELD_ACCESS */ 20: return JVMTI_EVENT_FIELD_ACCESS;
354     case /*  FIELD_MODIFICATION */ 21: return JVMTI_EVENT_FIELD_MODIFICATION;
355     case /*  EXCEPTION_CATCH */ 30: return JVMTI_EVENT_EXCEPTION_CATCH;
356     case /*  METHOD_ENTRY */ 40: return JVMTI_EVENT_METHOD_ENTRY;
357     case /*  METHOD_EXIT */ 41: return JVMTI_EVENT_METHOD_EXIT;
358     case /*  VM_INIT */ 90: return JVMTI_EVENT_VM_INIT;
359     case /*  VM_DEATH */ 99: return JVMTI_EVENT_VM_DEATH;    
360     case /*  VM_DISCONNECTED */ 100: return -1; /* can this be matched ? */
361         default: return -1;
362         }
363 }
364
365 /*
366  * Class:     gnu/classpath/jdwp/VMVirtualMachine
367  * Method:    registerEvent
368  * Signature: (Lgnu/classpath/jdwp/event/EventRequest;)V
369  */
370 JNIEXPORT void JNICALL Java_gnu_classpath_jdwp_VMVirtualMachine_registerEvent(JNIEnv *env, jclass clazz, struct gnu_classpath_jdwp_event_EventRequest* par1) {
371         jbyte kind;
372         jfieldID kindid;
373         jclass erc;
374
375         erc = (*env)->FindClass(env,"gnu.classpath.jdwp.event.EventRequest");
376         
377         kindid = (*env)->GetFieldID(env, erc, "_kind", "B");
378         kind = (*env)->GetByteField(env, (jobject)par1, kindid);
379
380         (*jvmtienv)->
381                 SetEventNotificationMode(jvmtienv, JVMTI_ENABLE, 
382                                                                  EventKind2jvmtiEvent(kind), NULL);
383
384         /* todo: error handling, suspend policy */
385 }
386
387
388 /*
389  * Class:     gnu/classpath/jdwp/VMVirtualMachine
390  * Method:    unregisterEvent
391  * Signature: (Lgnu/classpath/jdwp/event/EventRequest;)V
392  */
393 JNIEXPORT void JNICALL Java_gnu_classpath_jdwp_VMVirtualMachine_unregisterEvent(JNIEnv *env, jclass clazz, struct gnu_classpath_jdwp_event_EventRequest* par1) {
394         jbyte kind;
395         jfieldID kindid;
396         jclass erc;
397
398         erc = (*env)->FindClass(env,"gnu.classpath.jdwp.event.EventRequest");
399         
400         kindid = (*env)->GetFieldID(env, erc, "_kind", "B");
401         kind = (*env)->GetByteField(env, (jobject)par1, kindid);
402
403         (*jvmtienv)->
404                 SetEventNotificationMode(jvmtienv, JVMTI_DISABLE, 
405                                                                  EventKind2jvmtiEvent(kind), NULL);
406
407         /* todo: error handling, suspend policy */
408 }
409
410
411 /*
412  * Class:     gnu/classpath/jdwp/VMVirtualMachine
413  * Method:    clearEvents
414  * Signature: (B)V
415  */
416 JNIEXPORT void JNICALL Java_gnu_classpath_jdwp_VMVirtualMachine_clearEvents(JNIEnv *env, jclass clazz, s4 par1) {
417         /* jvmti events are not saved */
418     log_text ("VMVirtualMachine_clearEvents IMPLEMENT ME!!!");
419 }
420
421
422 /*
423  * These are local overrides for various environment variables in Emacs.
424  * Please do not remove this and leave it at the end of the file, where
425  * Emacs will automagically detect them.
426  * ---------------------------------------------------------------------
427  * Local variables:
428  * mode: c
429  * indent-tabs-mode: t
430  * c-basic-offset: 4
431  * tab-width: 4
432  * End:
433  */