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