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