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