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