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