b644d609d2ab996a16aaef7afae8a80e44c92e5f
[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 8305 2007-08-15 13:49:26Z panzi $
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         classloader *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 = (classloader *) 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_handle_t *) name, true);
157         uname = javastring_toutf((java_handle_t *) 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_handle_t *ob;
205
206         c = (classinfo *) klass;
207         ob = (java_handle_t *) 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] = 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++] = 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++] = 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++] = 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++] = 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_handle_t *o;
707
708         o = (java_handle_t *) 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         java_lang_Object         *o            = (java_lang_Object*)klass;
730
731         if (c == NULL) {
732                 exceptions_throw_nullpointerexception();
733                 return NULL;
734         }
735         
736         /* Return null for arrays and primitives: */
737         if (class_is_primitive(c) || class_is_array(c)) {
738                 return NULL;
739         }
740
741         if (c->annotations != NULL) {
742                 size        = c->annotations->size;
743                 annotations = builtin_newarray_byte(size);
744
745                 if(annotations != NULL) {
746                         MCOPY(annotations->data, c->annotations->data, uint8_t, size);
747                 }
748         }
749
750         constantPool = 
751                 (sun_reflect_ConstantPool*)native_new_and_init(
752                         class_sun_reflect_ConstantPool);
753         
754         if(constantPool == NULL) {
755                 /* out of memory */
756                 return NULL;
757         }
758
759         LLNI_field_set_ref(constantPool, constantPoolOop, o);
760
761         /* only resolve the method the first time */
762         if (m_parseAnnotationsIntoArray == NULL) {
763                 utf_parseAnnotationsIntoArray = utf_new_char("parseAnnotationsIntoArray");
764                 utf_desc = utf_new_char(
765                         "([BLsun/reflect/ConstantPool;Ljava/lang/Class;)"
766                         "[Ljava/lang/annotation/Annotation;");
767
768                 if (utf_parseAnnotationsIntoArray == NULL || utf_desc == NULL) {
769                         /* out of memory */
770                         return NULL;
771                 }
772
773                 m_parseAnnotationsIntoArray = class_resolveclassmethod(
774                         class_sun_reflect_annotation_AnnotationParser,
775                         utf_parseAnnotationsIntoArray,
776                         utf_desc,
777                         class_java_lang_Class,
778                         true);
779
780                 if (m_parseAnnotationsIntoArray == NULL) {
781                         /* method not found */
782                         return NULL;
783                 }
784         }
785
786         return vm_call_method(
787                 m_parseAnnotationsIntoArray, NULL,
788                 annotations, constantPool, klass);
789 }
790 #endif
791
792
793 /*
794  * Class:     java/lang/Class
795  * Method:    getEnclosingClass
796  * Signature: (Ljava/lang/Class;)Ljava/lang/Class;
797  */
798 java_lang_Class *_Jv_java_lang_Class_getEnclosingClass(java_lang_Class *klass)
799 {
800         classinfo             *c;
801         classref_or_classinfo  cr;
802         classinfo             *ec;
803
804         c = (classinfo *) klass;
805
806         /* get enclosing class */
807
808         cr = c->enclosingclass;
809
810         if (cr.any == NULL)
811                 return NULL;
812
813         /* resolve the class if necessary */
814
815         if (IS_CLASSREF(cr)) {
816                 ec = resolve_classref_eager(cr.ref);
817
818                 if (ec == NULL)
819                         return NULL;
820         }
821         else
822                 ec = cr.cls;
823
824         return (java_lang_Class *) ec;
825 }
826
827
828 /* _Jv_java_lang_Class_getEnclosingMethod_intern *******************************
829
830    Helper function for _Jv_java_lang_Class_getEnclosingConstructor and
831    _Jv_java_lang_Class_getEnclosingMethod.
832
833 *******************************************************************************/
834
835 static methodinfo *_Jv_java_lang_Class_getEnclosingMethod_intern(classinfo *c)
836 {
837         classref_or_classinfo     cr;
838         constant_nameandtype     *cn;
839         classinfo                *ec;
840         methodinfo               *m;
841
842         /* get enclosing class and method */
843
844         cr = c->enclosingclass;
845         cn = c->enclosingmethod;
846
847         /* check for enclosing class and method */
848
849         if (cr.any == NULL)
850                 return NULL;
851
852         if (cn == NULL)
853                 return NULL;
854
855         /* resolve the class if necessary */
856
857         if (IS_CLASSREF(cr)) {
858                 ec = resolve_classref_eager(cr.ref);
859
860                 if (ec == NULL)
861                         return NULL;
862         }
863         else
864                 ec = cr.cls;
865
866         /* find method in enclosing class */
867
868         m = class_findmethod(ec, cn->name, cn->descriptor);
869
870         if (m == NULL) {
871                 exceptions_throw_internalerror("Enclosing method doesn't exist");
872                 return NULL;
873         }
874
875         return m;
876 }
877
878
879 /*
880  * Class:     java/lang/Class
881  * Method:    getEnclosingConstructor
882  * Signature: (Ljava/lang/Class;)Ljava/lang/reflect/Constructor;
883  */
884 java_lang_reflect_Constructor *_Jv_java_lang_Class_getEnclosingConstructor(java_lang_Class *klass)
885 {
886         classinfo                     *c;
887         methodinfo                    *m;
888         java_lang_reflect_Constructor *rc;
889
890         c = (classinfo *) klass;
891
892         /* get enclosing method */
893
894         m = _Jv_java_lang_Class_getEnclosingMethod_intern(c);
895
896         if (m == NULL)
897                 return NULL;
898
899         /* check for <init> */
900
901         if (m->name != utf_init)
902                 return NULL;
903
904         /* create Constructor object */
905
906         rc = reflect_constructor_new(m);
907
908         return rc;
909 }
910
911
912 /*
913  * Class:     java/lang/Class
914  * Method:    getEnclosingMethod
915  * Signature: (Ljava/lang/Class;)Ljava/lang/reflect/Method;
916  */
917 java_lang_reflect_Method *_Jv_java_lang_Class_getEnclosingMethod(java_lang_Class *klass)
918 {
919         classinfo                *c;
920         methodinfo               *m;
921         java_lang_reflect_Method *rm;
922
923         c = (classinfo *) klass;
924
925         /* get enclosing method */
926
927         m = _Jv_java_lang_Class_getEnclosingMethod_intern(c);
928
929         if (m == NULL)
930                 return NULL;
931
932         /* check for <init> */
933
934         if (m->name == utf_init)
935                 return NULL;
936
937         /* create java.lang.reflect.Method object */
938
939         rm = reflect_method_new(m);
940
941         return rm;
942 }
943
944
945 /*
946  * Class:     java/lang/Class
947  * Method:    getClassSignature
948  * Signature: (Ljava/lang/Class;)Ljava/lang/String;
949  */
950 java_lang_String *_Jv_java_lang_Class_getClassSignature(java_lang_Class* klass)
951 {
952         classinfo     *c;
953         java_handle_t *o;
954
955         c = (classinfo *) klass;
956
957         if (c->signature == NULL)
958                 return NULL;
959
960         o = javastring_new(c->signature);
961
962         /* in error case o is NULL */
963
964         return (java_lang_String *) o;
965 }
966
967
968 #if 0
969 /*
970  * Class:     java/lang/Class
971  * Method:    isAnonymousClass
972  * Signature: (Ljava/lang/Class;)Z
973  */
974 s4 _Jv_java_lang_Class_isAnonymousClass(JNIEnv *env, jclass clazz, struct java_lang_Class* par1);
975
976
977 /*
978  * Class:     java/lang/VMClass
979  * Method:    isLocalClass
980  * Signature: (Ljava/lang/Class;)Z
981  */
982 JNIEXPORT s4 JNICALL Java_java_lang_VMClass_isLocalClass(JNIEnv *env, jclass clazz, struct java_lang_Class* par1);
983
984
985 /*
986  * Class:     java/lang/VMClass
987  * Method:    isMemberClass
988  * Signature: (Ljava/lang/Class;)Z
989  */
990 JNIEXPORT s4 JNICALL Java_java_lang_VMClass_isMemberClass(JNIEnv *env, jclass clazz, struct java_lang_Class* par1);
991 #endif
992
993 #endif /* ENABLE_JAVASE */
994
995
996 /*
997  * These are local overrides for various environment variables in Emacs.
998  * Please do not remove this and leave it at the end of the file, where
999  * Emacs will automagically detect them.
1000  * ---------------------------------------------------------------------
1001  * Local variables:
1002  * mode: c
1003  * indent-tabs-mode: t
1004  * c-basic-offset: 4
1005  * tab-width: 4
1006  * End:
1007  * vim:noexpandtab:sw=4:ts=4:
1008  */