* Typo
[cacao.git] / src / native / vm / VMClass.c
1 /* src/native/vm/VMClass.c - java/lang/VMClass
2
3    Copyright (C) 1996-2005 R. Grafl, A. Krall, C. Kruegel, C. Oates,
4    R. Obermaisser, M. Platter, M. Probst, S. Ring, E. Steiner,
5    C. Thalinger, D. Thuernbeck, P. Tomsich, C. Ullrich, J. Wenninger,
6    Institut f. Computersprachen - TU Wien
7
8    This file is part of CACAO.
9
10    This program is free software; you can redistribute it and/or
11    modify it under the terms of the GNU General Public License as
12    published by the Free Software Foundation; either version 2, or (at
13    your option) any later version.
14
15    This program is distributed in the hope that it will be useful, but
16    WITHOUT ANY WARRANTY; without even the implied warranty of
17    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
18    General Public License for more details.
19
20    You should have received a copy of the GNU General Public License
21    along with this program; if not, write to the Free Software
22    Foundation, Inc., 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             Christian Thalinger
31
32    $Id: VMClass.c 2655 2005-06-13 14:12:34Z twisti $
33
34 */
35
36
37 #include <string.h>
38
39 #include "types.h"
40 #include "mm/memory.h"
41 #include "native/jni.h"
42 #include "native/native.h"
43 #include "native/include/java_lang_Class.h"
44 #include "native/include/java_lang_ClassLoader.h"
45 #include "native/include/java_lang_Object.h"
46 #include "native/include/java_lang_VMClass.h"
47 #include "native/include/java_lang_reflect_Constructor.h"
48 #include "native/include/java_lang_reflect_Field.h"
49 #include "native/include/java_lang_reflect_Method.h"
50 #include "native/include/java_security_ProtectionDomain.h"
51 #include "toolbox/logging.h"
52 #include "vm/builtin.h"
53 #include "vm/exceptions.h"
54 #include "vm/global.h"
55 #include "vm/initialize.h"
56 #include "vm/loader.h"
57 #include "vm/stringlocal.h"
58 #include "vm/tables.h"
59 #include "vm/resolve.h"
60
61
62 /* for selecting public members */
63 #define MEMBER_PUBLIC  0
64
65
66 /*
67  * Class:     java/lang/VMClass
68  * Method:    forName
69  * Signature: (Ljava/lang/String;)Ljava/lang/Class;
70  */
71 JNIEXPORT java_lang_Class* JNICALL Java_java_lang_VMClass_forName(JNIEnv *env, jclass clazz, java_lang_String *s)
72 {
73         return NULL;
74
75         /* XXX TWISTI: we currently use the classpath default implementation, maybe 
76            we change this someday to a faster native version */
77 #if 0
78         classinfo *c;
79         utf       *u;
80
81         /* illegal argument */
82
83         if (!s)
84                 return NULL;
85         
86         /* create utf string in which '.' is replaced by '/' */
87
88         u = javastring_toutf(s, true);
89
90         /* try to load, ... */
91
92         if (!(c = load_class_bootstrap(u))) {
93                 classinfo *xclass;
94
95                 xclass = (*exceptionptr)->vftbl->class;
96
97                 /* if the exception is a NoClassDefFoundError, we replace it with a
98                    ClassNotFoundException, otherwise return the exception */
99
100                 if (xclass == class_java_lang_NoClassDefFoundError) {
101                         /* clear exceptionptr, because builtin_new checks for 
102                            ExceptionInInitializerError */
103                         *exceptionptr = NULL;
104
105                         *exceptionptr =
106                                 new_exception_javastring(string_java_lang_ClassNotFoundException, s);
107                 }
108
109             return NULL;
110         }
111
112         /* link, ... */
113
114         if (!link_class(c))
115                 return NULL;
116         
117         /* ...and initialize it */
118
119         if (!class_init(c))
120                 return NULL;
121
122         use_class_as_object(c);
123
124         return (java_lang_Class *) c;
125 #endif
126 }
127
128
129 /*
130  * Class:     java/lang/VMClass
131  * Method:    getClassLoader
132  * Signature: ()Ljava/lang/ClassLoader;
133  */
134 JNIEXPORT java_lang_ClassLoader* JNICALL Java_java_lang_VMClass_getClassLoader(JNIEnv *env, jclass clazz, java_lang_Class *that)
135 {  
136         return (java_lang_ClassLoader *) ((classinfo *) that)->classloader;
137 }
138
139
140 /*
141  * Class:     java/lang/VMClass
142  * Method:    getComponentType
143  * Signature: ()Ljava/lang/Class;
144  */
145 JNIEXPORT java_lang_Class* JNICALL Java_java_lang_VMClass_getComponentType(JNIEnv *env, jclass clazz, java_lang_Class *that)
146 {
147     classinfo *thisclass = (classinfo *) that;
148     classinfo *c = NULL;
149     arraydescriptor *desc;
150     
151     if ((desc = thisclass->vftbl->arraydesc) != NULL) {
152         if (desc->arraytype == ARRAYTYPE_OBJECT)
153             c = desc->componentvftbl->class;
154         else
155             c = primitivetype_table[desc->arraytype].class_primitive;
156         
157         /* set vftbl */
158                 use_class_as_object(c);
159     }
160     
161     return (java_lang_Class *) c;
162 }
163
164
165 /*
166  * Class:     java/lang/VMClass
167  * Method:    getDeclaredConstructors
168  * Signature: (Z)[Ljava/lang/reflect/Constructor;
169  */
170 JNIEXPORT java_objectarray* JNICALL Java_java_lang_VMClass_getDeclaredConstructors(JNIEnv *env, jclass clazz, java_lang_Class *that, s4 public_only)
171 {
172   
173     classinfo         *c;
174     java_objectheader *o;
175     java_objectarray  *array_constructor;  /* result: array of Method-objects */
176     java_objectarray *exceptiontypes;  /* the exceptions thrown by the method */
177     methodinfo *m;                      /* the current method to be represented */    
178     int public_methods = 0;             /* number of public methods of the class */
179     int pos = 0;
180     int i;
181
182     c = (classinfo *) that;
183
184     /* determine number of constructors */
185
186     for (i = 0; i < c->methodscount; i++) 
187                 if (((c->methods[i].flags & ACC_PUBLIC) || !public_only) && 
188                         (c->methods[i].name == utf_init))
189                         public_methods++;
190
191     array_constructor =
192                 builtin_anewarray(public_methods, class_java_lang_reflect_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_init)
201                                 continue;
202
203                         o = native_new_and_init(class_java_lang_reflect_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
213                         setfield_critical(class_java_lang_reflect_Constructor,
214                                                           o,
215                                                           "clazz",
216                                                           "Ljava/lang/Class;",
217                                                           jobject,
218                                                           (jobject) c /*this*/);
219
220                         setfield_critical(class_java_lang_reflect_Constructor,
221                                                           o,
222                                                           "slot",
223                                                           "I",
224                                                           jint,
225                                                           i);
226
227                         /*          setfield_critical(class_constructor,o,"flag",           "I",                     jint,    (m->flags & (ACC_PRIVATE | 
228                                         ACC_PUBLIC | ACC_PROTECTED))); */
229
230                         setfield_critical(class_java_lang_reflect_Constructor,
231                                                           o,
232                                                           "exceptionTypes",
233                                                           "[Ljava/lang/Class;",
234                                                           jobject,
235                                                           (jobject) exceptiontypes);
236
237                         setfield_critical(class_java_lang_reflect_Constructor,
238                                                           o,
239                                                           "parameterTypes",
240                                                           "[Ljava/lang/Class;",
241                                                           jobject,
242                                                           (jobject) get_parametertypes(m));
243         }
244         }
245
246         return array_constructor;
247 }
248
249
250 /*
251  * Class:     java/lang/VMClass
252  * Method:    getDeclaredClasses
253  * Signature: (Z)[Ljava/lang/Class;
254  */
255 JNIEXPORT java_objectarray* JNICALL Java_java_lang_VMClass_getDeclaredClasses(JNIEnv *env, jclass clazz, java_lang_Class *that, s4 publicOnly)
256 {
257         /* XXX fix the public only case */
258
259         classinfo *c = (classinfo *) that;
260         int pos = 0;                /* current declared class */
261         int declaredclasscount = 0; /* number of declared classes */
262         java_objectarray *result;   /* array of declared classes */
263         int notPublicOnly = !publicOnly;
264         int i;
265
266         if (!that)
267                 return NULL;
268
269         /*printf("PublicOnly: %d\n",publicOnly);*/
270         if (!Java_java_lang_VMClass_isPrimitive(env, clazz, (java_lang_Class *) c) && (c->name->text[0] != '[')) {
271                 /* determine number of declared classes */
272                 for (i = 0; i < c->innerclasscount; i++) {
273                         if ( (c->innerclass[i].outer_class.cls == c) && (notPublicOnly || (c->innerclass[i].flags & ACC_PUBLIC)))
274                                 /* outer class is this class */
275                                 declaredclasscount++;
276                 }
277         }
278
279         /*class_showmethods(c); */
280
281         result = builtin_anewarray(declaredclasscount, class_java_lang_Class);          
282
283         for (i = 0; i < c->innerclasscount; i++) {
284                 classinfo *inner;
285                 classinfo *outer;
286
287                 if (!resolve_classref_or_classinfo(NULL,c->innerclass[i].inner_class,resolveEager,false,&inner))
288                         return NULL;
289                 if (!resolve_classref_or_classinfo(NULL,c->innerclass[i].outer_class,resolveEager,false,&inner))
290                         return NULL;
291                 
292                 if ((outer == c) && (notPublicOnly || (inner->flags & ACC_PUBLIC))) {
293                         /* outer class is this class, store innerclass in array */
294                         use_class_as_object(inner);
295                         result->data[pos++] = (java_objectheader *) inner;
296                 }
297         }
298
299         return result;
300 }
301
302
303 /*
304  * Class:     java/lang/VMClass
305  * Method:    getDeclaringClass
306  * Signature: ()Ljava/lang/Class;
307  */
308 JNIEXPORT java_lang_Class* JNICALL Java_java_lang_VMClass_getDeclaringClass(JNIEnv *env, jclass clazz, struct java_lang_Class *that)
309 {
310         /* XXX fixme */
311
312         classinfo *c = (classinfo *) that;
313
314         if (that && !Java_java_lang_VMClass_isPrimitive(env, clazz,that) && (c->name->text[0] != '[')) {
315                 int i;
316
317                 if (c->innerclasscount == 0)  /* no innerclasses exist */
318                         return NULL;
319     
320                 for (i = 0; i < c->innerclasscount; i++) {
321                         classinfo *inner =  c->innerclass[i].inner_class.cls;
322                         classinfo *outer =  c->innerclass[i].outer_class.cls;
323       
324                         if (inner == c) {
325                                 /* innerclass is this class */
326                                 use_class_as_object(outer);
327                                 return (java_lang_Class *) outer;
328                         }
329                 }
330         }
331
332         /* return NULL for arrayclasses and primitive classes */
333         return NULL;
334 }
335
336
337 java_lang_reflect_Field* cacao_getField0(JNIEnv *env, java_lang_Class *that, java_lang_String *name, s4 public_only)
338 {
339     classinfo *c;
340     fieldinfo *f;               /* the field to be represented */
341     java_lang_reflect_Field *o; /* result: field-object */
342     int idx;
343
344         c = (classinfo *) that;
345
346     /* create Field object */
347
348     o = (java_lang_reflect_Field *)
349                 native_new_and_init(class_java_lang_reflect_Field);
350
351     /* get fieldinfo entry */
352         
353     idx = class_findfield_index_approx(c, javastring_toutf(name, false));
354
355     if (idx < 0) {
356             *exceptionptr = new_exception(string_java_lang_NoSuchFieldException);
357             return NULL;
358         }
359
360     f = &(c->fields[idx]);
361
362     if (f) {
363                 if (public_only && !(f->flags & ACC_PUBLIC)) {
364                         /* field is not public  and public only had been requested*/
365                         *exceptionptr =
366                                 new_exception(string_java_lang_NoSuchFieldException);
367                         return NULL;
368                 }
369
370                 /* initialize instance fields */
371
372                 setfield_critical(class_java_lang_reflect_Field,
373                                                   o,
374                                                   "declaringClass",
375                                                   "Ljava/lang/Class;",
376                                                   jobject,
377                                                   (jobject) that /*this*/);
378
379                 /*      ((java_lang_reflect_Field*)(o))->flag=f->flags;*/
380                 /* save type in slot-field for faster processing */
381                 /* setfield_critical(c,o,"flag",           "I",             jint,    (jint) f->flags); */
382                 /*o->flag = f->flags;*/
383
384                 setfield_critical(class_java_lang_reflect_Field,
385                                                   o,
386                                                   "slot",
387                                                   "I",
388                                                   jint,
389                                                   (jint) idx);
390
391                 setfield_critical(class_java_lang_reflect_Field,
392                                                   o,
393                                                   "name",
394                                                   "Ljava/lang/String;",
395                                                   jstring,
396                                                   (jstring) name);
397
398                 /*setfield_critical(c,o,"type",           "Ljava/lang/Class;",  jclass,  fieldtype);*/
399
400                 return o;
401     }
402
403     return NULL;
404 }
405
406
407 /*
408  * Class:     java/lang/VMClass
409  * Method:    getDeclaredFields
410  * Signature: (Z)[Ljava/lang/reflect/Field;
411  */
412 JNIEXPORT java_objectarray* JNICALL Java_java_lang_VMClass_getDeclaredFields(JNIEnv *env, jclass clazz, java_lang_Class *that, s4 public_only)
413 {
414     classinfo        *c;
415     java_objectarray *array_field; /* result: array of field-objects */
416         java_lang_String *s;
417     int public_fields = 0;         /* number of elements in field-array */
418     int pos = 0;
419     int i;
420
421     c = (classinfo *) that;
422
423     /* determine number of fields */
424
425     for (i = 0; i < c->fieldscount; i++)
426                 if ((c->fields[i].flags & ACC_PUBLIC) || (!public_only))
427                         public_fields++;
428
429     /* create array of fields */
430
431     array_field =
432                 builtin_anewarray(public_fields, class_java_lang_reflect_Field);
433
434     /* creation of array failed */
435
436     if (!array_field)
437                 return NULL;
438
439     /* get the fields and store in the array */
440
441     for (i = 0; i < c->fieldscount; i++) {
442                 if ((c->fields[i].flags & ACC_PUBLIC) || (!public_only)) {
443                         s = (java_lang_String *) javastring_new(c->fields[i].name);
444
445                         array_field->data[pos++] = (java_objectheader *)
446                                 cacao_getField0(env, that, s, public_only);
447                 }
448         }
449
450     return array_field;
451 }
452
453
454 /*
455  * Class:     java/lang/VMClass
456  * Method:    getInterfaces
457  * Signature: ()[Ljava/lang/Class;
458  */
459 JNIEXPORT java_objectarray* JNICALL Java_java_lang_VMClass_getInterfaces(JNIEnv *env, jclass clazz, java_lang_Class *that)
460 {
461         classinfo *c = (classinfo *) that;
462         u4 i;
463         java_objectarray *a;
464
465         a = builtin_anewarray(c->interfacescount, class_java_lang_Class);
466
467         if (!a)
468                 return NULL;
469
470         for (i = 0; i < c->interfacescount; i++) {
471                 use_class_as_object(c->interfaces[i].cls);
472
473                 a->data[i] = (java_objectheader *) c->interfaces[i].cls;
474         }
475
476         return a;
477 }
478
479
480 java_lang_reflect_Method* cacao_getMethod0(JNIEnv *env, java_lang_Class *that, java_lang_String *name, java_objectarray *types, s4 which)
481 {
482     classinfo *clazz;
483     java_lang_reflect_Method* o;                     /* result: Method-object */
484     java_objectarray *exceptiontypes;  /* the exceptions thrown by the method */
485     methodinfo *m;                            /* the method to be represented */
486
487     clazz = (classinfo *) that;
488
489     o = (java_lang_reflect_Method *)
490                 native_new_and_init(class_java_lang_reflect_Method);
491
492     /* find the method */
493
494     m = class_resolvemethod_approx(clazz, 
495                                                                    javastring_toutf(name, false),
496                                                                    create_methodsig(types, 0));
497
498     if (!m || (which == MEMBER_PUBLIC && !(m->flags & ACC_PUBLIC))) {
499                 /* no apropriate method was found */
500                 *exceptionptr = new_exception(string_java_lang_NoSuchMethodException);
501                 return NULL;
502         }
503    
504     /* array of exceptions declared to be thrown, information not available! */
505
506     exceptiontypes = builtin_anewarray(0, class_java_lang_Class);
507
508     /* initialize instance fields */
509
510     setfield_critical(class_java_lang_reflect_Method,
511                                           o,
512                                           "clazz",
513                                           "Ljava/lang/Class;",
514                                           jobject,
515                                           (jobject) clazz /*this*/);
516
517     setfield_critical(class_java_lang_reflect_Method,
518                                           o,
519                                           "parameterTypes",
520                                           "[Ljava/lang/Class;",
521                                           jobject,
522                                           (jobject) types);
523
524     setfield_critical(class_java_lang_reflect_Method,
525                                           o,
526                                           "exceptionTypes",
527                                           "[Ljava/lang/Class;",
528                                           jobject,
529                                           (jobject) exceptiontypes);
530
531     setfield_critical(class_java_lang_reflect_Method,
532                                           o,
533                                           "name",
534                                           "Ljava/lang/String;",
535                                           jstring,
536                                           (jobject) javastring_new(m->name));
537
538     setfield_critical(class_java_lang_reflect_Method,
539                                           o,
540                                           "modifiers",
541                                           "I",
542                                           jint,
543                                           m->flags);
544
545     setfield_critical(class_java_lang_reflect_Method,
546                                           o,
547                                           "slot",
548                                           "I",
549                                           jint,
550                                           0); 
551
552     setfield_critical(class_java_lang_reflect_Method,
553                                           o,
554                                           "returnType",
555                                           "Ljava/lang/Class;",
556                                           jclass,
557                                           get_returntype(m));
558
559     return o;
560 }
561
562
563 /*
564  * Class:     java/lang/VMClass
565  * Method:    getDeclaredMethods
566  * Signature: (Z)[Ljava/lang/reflect/Method;
567  */
568 JNIEXPORT java_objectarray* JNICALL Java_java_lang_VMClass_getDeclaredMethods(JNIEnv *env, jclass clazz, java_lang_Class *that, s4 public_only)
569 {
570     classinfo *c;
571     java_objectheader *o;
572     java_objectarray *array_method;     /* result: array of Method-objects */
573     java_objectarray *exceptiontypes;  /* the exceptions thrown by the method */
574     methodinfo *m;                    /* the current method to be represented */
575     int public_methods = 0;          /* number of public methods of the class */
576     int pos = 0;
577     int i;
578
579     c = (classinfo *) that;    
580
581         /* JOWENN: array classes do not declare methods according to mauve test.  */
582         /* It should be considered, if we should return to my old clone method    */
583         /* overriding instead of declaring it as a member function.               */
584
585         if (Java_java_lang_VMClass_isArray(env, clazz, that))
586                 return builtin_anewarray(0, class_java_lang_reflect_Method);
587
588     /* determine number of methods */
589
590     for (i = 0; i < c->methodscount; i++) 
591                 if ((((c->methods[i].flags & ACC_PUBLIC)) || (!public_only)) && 
592                         (!
593                          ((c->methods[i].name == utf_init) ||
594                           (c->methods[i].name == utf_clinit))
595                          ))
596                         public_methods++;
597
598         /*      
599                 class_showmethods(class_method);
600                 log_text("JOWENN");
601                 assert(0);
602         */
603
604     array_method =
605                 builtin_anewarray(public_methods, class_java_lang_reflect_Method);
606
607     if (!array_method) 
608                 return NULL;
609
610     for (i = 0; i < c->methodscount; i++) {
611                 if (((c->methods[i].flags & ACC_PUBLIC) || (!public_only)) && 
612                         (!
613                          ((c->methods[i].name == utf_init) ||
614                           (c->methods[i].name == utf_clinit))
615                          )) {
616
617                         m = &c->methods[i];
618                         o = native_new_and_init(class_java_lang_reflect_Method);
619                         array_method->data[pos++] = o;
620
621                         /* array of exceptions declared to be thrown, information not available !! */
622                         exceptiontypes = builtin_anewarray(0, class_java_lang_Class);
623
624
625                         /* initialize instance fields */
626                         /*          ((java_lang_reflect_Method*)o)->flag=(m->flags & 
627                                         (ACC_PUBLIC | ACC_PRIVATE | ACC_PROTECTED | ACC_ABSTRACT | ACC_STATIC | ACC_FINAL |
628                                         ACC_SYNCHRONIZED | ACC_NATIVE | ACC_STRICT)
629                                         );*/
630
631                         setfield_critical(class_java_lang_reflect_Method,
632                                                           o,
633                                                           "declaringClass",
634                                                           "Ljava/lang/Class;",
635                                                           jobject,
636                                                           (jobject) c /*this*/);
637
638                         setfield_critical(class_java_lang_reflect_Method,
639                                                           o,
640                                                           "name",
641                                                           "Ljava/lang/String;",
642                                                           jstring,
643                                                           (jobject) javastring_new(m->name));
644
645                         /*          setfield_critical(class_method,o,"flag",      "I",               jint,   (m->flags &
646                                         (ACC_PUBLIC | ACC_PRIVATE | ACC_PROTECTED | ACC_ABSTRACT | ACC_STATIC | ACC_FINAL |
647                                         ACC_SYNCHRONIZED | ACC_NATIVE | ACC_STRICT)));*/
648
649                         setfield_critical(class_java_lang_reflect_Method,
650                                                           o,
651                                                           "slot",
652                                                           "I",
653                                                           jint,
654                                                           i);
655
656                         /*          setfield_critical(class_method,o,"returnType",     "Ljava/lang/Class;",  jclass,  get_returntype(m));
657                                         setfield_critical(class_method,o,"exceptionTypes", "[Ljava/lang/Class;", jobject, (jobject) exceptiontypes);
658                                         setfield_critical(class_method,o,"parameterTypes", "[Ljava/lang/Class;", jobject, (jobject) get_parametertypes(m));*/
659         }            
660         }
661
662     return array_method;
663 }
664
665
666 /*
667  * Class:     java/lang/VMClass
668  * Method:    getModifiers
669  * Signature: ()I
670  */
671 JNIEXPORT s4 JNICALL Java_java_lang_VMClass_getModifiers(JNIEnv *env, jclass clazz, java_lang_Class *that)
672 {
673         classinfo *c = (classinfo *) that;
674
675         return c->flags;
676 }
677
678
679 /*
680  * Class:     java/lang/VMClass
681  * Method:    getName
682  * Signature: ()Ljava/lang/String;
683  */
684 JNIEXPORT java_lang_String* JNICALL Java_java_lang_VMClass_getName(JNIEnv *env, jclass clazz, java_lang_Class *that)
685 {
686         classinfo        *c;
687         java_lang_String *s;
688         u4                i;
689
690         c = (classinfo *) that;
691         s = (java_lang_String *) javastring_new(c->name);
692
693         if (!s)
694                 return NULL;
695
696         /* return string where '/' is replaced by '.' */
697
698         for (i = 0; i < s->value->header.size; i++) {
699                 if (s->value->data[i] == '/')
700                         s->value->data[i] = '.';
701         }
702
703         return s;
704 }
705
706
707 /*
708  * Class:     java/lang/VMClass
709  * Method:    getBeautifiedName
710  * Signature: (Ljava/lang/Class;)Ljava/lang/String;
711  */
712 JNIEXPORT java_lang_String* JNICALL Java_java_lang_VMClass_getBeautifiedName(JNIEnv *env, jclass clazz, java_lang_Class *par1)
713 {
714     u4 dimCnt;
715     classinfo *c = (classinfo *) (par1);
716
717     char *utf__ptr = c->name->text;      /* current position in utf-text */
718     char **utf_ptr = &utf__ptr;
719     char *desc_end = UTF_END(c->name);   /* points behind utf string     */
720     java_lang_String *s;
721     char *str = NULL;
722     s4   len;
723     s4   i;
724     
725 #if 0
726     log_text("Java_java_lang_VMClass_getBeautifiedName");
727     utf_display(c->name);
728     log_text("beautifying");
729 #endif
730     dimCnt=0;
731     while ( *utf_ptr != desc_end ) {
732                 if (utf_nextu2(utf_ptr)=='[') dimCnt++;
733                 else break;
734     }
735     utf__ptr = (*utf_ptr) - 1;
736
737     len = 0;
738
739 #if 0   
740     log_text("------>");
741     utf_display(c->name);
742     log_text("<------");
743 #endif 
744
745     if (((*utf_ptr) + 1) == desc_end) {
746             for (i = 0; i < PRIMITIVETYPE_COUNT; i++) {
747                         if (primitivetype_table[i].typesig == (*utf__ptr)) {
748                                 len = dimCnt * 2 + strlen(primitivetype_table[i].name);
749                                 str = MNEW(char, len + 1);
750                                 strcpy(str, primitivetype_table[i].name);
751                                 break;
752                         }
753             }
754     }
755
756     if (len == 0) {
757                 if (dimCnt>0) {
758                         len = dimCnt + strlen(c->name->text) - 2;
759                         str = MNEW(char, len + 1);
760                         strncpy(str, ++utf__ptr, len - 2 * dimCnt);        
761                 } else {
762                         len = strlen(c->name->text);
763                         str = MNEW(char, len + 1);
764                         strncpy(str, utf__ptr, len);       
765                 }
766                 
767     }   
768
769     dimCnt = len - 2 * dimCnt;
770     str[len] = 0;
771     for (i = len - 1; i >= dimCnt; i = i - 2) {
772                 str[i] = ']';
773                 str[i - 1] = '[';
774     }
775
776     s = javastring_new(utf_new_char(str));
777     MFREE(str, char, len + 1);
778
779     if (!s) return NULL;
780
781         /* return string where '/' is replaced by '.' */
782         for (i = 0; i < s->value->header.size; i++) {
783                 if (s->value->data[i] == '/') s->value->data[i] = '.';
784         }
785         
786         return s;
787 }
788
789
790
791 /*
792  * Class:     java/lang/Class
793  * Method:    getSuperclass
794  * Signature: ()Ljava/lang/Class;
795  */
796 JNIEXPORT java_lang_Class* JNICALL Java_java_lang_VMClass_getSuperclass(JNIEnv *env, jclass clazz, java_lang_Class *that)
797 {
798         classinfo *cl = (classinfo *) that;
799         classinfo *c = cl->super.cls;
800
801         if (cl->flags & ACC_INTERFACE)
802                 return NULL;
803
804         if (!c)
805                 return NULL;
806
807         use_class_as_object(c);
808
809         return (java_lang_Class *) c;
810 }
811
812
813 /*
814  * Class:     java/lang/Class
815  * Method:    isArray
816  * Signature: ()Z
817  */
818 JNIEXPORT s4 JNICALL Java_java_lang_VMClass_isArray(JNIEnv *env, jclass clazz, java_lang_Class *that)
819 {
820     classinfo *c = (classinfo *) that;
821
822     return c->vftbl->arraydesc != NULL;
823 }
824
825
826 /*
827  * Class:     java/lang/Class
828  * Method:    isAssignableFrom
829  * Signature: (Ljava/lang/Class;)Z
830  */
831 JNIEXPORT s4 JNICALL Java_java_lang_VMClass_isAssignableFrom(JNIEnv *env, jclass clazz, java_lang_Class *that, java_lang_Class *sup)
832 {
833         if (!sup) {
834                 *exceptionptr = new_nullpointerexception();
835                 return 0;
836         }
837
838         /* XXX this may be wrong for array classes */
839         return builtin_isanysubclass((classinfo*)sup, (classinfo*)that);
840
841 }
842
843
844 /*
845  * Class:     java/lang/Class
846  * Method:    isInstance
847  * Signature: (Ljava/lang/Object;)Z
848  */
849 JNIEXPORT s4 JNICALL Java_java_lang_VMClass_isInstance(JNIEnv *env, jclass clazz, java_lang_Class *that, java_lang_Object *obj)
850 {
851         return builtin_instanceof((java_objectheader*)obj, (classinfo*)that);
852 }
853
854
855 /*
856  * Class:     java/lang/Class
857  * Method:    isInterface
858  * Signature: ()Z
859  */
860 JNIEXPORT s4 JNICALL Java_java_lang_VMClass_isInterface(JNIEnv *env, jclass clazz, java_lang_Class *that)
861 {
862         classinfo *c = (classinfo *) that;
863
864         if (c->flags & ACC_INTERFACE)
865                 return true;
866
867         return false;
868 }
869
870
871 /*
872  * Class:     java/lang/Class
873  * Method:    isPrimitive
874  * Signature: ()Z
875  */
876 JNIEXPORT s4 JNICALL Java_java_lang_VMClass_isPrimitive(JNIEnv *env, jclass clazz, java_lang_Class *that)
877 {
878         int i;
879         classinfo *c = (classinfo *) that;
880
881         /* search table of primitive classes */
882         for (i = 0; i < PRIMITIVETYPE_COUNT; i++)
883                 if (primitivetype_table[i].class_primitive == c)
884                         return true;
885
886         return false;
887 }
888
889
890 /*
891  * Class:     java/lang/VMClass
892  * Method:    initialize
893  * Signature: ()V
894  */
895 JNIEXPORT void JNICALL Java_java_lang_VMClass_initialize(JNIEnv *env, jclass clazz, java_lang_Class *c)
896 {
897         classinfo *ci;
898
899         ci = (classinfo *) c;
900
901         /* initialize class */
902
903         if (!ci->initialized) {
904                 /* No need to check return value, because initialize_class already */
905                 /* sets the exception pointer. */
906                 (void) initialize_class(ci);
907         }
908 }
909
910
911 /*
912  * Class:     java/lang/VMClass
913  * Method:    loadArrayClass
914  * Signature: (Ljava/lang/String;Ljava/lang/ClassLoader;)Ljava/lang/Class;
915  */
916 JNIEXPORT java_lang_Class* JNICALL Java_java_lang_VMClass_loadArrayClass(JNIEnv *env, jclass clazz, java_lang_String *name, java_lang_ClassLoader *classloader)
917 {
918         classinfo *c;
919         utf       *u;
920
921         /* create utf string with `.' replaced by `/' */
922
923         u = javastring_toutf(name, true);
924
925         /* load the array class */
926
927         if (!load_class_from_classloader(u,(java_objectheader*)classloader,&c))
928                 return NULL;
929
930         use_class_as_object(c);
931
932         return (java_lang_Class *) c;
933 }
934
935
936 /*
937  * Class:     java/lang/VMClass
938  * Method:    throwException
939  * Signature: (Ljava/lang/Throwable;)V
940  */
941 JNIEXPORT void JNICALL Java_java_lang_VMClass_throwException(JNIEnv *env, jclass clazz, java_lang_Throwable *t)
942 {
943         *exceptionptr = (java_objectheader *) t;
944 }
945
946
947 /*
948  * These are local overrides for various environment variables in Emacs.
949  * Please do not remove this and leave it at the end of the file, where
950  * Emacs will automagically detect them.
951  * ---------------------------------------------------------------------
952  * Local variables:
953  * mode: c
954  * indent-tabs-mode: t
955  * c-basic-offset: 4
956  * tab-width: 4
957  * End:
958  */