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