a few finalizer testcases, old thread implementation uses now VMThread, no mor contex...
[cacao.git] / src / native / vm / VMClass.c
1 /* nat/VMClass.c - java/lang/Class
2
3    Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003
4    R. Grafl, A. Krall, C. Kruegel, C. Oates, R. Obermaisser,
5    M. Probst, S. Ring, E. Steiner, C. Thalinger, D. Thuernbeck,
6    P. Tomsich, J. Wenninger
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., 59 Temple Place - Suite 330, Boston, MA
23    02111-1307, USA.
24
25    Contact: cacao@complang.tuwien.ac.at
26
27    Authors: Roman Obermaiser
28
29    Changes: Joseph Wenninger
30
31    $Id: VMClass.c 1173 2004-06-16 14:56:18Z jowenn $
32
33 */
34
35
36 #include <string.h>
37 #include "jni.h"
38 #include "types.h"
39 #include "global.h"
40 #include "builtin.h"
41 #include "loader.h"
42 #include "native.h"
43 #include "tables.h"
44 #include "toolbox/logging.h"
45 #include "toolbox/memory.h"
46 #include "java_lang_Object.h"
47 #include "java_lang_Class.h"
48 #include "java_lang_ClassLoader.h"
49 #include "java_security_ProtectionDomain.h"
50 #include "java_lang_reflect_Constructor.h"
51 #include "java_lang_reflect_Field.h"
52 #include "java_lang_reflect_Method.h"
53 #include "java_lang_Throwable.h"    /* needed for java_lang_VMClass.h */
54 #include "java_lang_VMClass.h"
55
56
57 /* for selecting public members */
58 #define MEMBER_PUBLIC  0
59
60
61 /*
62  * Class:     java_lang_VMClass
63  * Method:    forName
64  * Signature: (Ljava/lang/String;)Ljava/lang/Class;
65  */
66 JNIEXPORT java_lang_Class* JNICALL Java_java_lang_VMClass_forName(JNIEnv *env, jclass clazz, java_lang_String *s)
67 {
68         classinfo *c;
69         utf *u;
70
71         /* illegal argument */
72         if (!s)
73                 return NULL;
74         
75         /* create utf string in which '.' is replaced by '/' */
76         u = javastring_toutf(s, true);
77
78         /* create a new class, ... */
79         c = class_new(u);
80
81         /* load, ... */
82         class_load(c);
83
84         /* class was not loaded. raise exception */
85         if (!c->loaded) {
86                 /* there is already an exception (NoClassDefFoundError), but forName()
87                    returns a ClassNotFoundException */
88
89                 /* clear exceptionptr, because builtin_new checks for 
90                    ExceptionInInitializerError */
91                 *exceptionptr = NULL;
92
93                 *exceptionptr =
94                         new_exception_javastring(string_java_lang_ClassNotFoundException, s);
95
96             return NULL;
97         }
98
99         /* link, ... */
100         class_link(c);
101
102         /* ...and initialize it */
103         class_init(c);
104
105         use_class_as_object(c);
106
107         return (java_lang_Class *) c;
108 }
109
110
111 /*
112  * Class:     java_lang_VMClass
113  * Method:    getClassLoader
114  * Signature: ()Ljava/lang/ClassLoader;
115  */
116 JNIEXPORT java_lang_ClassLoader* JNICALL Java_java_lang_VMClass_getClassLoader(JNIEnv *env, jclass clazz, java_lang_Class *that)
117 {  
118         return ((classinfo*)that)->classloader;
119 /*      init_systemclassloader();
120
121         return SystemClassLoader;*/
122 }
123
124
125 /*
126  * Class:     java_lang_VMClass
127  * Method:    getComponentType
128  * Signature: ()Ljava/lang/Class;
129  */
130 JNIEXPORT java_lang_Class* JNICALL Java_java_lang_VMClass_getComponentType(JNIEnv *env, jclass clazz,java_lang_Class *that)
131 {
132     classinfo *thisclass = (classinfo *) that;
133     classinfo *c = NULL;
134     arraydescriptor *desc;
135     
136     if ((desc = thisclass->vftbl->arraydesc) != NULL) {
137         if (desc->arraytype == ARRAYTYPE_OBJECT)
138             c = desc->componentvftbl->class;
139         else
140             c = primitivetype_table[desc->arraytype].class_primitive;
141         
142         /* set vftbl */
143                 use_class_as_object(c);
144     }
145     
146     return (java_lang_Class *) c;
147 }
148
149
150 /*
151  * Class:     java_lang_VMClass
152  * Method:    getDeclaredConstructors
153  * Signature: (Z)[Ljava/lang/reflect/Constructor;
154  */
155 JNIEXPORT java_objectarray* JNICALL Java_java_lang_VMClass_getDeclaredConstructors(JNIEnv *env, jclass clazz,
156         struct java_lang_Class *that, s4 public_only)
157 {
158   
159     classinfo *c = (classinfo *) that;
160     java_objectheader *o;
161     classinfo *class_constructor;
162     java_objectarray *array_constructor;     /* result: array of Method-objects */
163     java_objectarray *exceptiontypes;   /* the exceptions thrown by the method */
164     methodinfo *m;                      /* the current method to be represented */    
165     int public_methods = 0;             /* number of public methods of the class */
166     int pos = 0;
167     int i;
168     utf *utf_constr = utf_new_char("<init>");
169
170     /* determine number of constructors */
171     for (i = 0; i < c->methodscount; i++) 
172                 if (((c->methods[i].flags & ACC_PUBLIC) || !public_only) && 
173                         (c->methods[i].name == utf_constr))
174                         public_methods++;
175
176     class_constructor = class_new(utf_new_char("java/lang/reflect/Constructor"));
177
178         if (!class_constructor->loaded)
179                 class_load(class_constructor);
180
181         if (!class_constructor->linked)
182                 class_link(class_constructor);
183
184     array_constructor = builtin_anewarray(public_methods, class_constructor);
185
186     if (!array_constructor) 
187                 return NULL;
188
189     for (i = 0; i < c->methodscount; i++) 
190                 if ((c->methods[i].flags & ACC_PUBLIC) || !public_only){
191                         m = &c->methods[i];         
192                         if (m->name!=utf_constr)
193                                 continue;
194
195                         o = native_new_and_init(class_constructor);     
196                         array_constructor->data[pos++] = o;
197
198                         /* array of exceptions declared to be thrown, information not available !! */
199                         exceptiontypes = builtin_anewarray(0, class_java_lang_Class);
200
201                         /*          class_showconstantpool(class_constructor);*/
202                         /* initialize instance fields */
203                         /*          ((java_lang_reflect_Constructor*)o)->flag=(m->flags & (ACC_PRIVATE | ACC_PUBLIC | ACC_PROTECTED));*/
204                         setfield_critical(class_constructor,o,"clazz",          "Ljava/lang/Class;",  jobject, (jobject) c /*this*/);
205                         setfield_critical(class_constructor,o,"slot",           "I",                 jint,    i); 
206                         /*          setfield_critical(class_constructor,o,"flag",           "I",                     jint,    (m->flags & (ACC_PRIVATE | 
207                                         ACC_PUBLIC | ACC_PROTECTED))); */
208                         setfield_critical(class_constructor,o,"exceptionTypes", "[Ljava/lang/Class;", jobject, (jobject) exceptiontypes);
209             setfield_critical(class_constructor,o,"parameterTypes", "[Ljava/lang/Class;", jobject, (jobject) get_parametertypes(m));
210         }            
211     
212         return array_constructor;
213 }
214
215
216 /*
217  * Class:     java_lang_VMClass
218  * Method:    getDeclaredClasses
219  * Signature: (Z)[Ljava/lang/Class;
220  */
221 JNIEXPORT java_objectarray* JNICALL Java_java_lang_VMClass_getDeclaredClasses(JNIEnv *env, jclass clazz, java_lang_Class *that, s4 publicOnly)
222 {
223 #if defined(__GNUC__)
224 #warning fix the public only case
225 #endif
226         classinfo *c = (classinfo *) that;
227         int pos = 0;                /* current declared class */
228         int declaredclasscount = 0; /* number of declared classes */
229         java_objectarray *result;   /* array of declared classes */
230         int notPublicOnly = !publicOnly;
231         int i;
232
233         if (!that)
234                 return NULL;
235
236         /*printf("PublicOnly: %d\n",publicOnly);*/
237         if (!Java_java_lang_VMClass_isPrimitive(env, clazz, (java_lang_Class *) c) && (c->name->text[0] != '[')) {
238                 /* determine number of declared classes */
239                 for (i = 0; i < c->innerclasscount; i++) {
240                         if ( (c->innerclass[i].outer_class == c) && (notPublicOnly || (c->innerclass[i].flags & ACC_PUBLIC)))
241                                 /* outer class is this class */
242                                 declaredclasscount++;
243                 }
244         }
245
246         /*class_showmethods(c); */
247
248         result = builtin_anewarray(declaredclasscount, class_java_lang_Class);          
249
250         for (i = 0; i < c->innerclasscount; i++) {
251                 classinfo *inner = c->innerclass[i].inner_class;
252                 classinfo *outer = c->innerclass[i].outer_class;
253                 
254                 if ((outer == c) && (notPublicOnly || (inner->flags & ACC_PUBLIC))) {
255                         /* outer class is this class, store innerclass in array */
256                         use_class_as_object(inner);
257                         result->data[pos++] = (java_objectheader *) inner;
258                 }
259         }
260
261         return result;
262 }
263
264
265 /*
266  * Class:     java/lang/Class
267  * Method:    getDeclaringClass
268  * Signature: ()Ljava/lang/Class;
269  */
270 JNIEXPORT java_lang_Class* JNICALL Java_java_lang_VMClass_getDeclaringClass(JNIEnv *env, jclass clazz, struct java_lang_Class *that)
271 {
272 #if defined(__GNUC__)
273 #warning fixme
274 #endif
275         classinfo *c = (classinfo *) that;
276
277         if (that && !Java_java_lang_VMClass_isPrimitive(env, clazz,that) && (c->name->text[0] != '[')) {
278                 int i;
279
280                 if (c->innerclasscount == 0)  /* no innerclasses exist */
281                         return NULL;
282     
283                 for (i = 0; i < c->innerclasscount; i++) {
284                         classinfo *inner =  c->innerclass[i].inner_class;
285                         classinfo *outer =  c->innerclass[i].outer_class;
286       
287                         if (inner == c) {
288                                 /* innerclass is this class */
289                                 use_class_as_object(outer);
290                                 return (java_lang_Class *) outer;
291                         }
292                 }
293         }
294
295         /* return NULL for arrayclasses and primitive classes */
296         return NULL;
297 }
298
299
300 java_lang_reflect_Field* cacao_getField0(JNIEnv *env, java_lang_Class *that, java_lang_String *name, s4 public_only)
301 {
302     classinfo *c;
303         classinfo *fieldtype;
304     fieldinfo *f;               /* the field to be represented */
305     java_lang_reflect_Field *o; /* result: field-object */
306     utf *desc;                          /* the fielddescriptor */
307     int idx;
308
309     /* create Field object */
310 /*      c = (classinfo *) loader_load(utf_new_char("java/lang/reflect/Field")); */
311     c = class_new(utf_new_char("java/lang/reflect/Field"));
312     o = (java_lang_reflect_Field *) native_new_and_init(c);
313
314     /* get fieldinfo entry */
315     idx = class_findfield_index_approx((classinfo *) that, javastring_toutf(name, false));
316
317     if (idx < 0) {
318             *exceptionptr = new_exception(string_java_lang_NoSuchFieldException);
319             return NULL;
320         }
321
322     f = &(((classinfo *) that)->fields[idx]);
323     if (f) {
324                 if (public_only && !(f->flags & ACC_PUBLIC)) {
325                         /* field is not public  and public only had been requested*/
326                         *exceptionptr = new_exception(string_java_lang_NoSuchFieldException);
327                         return NULL;
328                 }
329
330                 desc = f->descriptor;
331                 fieldtype = class_from_descriptor(desc->text, utf_end(desc), NULL, CLASSLOAD_LOAD);
332                 if (!fieldtype)
333                         return NULL;
334          
335                 /* initialize instance fields */
336                 setfield_critical(c,o,"declaringClass",          "Ljava/lang/Class;",  jobject, (jobject) that /*this*/);
337                 /*      ((java_lang_reflect_Field*)(o))->flag=f->flags;*/
338                 /* save type in slot-field for faster processing */
339                 /*      setfield_critical(c,o,"flag",           "I",                jint,    (jint) f->flags);  */
340                 setfield_critical(c,o,"slot",           "I",                jint,    (jint) idx);  
341                 setfield_critical(c,o,"name",           "Ljava/lang/String;", jstring, (jstring) name);
342                 /*setfield_critical(c,o,"type",           "Ljava/lang/Class;",  jclass,  fieldtype);*/
343
344                 return o;
345     }
346
347     return NULL;
348 }
349
350
351 /*
352  * Class:     java_lang_VMClass
353  * Method:    getDeclaredFields
354  * Signature: (Z)[Ljava/lang/reflect/Field;
355  */
356 JNIEXPORT java_objectarray* JNICALL Java_java_lang_VMClass_getDeclaredFields(JNIEnv *env, jclass clazz, java_lang_Class *that, s4 public_only)
357 {
358     classinfo *c = (classinfo *) that;
359     classinfo *class_field;
360     java_objectarray *array_field; /* result: array of field-objects */
361     int public_fields = 0;         /* number of elements in field-array */
362     int pos = 0;
363     int i;
364
365     /* determine number of fields */
366     for (i = 0; i < c->fieldscount; i++) 
367                 if ((c->fields[i].flags & ACC_PUBLIC) || (!public_only))
368                         public_fields++;
369
370 /*      class_field = loader_load(utf_new_char("java/lang/reflect/Field")); */
371     class_field = class_new(utf_new_char("java/lang/reflect/Field"));
372
373     if (!class_field) 
374                 return NULL;
375
376     /* create array of fields */
377     array_field = builtin_anewarray(public_fields, class_field);
378
379     /* creation of array failed */
380     if (!array_field) 
381                 return NULL;
382
383     /* get the fields and store in the array */    
384     for (i = 0; i < c->fieldscount; i++) 
385                 if ( (c->fields[i].flags & ACC_PUBLIC) || (!public_only))
386                         array_field->data[pos++] = 
387                                 (java_objectheader *) cacao_getField0(env,
388                                            that, (java_lang_String *) javastring_new(c->fields[i].name),public_only);
389     return array_field;
390 }
391
392
393 /*
394  * Class:     java/lang/Class
395  * Method:    getInterfaces
396  * Signature: ()[Ljava/lang/Class;
397  */
398 JNIEXPORT java_objectarray* JNICALL Java_java_lang_VMClass_getInterfaces(JNIEnv *env, jclass clazz, java_lang_Class *that)
399 {
400         classinfo *c = (classinfo *) that;
401         u4 i;
402         java_objectarray *a;
403
404         a = builtin_anewarray(c->interfacescount, class_java_lang_Class);
405
406         if (!a)
407                 return NULL;
408
409         for (i = 0; i < c->interfacescount; i++) {
410                 use_class_as_object(c->interfaces[i]);
411
412                 a->data[i] = (java_objectheader *) c->interfaces[i];
413         }
414
415         return a;
416 }
417
418
419 java_lang_reflect_Method* cacao_getMethod0(JNIEnv *env, java_lang_Class *that, java_lang_String *name, java_objectarray *types, s4 which)
420 {
421     classinfo *c; 
422     classinfo *clazz = (classinfo *) that;
423     java_lang_reflect_Method* o;         /* result: Method-object */ 
424     java_objectarray *exceptiontypes;    /* the exceptions thrown by the method */
425     methodinfo *m;                       /* the method to be represented */
426
427 /*      c = (classinfo *) loader_load(utf_new_char("java/lang/reflect/Method")); */
428     c = class_new(utf_new_char("java/lang/reflect/Method"));
429     o = (java_lang_reflect_Method *) native_new_and_init(c);
430
431     /* find the method */
432     m = class_resolvemethod_approx(clazz, 
433                                                                    javastring_toutf(name, false),
434                                                                    create_methodsig(types,0)
435                                                                    );
436
437     if (!m || (which == MEMBER_PUBLIC && !(m->flags & ACC_PUBLIC))) {
438                 /* no apropriate method was found */
439                 *exceptionptr = new_exception(string_java_lang_NoSuchMethodException);
440                 return NULL;
441         }
442    
443     /* array of exceptions declared to be thrown, information not available !! */
444     exceptiontypes = builtin_anewarray(0, class_java_lang_Class);
445
446     /* initialize instance fields */
447     setfield_critical(c,o,"clazz",          "Ljava/lang/Class;",  jobject, (jobject) clazz /*this*/);
448     setfield_critical(c,o,"parameterTypes", "[Ljava/lang/Class;", jobject, (jobject) types);
449     setfield_critical(c,o,"exceptionTypes", "[Ljava/lang/Class;", jobject, (jobject) exceptiontypes);
450     setfield_critical(c,o,"name",           "Ljava/lang/String;", jstring, javastring_new(m->name));
451     setfield_critical(c,o,"modifiers",      "I",                  jint,    m->flags);
452     setfield_critical(c,o,"slot",           "I",                  jint,    0); 
453     setfield_critical(c,o,"returnType",     "Ljava/lang/Class;",  jclass,  get_returntype(m));
454
455     return o;
456 }
457
458
459 /*
460  * Class:     java_lang_VMClass
461  * Method:    getDeclaredMethods
462  * Signature: (Z)[Ljava/lang/reflect/Method;
463  */
464 JNIEXPORT java_objectarray* JNICALL Java_java_lang_VMClass_getDeclaredMethods(JNIEnv *env, jclass clazz, java_lang_Class *that, s4 public_only)
465 {
466     classinfo *c = (classinfo *) that;    
467     java_objectheader *o;
468     classinfo *class_method;
469     java_objectarray *array_method;     /* result: array of Method-objects */
470     java_objectarray *exceptiontypes;   /* the exceptions thrown by the method */
471     methodinfo *m;                      /* the current method to be represented */    
472     int public_methods = 0;             /* number of public methods of the class */
473     int pos = 0;
474     int i;
475     utf *utf_constr=utf_new_char("<init>");
476     utf *utf_clinit=utf_new_char("<clinit>");
477
478 /*      class_method = (classinfo*) loader_load(utf_new_char ("java/lang/reflect/Method")); */
479     class_method = class_new(utf_new_char("java/lang/reflect/Method"));
480
481     if (!class_method) 
482                 return NULL;
483
484         /* JOWENN: array classes do not declare methods according to mauve test. It should be considered, if 
485            we should return to my old clone method overriding instead of declaring it as a member function */
486         if (Java_java_lang_VMClass_isArray(env, clazz,that)) {
487                 return builtin_anewarray(0, class_method);
488         }
489
490
491     /* determine number of methods */
492     for (i = 0; i < c->methodscount; i++) 
493                 if ((((c->methods[i].flags & ACC_PUBLIC)) || (!public_only)) && 
494                         (!
495                          ((c->methods[i].name==utf_constr) ||
496                           (c->methods[i].name==utf_clinit) )
497                          )) public_methods++;
498
499         /*      
500                 class_showmethods(class_method);
501                 panic("JOWENN");
502         */
503     
504
505     array_method = builtin_anewarray(public_methods, class_method);
506
507     if (!array_method) 
508                 return NULL;
509
510     for (i = 0; i < c->methodscount; i++) 
511                 if (((c->methods[i].flags & ACC_PUBLIC) || (!public_only)) && 
512                         (!
513                          ((c->methods[i].name==utf_constr) ||
514                           (c->methods[i].name==utf_clinit) )
515                          )) {
516
517                         m = &c->methods[i];         
518                         o = native_new_and_init(class_method);     
519                         array_method->data[pos++] = o;
520
521                         /* array of exceptions declared to be thrown, information not available !! */
522                         exceptiontypes = builtin_anewarray (0, class_java_lang_Class);
523
524
525                         /* initialize instance fields */
526                         /*          ((java_lang_reflect_Method*)o)->flag=(m->flags & 
527                                         (ACC_PUBLIC | ACC_PRIVATE | ACC_PROTECTED | ACC_ABSTRACT | ACC_STATIC | ACC_FINAL |
528                                         ACC_SYNCHRONIZED | ACC_NATIVE | ACC_STRICT)
529                                         );*/
530                         setfield_critical(class_method,o,"declaringClass",          "Ljava/lang/Class;",  jobject, (jobject) c /*this*/);
531                         setfield_critical(class_method,o,"name",           "Ljava/lang/String;", jstring, javastring_new(m->name));
532                         /*          setfield_critical(class_method,o,"flag",      "I",               jint,   (m->flags &
533                                         (ACC_PUBLIC | ACC_PRIVATE | ACC_PROTECTED | ACC_ABSTRACT | ACC_STATIC | ACC_FINAL |
534                                         ACC_SYNCHRONIZED | ACC_NATIVE | ACC_STRICT)));*/
535                         setfield_critical(class_method,o,"slot",           "I",              jint,    i); 
536                         /*          setfield_critical(class_method,o,"returnType",     "Ljava/lang/Class;",  jclass,  get_returntype(m));
537                                         setfield_critical(class_method,o,"exceptionTypes", "[Ljava/lang/Class;", jobject, (jobject) exceptiontypes);
538                                         setfield_critical(class_method,o,"parameterTypes", "[Ljava/lang/Class;", jobject, (jobject) get_parametertypes(m));*/
539         }            
540
541     return array_method;
542 }
543
544
545 /*
546  * Class:     java/lang/Class
547  * Method:    getModifiers
548  * Signature: ()I
549  */
550 JNIEXPORT s4 JNICALL Java_java_lang_VMClass_getModifiers(JNIEnv *env, jclass clazz, java_lang_Class *that)
551 {
552         classinfo *c = (classinfo *) that;
553         return c->flags;
554 }
555
556
557 /*
558  * Class:     java/lang/Class
559  * Method:    getName
560  * Signature: ()Ljava/lang/String;
561  */
562 JNIEXPORT java_lang_String* JNICALL Java_java_lang_VMClass_getName(JNIEnv *env, jclass clazz, java_lang_Class* that)
563 {
564         u4 i;
565         classinfo *c = (classinfo *) that;
566         java_lang_String *s = (java_lang_String *) javastring_new(c->name);
567
568         if (!s)
569                 return NULL;
570
571         /* return string where '/' is replaced by '.' */
572         for (i = 0; i < s->value->header.size; i++) {
573                 if (s->value->data[i] == '/')
574                         s->value->data[i] = '.';
575         }
576
577         return s;
578         
579 }
580
581
582 /*
583  * Class:     java/lang/VMClass
584  * Method:    getBeautifiedName
585  * Signature: (Ljava/lang/Class;)Ljava/lang/String;
586  */
587 JNIEXPORT java_lang_String* JNICALL Java_java_lang_VMClass_getBeautifiedName(JNIEnv *env, jclass clazz, java_lang_Class *par1)
588 {
589     u4 dimCnt;
590     classinfo *c = (classinfo *) (par1);
591
592     char *utf__ptr = c->name->text;      /* current position in utf-text */
593     char **utf_ptr = &utf__ptr;
594     char *desc_end = utf_end(c->name);   /* points behind utf string     */
595     java_lang_String *s;
596     char *str = NULL;
597     s4   len;
598     s4   i;
599     
600 #if 0
601     log_text("Java_java_lang_VMClass_getBeautifiedName");
602     utf_display(c->name);
603     log_text("beautifying");
604 #endif
605     dimCnt=0;
606     while ( *utf_ptr != desc_end ) {
607                 if (utf_nextu2(utf_ptr)=='[') dimCnt++;
608                 else break;
609     }
610     utf__ptr = (*utf_ptr) - 1;
611
612     len = 0;
613
614 #if 0   
615     log_text("------>");
616     utf_display(c->name);
617     log_text("<------");
618 #endif 
619
620     if (((*utf_ptr) + 1) == desc_end) {
621             for (i = 0; i < PRIMITIVETYPE_COUNT; i++) {
622                         if (primitivetype_table[i].typesig == (*utf__ptr)) {
623                                 len = dimCnt * 2 + strlen(primitivetype_table[i].name);
624                                 str = MNEW(char, len + 1);
625                                 strcpy(str, primitivetype_table[i].name);
626                                 break;
627                         }
628             }
629     }
630
631     if (len == 0) {
632                 if (dimCnt>0) {
633                         len = dimCnt + strlen(c->name->text) - 2;
634                         str = MNEW(char, len + 1);
635                         strncpy(str, ++utf__ptr, len - 2 * dimCnt);        
636                 } else {
637                         len = strlen(c->name->text);
638                         str = MNEW(char, len + 1);
639                         strncpy(str, utf__ptr, len);       
640                 }
641                 
642     }   
643
644     dimCnt = len - 2 * dimCnt;
645     str[len] = 0;
646     for (i = len - 1; i >= dimCnt; i = i - 2) {
647                 str[i] = ']';
648                 str[i - 1] = '[';
649     }
650
651     s = javastring_new(utf_new_char(str));
652     MFREE(str, char, len + 1);
653
654     if (!s) return NULL;
655
656         /* return string where '/' is replaced by '.' */
657         for (i = 0; i < s->value->header.size; i++) {
658                 if (s->value->data[i] == '/') s->value->data[i] = '.';
659         }
660         
661         return s;
662 }
663
664
665
666 /*
667  * Class:     java/lang/Class
668  * Method:    getSuperclass
669  * Signature: ()Ljava/lang/Class;
670  */
671 JNIEXPORT java_lang_Class* JNICALL Java_java_lang_VMClass_getSuperclass(JNIEnv *env, jclass clazz, java_lang_Class *that)
672 {
673         classinfo *cl = (classinfo *) that;
674         classinfo *c = cl->super;
675
676         if (!c)
677                 return NULL;
678
679         use_class_as_object (c);
680
681         return (java_lang_Class *) c;
682 }
683
684
685 /*
686  * Class:     java/lang/Class
687  * Method:    isArray
688  * Signature: ()Z
689  */
690 JNIEXPORT s4 JNICALL Java_java_lang_VMClass_isArray(JNIEnv *env, jclass clazz, java_lang_Class *that)
691 {
692     classinfo *c = (classinfo *) that;
693
694     return c->vftbl->arraydesc != NULL;
695 }
696
697
698 /*
699  * Class:     java/lang/Class
700  * Method:    isAssignableFrom
701  * Signature: (Ljava/lang/Class;)Z
702  */
703 JNIEXPORT s4 JNICALL Java_java_lang_VMClass_isAssignableFrom(JNIEnv *env, jclass clazz, java_lang_Class *that, java_lang_Class *sup)
704 {
705         /*      log_text("Java_java_lang_VMClass_isAssignableFrom");*/
706         
707         if (!sup) return 0;
708         if (!that) {
709                 panic("sup->vmClass is NULL in VMClass.isAssignableFrom");
710                 return 0;
711         }
712         return (*env)->IsAssignableForm(env, (jclass) sup, (jclass) that);
713 }
714
715
716 /*
717  * Class:     java/lang/Class
718  * Method:    isInstance
719  * Signature: (Ljava/lang/Object;)Z
720  */
721 JNIEXPORT s4 JNICALL Java_java_lang_VMClass_isInstance(JNIEnv *env, jclass clazz, java_lang_Class *that, java_lang_Object *obj)
722 {
723         classinfo *clazz = (classinfo *) that;
724
725         return (*env)->IsInstanceOf(env, (jobject) obj, that);
726 }
727
728
729 /*
730  * Class:     java/lang/Class
731  * Method:    isInterface
732  * Signature: ()Z
733  */
734 JNIEXPORT s4 JNICALL Java_java_lang_VMClass_isInterface(JNIEnv *env, jclass clazz, java_lang_Class *that)
735 {
736         classinfo *c = (classinfo *) that;
737
738         if (c->flags & ACC_INTERFACE)
739                 return true;
740
741         return false;
742 }
743
744
745 /*
746  * Class:     java/lang/Class
747  * Method:    isPrimitive
748  * Signature: ()Z
749  */
750 JNIEXPORT s4 JNICALL Java_java_lang_VMClass_isPrimitive(JNIEnv *env, jclass clazz, java_lang_Class *that)
751 {
752         int i;
753         classinfo *c = (classinfo *) that;
754
755         /* search table of primitive classes */
756         for (i = 0; i < PRIMITIVETYPE_COUNT; i++)
757                 if (primitivetype_table[i].class_primitive == c)
758                         return true;
759
760         return false;
761 }
762
763
764
765
766 /*
767  * Class:     java_lang_VMClass
768  * Method:    initialize
769  * Signature: ()V
770  */
771 JNIEXPORT void JNICALL Java_java_lang_VMClass_initialize(JNIEnv *env, jclass clazz, java_lang_Class *that)
772 {
773         log_text("Java_java_lang_VMClass_initialize");
774 }
775
776
777 /*
778  * Class:     java_lang_VMClass
779  * Method:    loadArrayClass
780  * Signature: (Ljava/lang/String;Ljava/lang/ClassLoader;)Ljava/lang/Class;
781  */
782 JNIEXPORT java_lang_Class* JNICALL Java_java_lang_VMClass_loadArrayClass(JNIEnv *env, jclass clazz, java_lang_String *par1, java_lang_ClassLoader* par2)
783 {
784         log_text("Java_java_lang_VMClass_loadArrayClass");
785
786         return 0;
787 }
788
789
790 /*
791  * Class:     java_lang_VMClass
792  * Method:    throwException
793  * Signature: (Ljava/lang/Throwable;)V
794  */
795 JNIEXPORT void JNICALL Java_java_lang_VMClass_throwException(JNIEnv *env, jclass clazz, java_lang_Throwable *par1)
796 {
797         log_text("Won't implement VmClass.throwException. (Not needed according to spec) Is only needed to be bug compatible with the SUN VM. (according to gnuclasspath team)");
798 }
799
800
801
802
803
804 /*
805  * These are local overrides for various environment variables in Emacs.
806  * Please do not remove this and leave it at the end of the file, where
807  * Emacs will automagically detect them.
808  * ---------------------------------------------------------------------
809  * Local variables:
810  * mode: c
811  * indent-tabs-mode: t
812  * c-basic-offset: 4
813  * tab-width: 4
814  * End:
815  */