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