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