major rework of jvmti. now we have three processes in jvmti mode. there are still...
[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: 
30
31
32 $Id: VMVirtualMachine.c 4661 2006-03-21 00:04:59Z 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/cacaodbg.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     (*remotedbgjvmtienv)->SuspendThread(remotedbgjvmtienv, (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     (*remotedbgjvmtienv)->ResumeThread(remotedbgjvmtienv, (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
90     (*remotedbgjvmtienv)->GetLoadedClasses(remotedbgjvmtienv, &count, &classes);
91     return count;
92 }
93
94 /*
95  * Class:     gnu_classpath_jdwp_VMVirtualMachine
96  * Method:    getAllLoadedClasses
97  * Signature: ()Ljava/util/Iterator
98  */
99 JNIEXPORT struct java_util_Iterator* JNICALL Java_gnu_classpath_jdwp_VMVirtualMachine_getAllLoadedClasses(JNIEnv *env, jclass clazz) {
100         jclass *classes, *cl;
101         jint classcount;
102         jobjectArray joa;
103 /*      jthrowable e;*/
104         jmethodID m;
105         jobject *ol,*oi;
106         int i;
107         jvmtiError err;
108         char* errdesc;
109
110         if (JVMTI_ERROR_NONE != (err= (*remotedbgjvmtienv)->
111                 GetLoadedClasses(remotedbgjvmtienv, &classcount, &classes))) {
112                 (*remotedbgjvmtienv)->GetErrorName(remotedbgjvmtienv,err, &errdesc);
113                 fprintf(stderr,"jvmti error: %s\n",errdesc);
114                 fflush(stderr);
115 /*              env->ThrowNew(env,ec,"jvmti error occoured");*/
116         }
117         
118         cl = (*env)->FindClass(env,"java.lang.Class");
119
120         /* Arrays.asList(Object[] classes)->List.Iterator()->Iterator */
121         joa = (*env)->NewObjectArray(env, (jsize)classcount, cl , NULL);
122
123         for (i = 0; i < classcount; i++) 
124                 (*env)->SetObjectArrayElement(env,joa,(jsize)i, (jobject)classes[i]);
125         
126         cl = (*env)->FindClass(env,"java.util.Arrays");
127         if (!cl) return NULL;
128
129         m = (*env)->GetStaticMethodID(env, cl, "asList", "([Ljava/lang/Object;)Ljava/util/List;");
130         if (!m) return NULL;
131
132         ol = (*env)->CallStaticObjectMethod(env,(jclass)cl,m,joa);
133         if (!ol) return NULL;
134
135         cl = (*env)->FindClass(env,"java.util.List");
136         if (!cl) return NULL;
137         m = (*env)->GetMethodID(env,cl,"Iterator","()Ljava/util/Iterator;");
138
139         oi = (*env)->CallObjectMethod(env,*ol,m);
140                 
141         return (struct java_util_Iterator*)oi;
142 }
143
144 /* Class:     gnu/classpath/jdwp/VMVirtualMachine
145  * Method:    getClassStatus
146  * Signature: (Ljava/lang/Class;)I
147  */
148 JNIEXPORT s4 JNICALL Java_gnu_classpath_jdwp_VMVirtualMachine_getClassStatus(JNIEnv *env, jclass clazz, struct java_lang_Class* par1) {
149         jint status;
150         (*remotedbgjvmtienv)->GetClassStatus(remotedbgjvmtienv, (jclass) par1, &status);
151         return status;
152 }
153
154 /*
155  * Class:     gnu/classpath/jdwp/VMVirtualMachine
156  * Method:    getAllClassMethods
157  * Signature: (Ljava/lang/Class;)[Lgnu/classpath/jdwp/VMMethod;
158  */
159 JNIEXPORT java_objectarray* JNICALL Java_gnu_classpath_jdwp_VMVirtualMachine_getAllClassMethods(JNIEnv *env, jclass clazz, struct java_lang_Class* par1) {
160     log_text ("VMVirtualMachine_getAllClassMethods: IMPLEMENT ME !!!");
161 }
162
163
164 /*
165  * Class:     gnu/classpath/jdwp/VMVirtualMachine
166  * Method:    getClassMethod
167  * Signature: (Ljava/lang/Class;J)Lgnu/classpath/jdwp/VMMethod;
168  */
169 JNIEXPORT struct gnu_classpath_jdwp_VMMethod* JNICALL Java_gnu_classpath_jdwp_VMVirtualMachine_getClassMethod(JNIEnv *env, jclass clazz, struct java_lang_Class* par1, s8 par2) {
170     log_text ("VMVirtualMachine_getAllClassMethod: IMPLEMENT ME !!!");
171 }
172
173
174 /*
175  * Class:     gnu/classpath/jdwp/VMVirtualMachine
176  * Method:    getFrames
177  * Signature: (Ljava/lang/Thread;II)Ljava/util/ArrayList;
178  */
179 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) {
180     log_text ("VMVirtualMachine_getFrames - IMPLEMENT ME!!!");
181 /*      jclass ec = (*env)->FindClass(env,"gnu/classpath/jdwp/JdwpInternalErrorException");
182         if (JVMTI_ERROR_NONE != (*remotedbgjvmtienv)->GetClassStatus(remotedbgjvmtienv, par1, &status))
183         env->ThrowNew(env,ec,"jvmti error occoured");*/
184         return 0;
185 }
186
187
188 /*
189  * Class:     gnu/classpath/jdwp/VMVirtualMachine
190  * Method:    getFrame
191  * Signature: (Ljava/lang/Thread;Ljava/nio/ByteBuffer;)Lgnu/classpath/jdwp/VMFrame;
192  */
193 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) {
194     log_text ("VMVirtualMachine_getFrame - IMPLEMENT ME!!!");
195         return 0;
196 }
197
198
199 /*
200  * Class:     gnu/classpath/jdwp/VMVirtualMachine
201  * Method:    getFrameCount
202  * Signature: (Ljava/lang/Thread;)I
203  */
204 JNIEXPORT s4 JNICALL Java_gnu_classpath_jdwp_VMVirtualMachine_getFrameCount(JNIEnv *env, jclass clazz, struct java_lang_Thread* par1) {
205         jint count;
206         (*remotedbgjvmtienv)->GetFrameCount(remotedbgjvmtienv, (jthread)par1, &count);
207         return count;
208 }
209
210
211 /*
212  * Class:     gnu/classpath/jdwp/VMVirtualMachine
213  * Method:    getThreadStatus
214  * Signature: (Ljava/lang/Thread;)I
215  */
216 JNIEXPORT s4 JNICALL Java_gnu_classpath_jdwp_VMVirtualMachine_getThreadStatus(JNIEnv *env, jclass clazz, struct java_lang_Thread* par1) {
217         jint status;
218         if (JVMTI_ERROR_NONE != (*remotedbgjvmtienv)->GetThreadState(remotedbgjvmtienv, (jthread)par1, &status))
219                 return 0;
220         if (status && JVMTI_THREAD_STATE_ALIVE) {
221                 if (status && JVMTI_THREAD_STATE_WAITING) {             
222                         return 4; /* WAIT - see JdwpConstants */
223                 }
224                 if (status && JVMTI_THREAD_STATE_BLOCKED_ON_MONITOR_ENTER) { 
225                         return 3; /* MONITOR - see JdwpConstants */
226                 }
227                 if (status && JVMTI_THREAD_STATE_SLEEPING) { 
228                         return 2; /* SLEEPING - see JdwpConstants */
229                 }
230                 return 1; /* RUNNING - see JdwpConstants */
231         } else 
232                 return 0; /* ZOMBIE - see JdwpConstants */
233         return -1; /* some error */
234 }
235
236
237 /*
238  * Class:     gnu/classpath/jdwp/VMVirtualMachine
239  * Method:    getLoadRequests
240  * Signature: (Ljava/lang/ClassLoader;)Ljava/util/ArrayList;
241  */
242 JNIEXPORT struct java_util_ArrayList* JNICALL Java_gnu_classpath_jdwp_VMVirtualMachine_getLoadRequests(JNIEnv *env, jclass clazz, struct java_lang_ClassLoader* par1) {
243     log_text ("VMVirtualMachine_getLoadRequests(");
244         return 0;
245 }
246
247
248 /*
249  * Class:     gnu/classpath/jdwp/VMVirtualMachine
250  * Method:    executeMethod
251  * Signature: (Ljava/lang/Object;Ljava/lang/Thread;Ljava/lang/Class;Ljava/lang/reflect/Method;[Ljava/lang/Object;Z)Lgnu/classpath/jdwp/util/MethodResult;
252  */
253 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) {
254     log_text ("VMVirtualMachine_executeMethod");
255         return 0;
256 }
257
258
259 /*
260  * Class:     gnu/classpath/jdwp/VMVirtualMachine
261  * Method:    getSourceFile
262  * Signature: (Ljava/lang/Class;)Ljava/lang/String;
263  */
264 JNIEXPORT struct java_lang_String* JNICALL Java_gnu_classpath_jdwp_VMVirtualMachine_getSourceFile(JNIEnv *env, jclass clazz, struct java_lang_Class* par1) {
265         char* srcname;
266         jstring str;
267
268     (*remotedbgjvmtienv)->
269                 GetSourceFileName(remotedbgjvmtienv, (jclass)par1, &srcname);
270         str = (*env)->NewString(env,(jchar*)srcname,(jsize)strlen(srcname));
271
272         return (struct java_lang_String*)str;
273 }
274
275 /* match JdwpConstants.EventKind to jvmtiEvent constants */
276 static jvmtiEvent EventKind2jvmtiEvent(jbyte kind){
277         switch (kind) {
278         case /* SINGLE_STEP */ 1: return JVMTI_EVENT_SINGLE_STEP;
279         case /* BREAKPOINT */ 2: return JVMTI_EVENT_BREAKPOINT;
280     case /*  FRAME_POP */ 3: return JVMTI_EVENT_FRAME_POP;
281     case /*  EXCEPTION */ 4: return JVMTI_EVENT_EXCEPTION;
282     case /*  USER_DEFINED */ 5: return -1; /* can this be matched ? */
283     case /*  THREAD_START */ 6: return JVMTI_EVENT_THREAD_START;
284     case /*  THREAD_END */ 7: return JVMTI_EVENT_THREAD_END;
285     case /*  CLASS_PREPARE */ 8: return JVMTI_EVENT_CLASS_PREPARE;
286     case /*  CLASS_UNLOAD */ 9: return -1; /* can this be matched ? */
287     case /*  CLASS_LOAD */ 10: return JVMTI_EVENT_CLASS_LOAD;
288     case /*  FIELD_ACCESS */ 20: return JVMTI_EVENT_FIELD_ACCESS;
289     case /*  FIELD_MODIFICATION */ 21: return JVMTI_EVENT_FIELD_MODIFICATION;
290     case /*  EXCEPTION_CATCH */ 30: return JVMTI_EVENT_EXCEPTION_CATCH;
291     case /*  METHOD_ENTRY */ 40: return JVMTI_EVENT_METHOD_ENTRY;
292     case /*  METHOD_EXIT */ 41: return JVMTI_EVENT_METHOD_EXIT;
293     case /*  VM_INIT */ 90: return JVMTI_EVENT_VM_INIT;
294     case /*  VM_DEATH */ 99: return JVMTI_EVENT_VM_DEATH;    
295     case /*  VM_DISCONNECTED */ 100: return -1; /* can this be matched ? */
296         default: return -1;
297         }
298 }
299
300 /*
301  * Class:     gnu/classpath/jdwp/VMVirtualMachine
302  * Method:    registerEvent
303  * Signature: (Lgnu/classpath/jdwp/event/EventRequest;)V
304  */
305 JNIEXPORT void JNICALL Java_gnu_classpath_jdwp_VMVirtualMachine_registerEvent(JNIEnv *env, jclass clazz, struct gnu_classpath_jdwp_event_EventRequest* par1) {
306         jbyte kind;
307         jfieldID kindid;
308         jclass erc;
309
310         erc = (*env)->FindClass(env,"gnu.classpath.jdwp.event.EventRequest");
311         
312         kindid = (*env)->GetFieldID(env, erc, "_kind", "B");
313         kind = (*env)->GetByteField(env, (jobject)par1, kindid);
314
315         (*remotedbgjvmtienv)->
316                 SetEventNotificationMode(remotedbgjvmtienv, JVMTI_ENABLE, 
317                                                                  EventKind2jvmtiEvent(kind), NULL);
318
319         /* todo: error handling, suspend policy */
320 }
321
322
323 /*
324  * Class:     gnu/classpath/jdwp/VMVirtualMachine
325  * Method:    unregisterEvent
326  * Signature: (Lgnu/classpath/jdwp/event/EventRequest;)V
327  */
328 JNIEXPORT void JNICALL Java_gnu_classpath_jdwp_VMVirtualMachine_unregisterEvent(JNIEnv *env, jclass clazz, struct gnu_classpath_jdwp_event_EventRequest* par1) {
329         jbyte kind;
330         jfieldID kindid;
331         jclass erc;
332
333         erc = (*env)->FindClass(env,"gnu.classpath.jdwp.event.EventRequest");
334         
335         kindid = (*env)->GetFieldID(env, erc, "_kind", "B");
336         kind = (*env)->GetByteField(env, (jobject)par1, kindid);
337
338         (*remotedbgjvmtienv)->
339                 SetEventNotificationMode(remotedbgjvmtienv, JVMTI_DISABLE, 
340                                                                  EventKind2jvmtiEvent(kind), NULL);
341
342         /* todo: error handling, suspend policy */
343 }
344
345
346 /*
347  * Class:     gnu/classpath/jdwp/VMVirtualMachine
348  * Method:    clearEvents
349  * Signature: (B)V
350  */
351 JNIEXPORT void JNICALL Java_gnu_classpath_jdwp_VMVirtualMachine_clearEvents(JNIEnv *env, jclass clazz, s4 par1) {
352         /* jvmti events are not saved */
353     log_text ("VMVirtualMachine_clearEvents IMPLEMENT ME!!!");
354 }
355
356
357 /*
358  * These are local overrides for various environment variables in Emacs.
359  * Please do not remove this and leave it at the end of the file, where
360  * Emacs will automagically detect them.
361  * ---------------------------------------------------------------------
362  * Local variables:
363  * mode: c
364  * indent-tabs-mode: t
365  * c-basic-offset: 4
366  * tab-width: 4
367  * End:
368  */