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