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