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