Merged revisions 8123-8136 via svnmerge from
[cacao.git] / src / native / vm / java_lang_Class.c
1 /* src/native/vm/java_lang_Class.c - java/lang/Class
2
3    Copyright (C) 1996-2005, 2006, 2007 R. Grafl, A. Krall, C. Kruegel,
4    C. Oates, R. Obermaisser, M. Platter, M. Probst, S. Ring,
5    E. Steiner, C. Thalinger, D. Thuernbeck, P. Tomsich, C. Ullrich,
6    J. Wenninger, 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., 51 Franklin Street, Fifth Floor, Boston, MA
23    02110-1301, USA.
24
25    $Id: java_lang_Class.c 8137 2007-06-22 16:41:36Z michi $
26
27 */
28
29
30 #include "config.h"
31
32 #include <assert.h>
33 #include <string.h>
34
35 #include "vm/types.h"
36
37 #include "mm/memory.h"
38
39 #include "native/jni.h"
40 #include "native/native.h"
41
42 /* keep this order of the native includes */
43
44 #include "native/include/java_lang_String.h"
45
46 #if defined(ENABLE_JAVASE)
47 # if defined(WITH_CLASSPATH_SUN)
48 #  include "native/include/java_nio_ByteBuffer.h"       /* required by j.l.CL */
49 # endif
50 # include "native/include/java_lang_ClassLoader.h"
51 #endif
52
53 #include "native/include/java_lang_Object.h"
54 #include "native/include/java_lang_Class.h"
55
56 #if defined(ENABLE_JAVASE)
57 # include "native/include/java_lang_reflect_Constructor.h"
58 # include "native/include/java_lang_reflect_Field.h"
59 # include "native/include/java_lang_reflect_Method.h"
60 #endif
61
62 #include "native/vm/java_lang_Class.h"
63 #include "native/vm/java_lang_String.h"
64
65 #include "toolbox/logging.h"
66
67 #include "vm/builtin.h"
68 #include "vm/exceptions.h"
69 #include "vm/global.h"
70 #include "vm/initialize.h"
71 #include "vm/resolve.h"
72 #include "vm/stringlocal.h"
73
74 #include "vmcore/class.h"
75 #include "vmcore/loader.h"
76 #include "vmcore/primitive.h"
77
78
79 /*
80  * Class:     java/lang/Class
81  * Method:    getName
82  * Signature: ()Ljava/lang/String;
83  */
84 java_lang_String *_Jv_java_lang_Class_getName(java_lang_Class *klass)
85 {
86         classinfo        *c;
87         java_lang_String *s;
88         u4                i;
89
90         c = (classinfo *) klass;
91
92         /* create a java string */
93
94         s = (java_lang_String *) javastring_new(c->name);
95
96         if (s == NULL)
97                 return NULL;
98
99         /* return string where '/' is replaced by '.' */
100
101         for (i = 0; i < s->value->header.size; i++) {
102                 if (s->value->data[i] == '/')
103                         s->value->data[i] = '.';
104         }
105
106         return s;
107 }
108
109
110 /*
111  * Class:     java/lang/Class
112  * Method:    forName
113  * Signature: (Ljava/lang/String;ZLjava/lang/ClassLoader;)Ljava/lang/Class;
114  */
115 #if defined(ENABLE_JAVASE)
116 java_lang_Class *_Jv_java_lang_Class_forName(java_lang_String *name, s4 initialize, java_lang_ClassLoader *loader)
117 #elif defined(ENABLE_JAVAME_CLDC1_1)
118 java_lang_Class *_Jv_java_lang_Class_forName(java_lang_String *name)
119 #endif
120 {
121 #if defined(ENABLE_JAVASE)
122         classloader *cl;
123 #endif
124         utf               *ufile;
125         utf               *uname;
126         classinfo         *c;
127         u2                *pos;
128         s4                 i;
129
130 #if defined(ENABLE_JAVASE)
131         cl = loader_hashtable_classloader_add((java_objectheader *) loader);
132 #endif
133
134         /* illegal argument */
135
136         if (name == NULL) {
137                 exceptions_throw_nullpointerexception();
138                 return NULL;
139         }
140
141         /* create utf string in which '.' is replaced by '/' */
142
143         ufile = javastring_toutf((java_objectheader *) name, true);
144         uname = javastring_toutf((java_objectheader *) name, false);
145
146         /* name must not contain '/' (mauve test) */
147
148         for (i = 0, pos = name->value->data + name->offset; i < name->count; i++, pos++) {
149                 if (*pos == '/') {
150                         exceptions_throw_classnotfoundexception(uname);
151                         return NULL;
152                 }
153         }
154
155         /* try to load, ... */
156
157 #if defined(ENABLE_JAVASE)
158         c = load_class_from_classloader(ufile, cl);
159 #elif defined(ENABLE_JAVAME_CLDC1_1)
160         c = load_class_bootstrap(ufile);
161 #endif
162
163         if (c == NULL)
164             return NULL;
165
166         /* link, ... */
167
168         if (!link_class(c))
169                 return NULL;
170         
171         /* ...and initialize it, if required */
172
173 #if defined(ENABLE_JAVASE)
174         if (initialize)
175 #endif
176                 if (!initialize_class(c))
177                         return NULL;
178
179         return (java_lang_Class *) c;
180 }
181
182
183 /*
184  * Class:     java/lang/Class
185  * Method:    isInstance
186  * Signature: (Ljava/lang/Object;)Z
187  */
188 s4 _Jv_java_lang_Class_isInstance(java_lang_Class *klass, java_lang_Object *o)
189 {
190         classinfo         *c;
191         java_objectheader *ob;
192
193         c = (classinfo *) klass;
194         ob = (java_objectheader *) o;
195
196         if (!(c->state & CLASS_LINKED))
197                 if (!link_class(c))
198                         return 0;
199
200         return builtin_instanceof(ob, c);
201 }
202
203
204 /*
205  * Class:     java/lang/Class
206  * Method:    isAssignableFrom
207  * Signature: (Ljava/lang/Class;)Z
208  */
209 s4 _Jv_java_lang_Class_isAssignableFrom(java_lang_Class *klass, java_lang_Class *c)
210 {
211         classinfo *kc;
212         classinfo *cc;
213
214         kc = (classinfo *) klass;
215         cc = (classinfo *) c;
216
217         if (cc == NULL) {
218                 exceptions_throw_nullpointerexception();
219                 return 0;
220         }
221
222         if (!(kc->state & CLASS_LINKED))
223                 if (!link_class(kc))
224                         return 0;
225
226         if (!(cc->state & CLASS_LINKED))
227                 if (!link_class(cc))
228                         return 0;
229
230         return class_isanysubclass(cc, kc);
231 }
232
233
234 /*
235  * Class:     java/lang/Class
236  * Method:    isInterface
237  * Signature: ()Z
238  */
239 s4 _Jv_java_lang_Class_isInterface(java_lang_Class *klass)
240 {
241         classinfo *c;
242
243         c = (classinfo *) klass;
244
245         if (c->flags & ACC_INTERFACE)
246                 return true;
247
248         return false;
249 }
250
251
252 #if defined(ENABLE_JAVASE)
253
254 /*
255  * Class:     java/lang/Class
256  * Method:    isPrimitive
257  * Signature: ()Z
258  */
259 s4 _Jv_java_lang_Class_isPrimitive(java_lang_Class *klass)
260 {
261         classinfo *c;
262         bool       result;
263
264         c = (classinfo *) klass;
265
266         result = primitive_class_is_primitive(c);
267
268         return result;
269 }
270
271
272 /*
273  * Class:     java/lang/Class
274  * Method:    getSuperclass
275  * Signature: ()Ljava/lang/Class;
276  */
277 java_lang_Class *_Jv_java_lang_Class_getSuperclass(java_lang_Class *klass)
278 {
279         classinfo *c;
280         classinfo *sc;
281
282         c = (classinfo *) klass;
283
284         /* for java.lang.Object, primitive and Void classes we return NULL */
285
286         if (!c->super.any)
287                 return NULL;
288
289         /* for interfaces we also return NULL */
290
291         if (c->flags & ACC_INTERFACE)
292                 return NULL;
293
294         /* we may have to resolve the super class reference */
295
296         if ((sc = resolve_classref_or_classinfo_eager(c->super, true)) == NULL)
297                 return NULL;
298
299         /* store the resolution */
300
301         c->super.cls = sc;
302
303         return (java_lang_Class *) sc;
304 }
305
306
307 /*
308  * Class:     java/lang/Class
309  * Method:    getInterfaces
310  * Signature: ()[Ljava/lang/Class;
311  */
312 java_objectarray *_Jv_java_lang_Class_getInterfaces(java_lang_Class *klass)
313 {
314         classinfo        *c;
315         classinfo        *ic;
316         java_objectarray *oa;
317         u4                i;
318
319         c = (classinfo *) klass;
320
321         if (!(c->state & CLASS_LINKED))
322                 if (!link_class(c))
323                         return NULL;
324
325         oa = builtin_anewarray(c->interfacescount, class_java_lang_Class);
326
327         if (oa == NULL)
328                 return NULL;
329
330         for (i = 0; i < c->interfacescount; i++) {
331                 ic = c->interfaces[i].cls;
332
333                 oa->data[i] = (java_objectheader *) ic;
334         }
335
336         return oa;
337 }
338
339
340 /*
341  * Class:     java/lang/Class
342  * Method:    getComponentType
343  * Signature: ()Ljava/lang/Class;
344  */
345 java_lang_Class *_Jv_java_lang_Class_getComponentType(java_lang_Class *klass)
346 {
347         classinfo       *c;
348         classinfo       *comp;
349         arraydescriptor *desc;
350         
351         c = (classinfo *) klass;
352         
353         /* XXX maybe we could find a way to do this without linking. */
354         /* This way should be safe and easy, however.                */
355
356         if (!(c->state & CLASS_LINKED))
357                 if (!link_class(c))
358                         return NULL;
359
360         desc = c->vftbl->arraydesc;
361         
362         if (desc == NULL)
363                 return NULL;
364         
365         if (desc->arraytype == ARRAYTYPE_OBJECT)
366                 comp = desc->componentvftbl->class;
367         else
368                 comp = primitive_class_get_by_type(desc->arraytype);
369                 
370         return (java_lang_Class *) comp;
371 }
372
373
374 /*
375  * Class:     java/lang/Class
376  * Method:    getModifiers
377  * Signature: (Z)I
378  */
379 s4 _Jv_java_lang_Class_getModifiers(java_lang_Class *klass, s4 ignoreInnerClassesAttrib)
380 {
381         classinfo             *c;
382         classref_or_classinfo  inner;
383         classref_or_classinfo  outer;
384         utf                   *innername;
385         s4                     i;
386
387         c = (classinfo *) klass;
388
389         if (!ignoreInnerClassesAttrib && (c->innerclasscount != 0)) {
390                 /* search for passed class as inner class */
391
392                 for (i = 0; i < c->innerclasscount; i++) {
393                         inner = c->innerclass[i].inner_class;
394                         outer = c->innerclass[i].outer_class;
395
396                         /* Check if inner is a classref or a real class and get
397                the name of the structure */
398
399                         innername = IS_CLASSREF(inner) ? inner.ref->name : inner.cls->name;
400
401                         /* innerclass is this class */
402
403                         if (innername == c->name) {
404                                 /* has the class actually an outer class? */
405
406                                 if (outer.any)
407                                         /* return flags got from the outer class file */
408                                         return c->innerclass[i].flags & ACC_CLASS_REFLECT_MASK;
409                                 else
410                                         return c->flags & ACC_CLASS_REFLECT_MASK;
411                         }
412                 }
413         }
414
415         /* passed class is no inner class or it was not requested */
416
417         return c->flags & ACC_CLASS_REFLECT_MASK;
418 }
419
420
421 /*
422  * Class:     java/lang/Class
423  * Method:    getDeclaringClass
424  * Signature: ()Ljava/lang/Class;
425  */
426 java_lang_Class *_Jv_java_lang_Class_getDeclaringClass(java_lang_Class *klass)
427 {
428         classinfo             *c;
429         classref_or_classinfo  inner;
430         utf                   *innername;
431         classinfo             *outer;
432         s4                     i;
433
434         c = (classinfo *) klass;
435
436         if (!primitive_class_is_primitive(c) && (c->name->text[0] != '[')) {
437                 if (c->innerclasscount == 0)  /* no innerclasses exist */
438                         return NULL;
439     
440                 for (i = 0; i < c->innerclasscount; i++) {
441                         inner = c->innerclass[i].inner_class;
442
443                         /* check if inner_class is a classref or a real class and
444                get the class name from the structure */
445
446                         innername = IS_CLASSREF(inner) ? inner.ref->name : inner.cls->name;
447
448                         /* innerclass is this class */
449
450                         if (innername == c->name) {
451                                 /* maybe the outer class is not loaded yet */
452
453                                 if ((outer = resolve_classref_or_classinfo_eager(
454                                                                 c->innerclass[i].outer_class,
455                                                                 false)) == NULL)
456                                         return NULL;
457
458                                 if (!(outer->state & CLASS_LINKED))
459                                         if (!link_class(outer))
460                                                 return NULL;
461
462                                 return (java_lang_Class *) outer;
463                         }
464                 }
465         }
466
467         /* return NULL for arrayclasses and primitive classes */
468
469         return NULL;
470 }
471
472
473 /*
474  * Class:     java/lang/Class
475  * Method:    getDeclaredClasses
476  * Signature: (Z)[Ljava/lang/Class;
477  */
478 java_objectarray *_Jv_java_lang_Class_getDeclaredClasses(java_lang_Class *klass, s4 publicOnly)
479 {
480         classinfo             *c;
481         classref_or_classinfo  outer;
482         utf                   *outername;
483         s4                     declaredclasscount;  /* number of declared classes */
484         s4                     pos;                     /* current declared class */
485         java_objectarray      *oa;                   /* array of declared classes */
486         s4                     i;
487
488         c = (classinfo *) klass;
489         declaredclasscount = 0;
490
491         if (!primitive_class_is_primitive(c) && (c->name->text[0] != '[')) {
492                 /* determine number of declared classes */
493
494                 for (i = 0; i < c->innerclasscount; i++) {
495                         outer = c->innerclass[i].outer_class;
496
497                         /* check if outer_class is a classref or a real class and
498                get the class name from the structure */
499
500                         outername = IS_CLASSREF(outer) ? outer.ref->name : outer.cls->name;
501
502                         /* outer class is this class */
503
504                         if ((outername == c->name) &&
505                                 ((publicOnly == 0) || (c->innerclass[i].flags & ACC_PUBLIC)))
506                                 declaredclasscount++;
507                 }
508         }
509
510         /* allocate Class[] and check for OOM */
511
512         oa = builtin_anewarray(declaredclasscount, class_java_lang_Class);
513
514         if (oa == NULL)
515                 return NULL;
516
517         for (i = 0, pos = 0; i < c->innerclasscount; i++) {
518                 outer = c->innerclass[i].outer_class;
519
520                 /* check if outer_class is a classref or a real class and
521                    get the class name from the structure */
522
523                 outername = IS_CLASSREF(outer) ? outer.ref->name : outer.cls->name;
524
525                 /* outer class is this class */
526
527                 if ((outername == c->name) &&
528                         ((publicOnly == 0) || (c->innerclass[i].flags & ACC_PUBLIC))) {
529                         classinfo *inner;
530
531                         if ((inner = resolve_classref_or_classinfo_eager(
532                                                                                            c->innerclass[i].inner_class,
533                                                                                            false)) == NULL)
534                                 return NULL;
535
536                         if (!(inner->state & CLASS_LINKED))
537                                 if (!link_class(inner))
538                                         return NULL;
539
540                         oa->data[pos++] = (java_objectheader *) inner;
541                 }
542         }
543
544         return oa;
545 }
546
547
548 /*
549  * Class:     java/lang/Class
550  * Method:    getDeclaredFields
551  * Signature: (Z)[Ljava/lang/reflect/Field;
552  */
553 java_objectarray *_Jv_java_lang_Class_getDeclaredFields(java_lang_Class *klass, s4 publicOnly)
554 {
555         classinfo               *c;
556         java_objectarray        *oa;            /* result: array of field-objects */
557         fieldinfo               *f;
558         java_objectheader       *o;
559         java_lang_reflect_Field *rf;
560         s4 public_fields;                    /* number of elements in field-array */
561         s4 pos;
562         s4 i;
563
564         c = (classinfo *) klass;
565
566         /* determine number of fields */
567
568         for (i = 0, public_fields = 0; i < c->fieldscount; i++)
569                 if ((c->fields[i].flags & ACC_PUBLIC) || (publicOnly == 0))
570                         public_fields++;
571
572         /* create array of fields */
573
574         oa = builtin_anewarray(public_fields, class_java_lang_reflect_Field);
575
576         if (oa == NULL)
577                 return NULL;
578
579         /* get the fields and store in the array */
580
581         for (i = 0, pos = 0; i < c->fieldscount; i++) {
582                 f = &(c->fields[i]);
583
584                 if ((f->flags & ACC_PUBLIC) || (publicOnly == 0)) {
585                         /* create Field object */
586
587                         o = native_new_and_init(class_java_lang_reflect_Field);
588
589                         if (o == NULL)
590                                 return NULL;
591
592                         /* initialize instance fields */
593
594                         rf = (java_lang_reflect_Field *) o;
595
596 #if defined(WITH_CLASSPATH_GNU)
597
598                         rf->clazz = (java_lang_Class *) c;
599
600                         /* The name needs to be interned */
601                         /* XXX implement me better! */
602
603                         rf->name           = _Jv_java_lang_String_intern((java_lang_String *) javastring_new(f->name));
604                         rf->slot           = i;
605
606 #elif defined(WITH_CLASSPATH_SUN)
607
608                         rf->clazz          = (java_lang_Class *) c;
609
610                         /* The name needs to be interned */
611                         /* XXX implement me better! */
612
613                         rf->name           = _Jv_java_lang_String_intern((java_lang_String *) javastring_new(f->name));
614                         rf->type           = (java_lang_Class *) field_get_type(f);
615                         rf->modifiers      = f->flags;
616                         rf->slot           = i;
617                         rf->signature      = f->signature ? (java_lang_String *) javastring_new(f->signature) : NULL;
618                         rf->annotations    = NULL;
619 #else
620 # error unknown classpath configuration
621 #endif
622
623                         /* store object into array */
624
625                         oa->data[pos++] = o;
626                 }
627         }
628
629         return oa;
630 }
631
632
633 /*
634  * Class:     java/lang/Class
635  * Method:    getDeclaredMethods
636  * Signature: (Z)[Ljava/lang/reflect/Method;
637  */
638 java_objectarray *_Jv_java_lang_Class_getDeclaredMethods(java_lang_Class *klass, s4 publicOnly)
639 {
640         classinfo                *c;
641         java_objectheader        *o;
642         java_lang_reflect_Method *rm;
643         java_objectarray         *oa;          /* result: array of Method-objects */
644         methodinfo               *m;      /* the current method to be represented */
645         s4 public_methods;               /* number of public methods of the class */
646         s4 pos;
647         s4 i;
648
649         c = (classinfo *) klass;    
650         public_methods = 0;
651
652         /* JOWENN: array classes do not declare methods according to mauve
653            test.  It should be considered, if we should return to my old
654            clone method overriding instead of declaring it as a member
655            function. */
656
657         if (_Jv_java_lang_Class_isArray(klass))
658                 return builtin_anewarray(0, class_java_lang_reflect_Method);
659
660         /* determine number of methods */
661
662         for (i = 0; i < c->methodscount; i++) {
663                 m = &c->methods[i];
664
665                 if (((m->flags & ACC_PUBLIC) || (publicOnly == false)) &&
666                         ((m->name != utf_init) && (m->name != utf_clinit)) &&
667                         !(m->flags & ACC_MIRANDA))
668                         public_methods++;
669         }
670
671         oa = builtin_anewarray(public_methods, class_java_lang_reflect_Method);
672
673         if (oa == NULL)
674                 return NULL;
675
676         for (i = 0, pos = 0; i < c->methodscount; i++) {
677                 m = &c->methods[i];
678
679                 if (((m->flags & ACC_PUBLIC) || (publicOnly == false)) && 
680                         ((m->name != utf_init) && (m->name != utf_clinit)) &&
681                         !(m->flags & ACC_MIRANDA)) {
682
683                         o = native_new_and_init(class_java_lang_reflect_Method);
684
685                         if (o == NULL)
686                                 return NULL;
687
688                         /* initialize instance fields */
689
690                         rm = (java_lang_reflect_Method *) o;
691
692 #if defined(WITH_CLASSPATH_GNU)
693
694                         rm->clazz       = (java_lang_Class *) m->class;
695
696                         /* The name needs to be interned */
697                         /* XXX implement me better! */
698
699                         rm->name                 = _Jv_java_lang_String_intern((java_lang_String *) javastring_new(m->name));
700                         rm->slot                 = i;
701
702 #elif defined(WITH_CLASSPATH_SUN)
703
704                         rm->clazz                = (java_lang_Class *) m->class;
705
706                         /* The name needs to be interned */
707                         /* XXX implement me better! */
708
709                         rm->name                 = _Jv_java_lang_String_intern((java_lang_String *) javastring_new(m->name));
710                         rm->parameterTypes       = method_get_parametertypearray(m);
711                         rm->returnType           = (java_lang_Class *) method_returntype_get(m);
712                         rm->exceptionTypes       = method_get_exceptionarray(m);
713                         rm->modifiers            = m->flags & ACC_CLASS_REFLECT_MASK;
714                         rm->slot                 = i;
715                         rm->signature            = m->signature ? (java_lang_String *) javastring_new(m->signature) : NULL;
716                         rm->annotations          = NULL;
717                         rm->parameterAnnotations = NULL;
718                         rm->annotationDefault    = NULL;
719
720 #else
721 # error unknown classpath configuration
722 #endif
723
724                         /* store object into array */
725
726                         oa->data[pos++] = o;
727                 }
728         }
729
730         return oa;
731 }
732
733
734 /*
735  * Class:     java/lang/Class
736  * Method:    getDeclaredConstructors
737  * Signature: (Z)[Ljava/lang/reflect/Constructor;
738  */
739 java_objectarray *_Jv_java_lang_Class_getDeclaredConstructors(java_lang_Class *klass, s4 publicOnly)
740 {
741         classinfo                     *c;
742         methodinfo                    *m; /* the current method to be represented */
743         java_objectarray              *oa;     /* result: array of Method-objects */
744         java_objectheader             *o;
745         java_lang_reflect_Constructor *rc;
746         s4 public_methods;               /* number of public methods of the class */
747         s4 pos;
748         s4 i;
749
750         c = (classinfo *) klass;
751
752         /* determine number of constructors */
753
754         for (i = 0, public_methods = 0; i < c->methodscount; i++) {
755                 m = &c->methods[i];
756
757                 if (((m->flags & ACC_PUBLIC) || (publicOnly == 0)) &&
758                         (m->name == utf_init))
759                         public_methods++;
760         }
761
762         oa = builtin_anewarray(public_methods, class_java_lang_reflect_Constructor);
763
764         if (oa == NULL)
765                 return NULL;
766
767         for (i = 0, pos = 0; i < c->methodscount; i++) {
768                 m = &c->methods[i];
769
770                 if (((m->flags & ACC_PUBLIC) || (publicOnly == 0)) &&
771                         (m->name == utf_init)) {
772
773                         o = native_new_and_init(class_java_lang_reflect_Constructor);
774
775                         if (o == NULL)
776                                 return NULL;
777
778                         /* initialize instance fields */
779
780                         rc = (java_lang_reflect_Constructor *) o;
781
782 #if defined(WITH_CLASSPATH_GNU)
783
784                         rc->clazz                = (java_lang_Class *) c;
785                         rc->slot                 = i;
786
787 #elif defined(WITH_CLASSPATH_SUN)
788
789                         rc->clazz                = (java_lang_Class *) c;
790                         rc->parameterTypes       = method_get_parametertypearray(m);
791                         rc->exceptionTypes       = method_get_exceptionarray(m);
792                         rc->modifiers            = m->flags & ACC_CLASS_REFLECT_MASK;
793                         rc->slot                 = i;
794                         rc->signature            = m->signature ? (java_lang_String *) javastring_new(m->signature) : NULL;
795                         rc->annotations          = NULL;
796                         rc->parameterAnnotations = NULL;
797
798 #else
799 # error unknown classpath configuration
800 #endif
801
802                         /* store object into array */
803
804                         oa->data[pos++] = o;
805                 }
806         }
807
808         return oa;
809 }
810
811
812 /*
813  * Class:     java/lang/Class
814  * Method:    getClassLoader
815  * Signature: ()Ljava/lang/ClassLoader;
816  */
817 java_lang_ClassLoader *_Jv_java_lang_Class_getClassLoader(java_lang_Class *klass)
818 {
819         classinfo *c;
820
821         c = (classinfo *) klass;
822
823         if (c->classloader == NULL)
824                 return NULL;
825         else
826                 return (java_lang_ClassLoader *) c->classloader->object;
827 }
828
829 #endif /* defined(ENABLE_JAVASE) */
830
831
832 /*
833  * Class:     java/lang/Class
834  * Method:    isArray
835  * Signature: ()Z
836  */
837 s4 _Jv_java_lang_Class_isArray(java_lang_Class *klass)
838 {
839         classinfo *c;
840
841         c = (classinfo *) klass;
842
843         if (!(c->state & CLASS_LINKED))
844                 if (!link_class(c))
845                         return 0;
846
847         return (c->vftbl->arraydesc != NULL);
848 }
849
850
851 #if defined(ENABLE_JAVASE)
852
853 /*
854  * Class:     java/lang/Class
855  * Method:    throwException
856  * Signature: (Ljava/lang/Throwable;)V
857  */
858 void _Jv_java_lang_Class_throwException(java_lang_Throwable *t)
859 {
860         java_objectheader *o;
861
862         o = (java_objectheader *) t;
863
864         exceptions_set_exception(o);
865 }
866
867
868 #if 0
869 /*
870  * Class:     java/lang/Class
871  * Method:    getDeclaredAnnotations
872  * Signature: (Ljava/lang/Class;)[Ljava/lang/annotation/Annotation;
873  */
874 java_objectarray *_Jv_java_lang_Class_getDeclaredAnnotations(java_lang_Class* klass)
875 {
876 }
877 #endif
878
879
880 /*
881  * Class:     java/lang/Class
882  * Method:    getEnclosingClass
883  * Signature: (Ljava/lang/Class;)Ljava/lang/Class;
884  */
885 java_lang_Class *_Jv_java_lang_Class_getEnclosingClass(java_lang_Class *klass)
886 {
887         classinfo             *c;
888         classref_or_classinfo  cr;
889         classinfo             *ec;
890
891         c = (classinfo *) klass;
892
893         /* get enclosing class */
894
895         cr = c->enclosingclass;
896
897         if (cr.any == NULL)
898                 return NULL;
899
900         /* resolve the class if necessary */
901
902         if (IS_CLASSREF(cr)) {
903                 ec = resolve_classref_eager(cr.ref);
904
905                 if (ec == NULL)
906                         return NULL;
907         }
908         else
909                 ec = cr.cls;
910
911         return (java_lang_Class *) ec;
912 }
913
914
915 /* _Jv_java_lang_Class_getEnclosingMethod_intern *******************************
916
917    Helper function for _Jv_java_lang_Class_getEnclosingConstructor and
918    _Jv_java_lang_Class_getEnclosingMethod.
919
920 *******************************************************************************/
921
922 static methodinfo *_Jv_java_lang_Class_getEnclosingMethod_intern(classinfo *c)
923 {
924         classref_or_classinfo     cr;
925         constant_nameandtype     *cn;
926         classinfo                *ec;
927         methodinfo               *m;
928
929         /* get enclosing class and method */
930
931         cr = c->enclosingclass;
932         cn = c->enclosingmethod;
933
934         /* check for enclosing class and method */
935
936         if (cr.any == NULL)
937                 return NULL;
938
939         if (cn == NULL)
940                 return NULL;
941
942         /* resolve the class if necessary */
943
944         if (IS_CLASSREF(cr)) {
945                 ec = resolve_classref_eager(cr.ref);
946
947                 if (ec == NULL)
948                         return NULL;
949         }
950         else
951                 ec = cr.cls;
952
953         /* find method in enclosing class */
954
955         m = class_findmethod(ec, cn->name, cn->descriptor);
956
957         if (m == NULL) {
958                 exceptions_throw_internalerror("Enclosing method doesn't exist");
959                 return NULL;
960         }
961
962         return m;
963 }
964
965
966 /*
967  * Class:     java/lang/Class
968  * Method:    getEnclosingConstructor
969  * Signature: (Ljava/lang/Class;)Ljava/lang/reflect/Constructor;
970  */
971 java_lang_reflect_Constructor *_Jv_java_lang_Class_getEnclosingConstructor(java_lang_Class *klass)
972 {
973         classinfo                     *c;
974         methodinfo                    *m;
975         java_objectheader             *o;
976         java_lang_reflect_Constructor *rc;
977
978         c = (classinfo *) klass;
979
980         /* get enclosing method */
981
982         m = _Jv_java_lang_Class_getEnclosingMethod_intern(c);
983
984         if (m == NULL)
985                 return NULL;
986
987         /* check for <init> */
988
989         if (m->name != utf_init)
990                 return NULL;
991
992         /* create java.lang.reflect.Constructor object */
993
994         o = native_new_and_init(class_java_lang_reflect_Constructor);
995
996         if (o == NULL)
997                 return NULL;
998
999         /* initialize instance fields */
1000
1001         rc = (java_lang_reflect_Constructor *) o;
1002
1003         rc->clazz = (java_lang_Class *) m->class;
1004         rc->slot  = m - m->class->methods;               /* calculate method slot */
1005
1006         return rc;
1007 }
1008
1009
1010 /*
1011  * Class:     java/lang/Class
1012  * Method:    getEnclosingMethod
1013  * Signature: (Ljava/lang/Class;)Ljava/lang/reflect/Method;
1014  */
1015 java_lang_reflect_Method *_Jv_java_lang_Class_getEnclosingMethod(java_lang_Class *klass)
1016 {
1017         classinfo                *c;
1018         methodinfo               *m;
1019         java_objectheader        *o;
1020         java_lang_reflect_Method *rm;
1021
1022         c = (classinfo *) klass;
1023
1024         /* get enclosing method */
1025
1026         m = _Jv_java_lang_Class_getEnclosingMethod_intern(c);
1027
1028         if (m == NULL)
1029                 return NULL;
1030
1031         /* check for <init> */
1032
1033         if (m->name == utf_init)
1034                 return NULL;
1035
1036         /* create java.lang.reflect.Method object */
1037
1038         o = native_new_and_init(class_java_lang_reflect_Method);
1039
1040         if (o == NULL)
1041                 return NULL;
1042
1043         /* initialize instance fields */
1044
1045         rm = (java_lang_reflect_Method *) o;
1046
1047 #if defined(WITH_CLASSPATH_GNU)
1048         rm->clazz          = (java_lang_Class *) m->class;
1049 #elif defined(WITH_CLASSPATH_SUN)
1050         rm->clazz          = (java_lang_Class *) m->class;
1051 #else
1052 # error unknown classpath configuration
1053 #endif
1054
1055         rm->name           = (java_lang_String *) javastring_new(m->name);
1056         rm->slot           = m - m->class->methods;      /* calculate method slot */
1057
1058         return rm;
1059 }
1060
1061
1062 /*
1063  * Class:     java/lang/Class
1064  * Method:    getClassSignature
1065  * Signature: (Ljava/lang/Class;)Ljava/lang/String;
1066  */
1067 java_lang_String *_Jv_java_lang_Class_getClassSignature(java_lang_Class* klass)
1068 {
1069         classinfo         *c;
1070         java_objectheader *o;
1071
1072         c = (classinfo *) klass;
1073
1074         if (c->signature == NULL)
1075                 return NULL;
1076
1077         o = javastring_new(c->signature);
1078
1079         /* in error case o is NULL */
1080
1081         return (java_lang_String *) o;
1082 }
1083
1084
1085 #if 0
1086 /*
1087  * Class:     java/lang/Class
1088  * Method:    isAnonymousClass
1089  * Signature: (Ljava/lang/Class;)Z
1090  */
1091 s4 _Jv_java_lang_Class_isAnonymousClass(JNIEnv *env, jclass clazz, struct java_lang_Class* par1);
1092
1093
1094 /*
1095  * Class:     java/lang/VMClass
1096  * Method:    isLocalClass
1097  * Signature: (Ljava/lang/Class;)Z
1098  */
1099 JNIEXPORT s4 JNICALL Java_java_lang_VMClass_isLocalClass(JNIEnv *env, jclass clazz, struct java_lang_Class* par1);
1100
1101
1102 /*
1103  * Class:     java/lang/VMClass
1104  * Method:    isMemberClass
1105  * Signature: (Ljava/lang/Class;)Z
1106  */
1107 JNIEXPORT s4 JNICALL Java_java_lang_VMClass_isMemberClass(JNIEnv *env, jclass clazz, struct java_lang_Class* par1);
1108 #endif
1109
1110 #endif /* ENABLE_JAVASE */
1111
1112
1113 /*
1114  * These are local overrides for various environment variables in Emacs.
1115  * Please do not remove this and leave it at the end of the file, where
1116  * Emacs will automagically detect them.
1117  * ---------------------------------------------------------------------
1118  * Local variables:
1119  * mode: c
1120  * indent-tabs-mode: t
1121  * c-basic-offset: 4
1122  * tab-width: 4
1123  * End:
1124  * vim:noexpandtab:sw=4:ts=4:
1125  */