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