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