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