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