c0c3c0d026b844170d225cd57ee9ff3a418b4fe9
[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
42 #if defined(ENABLE_JAVAME_CLDC1_1)
43 # include "native/include/java_lang_String.h"/* required by java_lang_Class.h */
44 #endif
45
46 #include "native/include/java_lang_Class.h"
47 #include "native/include/java_lang_Object.h"
48
49 #if defined(ENABLE_JAVASE)
50 # include "native/include/java_lang_ClassLoader.h"
51 # include "native/include/java_lang_reflect_Constructor.h"
52 # include "native/include/java_lang_reflect_Field.h"
53 # include "native/include/java_lang_reflect_Method.h"
54 #endif
55
56 #include "native/vm/java_lang_Class.h"
57
58 #include "toolbox/logging.h"
59
60 #include "vm/builtin.h"
61 #include "vm/exceptions.h"
62 #include "vm/global.h"
63 #include "vm/initialize.h"
64 #include "vm/stringlocal.h"
65
66 #include "vmcore/class.h"
67 #include "vmcore/loader.h"
68 #include "vm/resolve.h"
69
70
71 /*
72  * Class:     java/lang/Class
73  * Method:    getName
74  * Signature: ()Ljava/lang/String;
75  */
76 java_lang_String *_Jv_java_lang_Class_getName(java_lang_Class *klass)
77 {
78         classinfo        *c;
79         java_lang_String *s;
80         u4                i;
81
82         c = (classinfo *) klass;
83
84         /* create a java string */
85
86         s = (java_lang_String *) javastring_new(c->name);
87
88         if (s == NULL)
89                 return NULL;
90
91         /* return string where '/' is replaced by '.' */
92
93         for (i = 0; i < s->value->header.size; i++) {
94                 if (s->value->data[i] == '/')
95                         s->value->data[i] = '.';
96         }
97
98         return s;
99 }
100
101
102 /*
103  * Class:     java/lang/Class
104  * Method:    forName
105  * Signature: (Ljava/lang/String;ZLjava/lang/ClassLoader;)Ljava/lang/Class;
106  */
107 #if defined(ENABLE_JAVASE)
108 java_lang_Class *_Jv_java_lang_Class_forName(java_lang_String *name, s4 initialize, java_lang_ClassLoader *loader)
109 #elif defined(ENABLE_JAVAME_CLDC1_1)
110 java_lang_Class *_Jv_java_lang_Class_forName(java_lang_String *name)
111 #endif
112 {
113 #if defined(ENABLE_JAVASE)
114         classloader *cl;
115 #endif
116         utf               *ufile;
117         utf               *uname;
118         classinfo         *c;
119         java_objectheader *xptr;
120         classinfo         *xclass;
121         u2                *pos;
122         s4                 i;
123
124 #if defined(ENABLE_JAVASE)
125         cl = loader_hashtable_classloader_add((java_objectheader *) loader);
126 #endif
127
128         /* illegal argument */
129
130         if (name == NULL) {
131                 exceptions_throw_nullpointerexception();
132                 return NULL;
133         }
134
135         /* create utf string in which '.' is replaced by '/' */
136
137         ufile = javastring_toutf(name, true);
138         uname = javastring_toutf(name, false);
139
140         /* name must not contain '/' (mauve test) */
141
142         for (i = 0, pos = name->value->data + name->offset; i < name->count; i++, pos++) {
143                 if (*pos == '/') {
144                         exceptions_throw_classnotfoundexception(uname);
145                         return NULL;
146                 }
147         }
148
149         /* try to load, ... */
150
151 #if defined(ENABLE_JAVASE)
152         c = load_class_from_classloader(ufile, cl);
153 #elif defined(ENABLE_JAVAME_CLDC1_1)
154         c = load_class_bootstrap(ufile);
155 #endif
156
157         if (c == NULL) {
158                 xptr = exceptions_get_exception();
159
160                 xclass = xptr->vftbl->class;
161
162                 /* if the exception is a NoClassDefFoundError, we replace it with a
163                    ClassNotFoundException, otherwise return the exception */
164
165                 if (xclass == class_java_lang_NoClassDefFoundError) {
166                         /* clear exceptionptr, because builtin_new checks for 
167                            ExceptionInInitializerError */
168                         exceptions_clear_exception();
169
170                         exceptions_throw_classnotfoundexception(uname);
171                 }
172
173             return NULL;
174         }
175
176         /* link, ... */
177
178         if (!link_class(c))
179                 return NULL;
180         
181         /* ...and initialize it, if required */
182
183 #if defined(ENABLE_JAVASE)
184         if (initialize)
185 #endif
186                 if (!initialize_class(c))
187                         return NULL;
188
189         return (java_lang_Class *) c;
190 }
191
192
193 /*
194  * Class:     java/lang/Class
195  * Method:    isInstance
196  * Signature: (Ljava/lang/Object;)Z
197  */
198 s4 _Jv_java_lang_Class_isInstance(java_lang_Class *klass, java_lang_Object *o)
199 {
200         classinfo         *c;
201         java_objectheader *ob;
202
203         c = (classinfo *) klass;
204         ob = (java_objectheader *) o;
205
206         if (!(c->state & CLASS_LINKED))
207                 if (!link_class(c))
208                         return 0;
209
210         return builtin_instanceof(ob, c);
211 }
212
213
214 /*
215  * Class:     java/lang/Class
216  * Method:    isAssignableFrom
217  * Signature: (Ljava/lang/Class;)Z
218  */
219 s4 _Jv_java_lang_Class_isAssignableFrom(java_lang_Class *klass, java_lang_Class *c)
220 {
221         classinfo *kc;
222         classinfo *cc;
223
224         kc = (classinfo *) klass;
225         cc = (classinfo *) c;
226
227         if (cc == NULL) {
228                 exceptions_throw_nullpointerexception();
229                 return 0;
230         }
231
232         if (!(kc->state & CLASS_LINKED))
233                 if (!link_class(kc))
234                         return 0;
235
236         if (!(cc->state & CLASS_LINKED))
237                 if (!link_class(cc))
238                         return 0;
239
240         return class_isanysubclass(cc, kc);
241 }
242
243
244 /*
245  * Class:     java/lang/Class
246  * Method:    isInterface
247  * Signature: ()Z
248  */
249 s4 _Jv_java_lang_Class_isInterface(java_lang_Class *klass)
250 {
251         classinfo *c;
252
253         c = (classinfo *) klass;
254
255         if (c->flags & ACC_INTERFACE)
256                 return true;
257
258         return false;
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         s4         i;
273
274         c = (classinfo *) klass;
275
276         /* search table of primitive classes */
277
278         for (i = 0; i < PRIMITIVETYPE_COUNT; i++)
279                 if (primitivetype_table[i].class_primitive == c)
280                         return true;
281
282         return false;
283 }
284
285
286 /*
287  * Class:     java/lang/Class
288  * Method:    getSuperclass
289  * Signature: ()Ljava/lang/Class;
290  */
291 java_lang_Class *_Jv_java_lang_Class_getSuperclass(java_lang_Class *klass)
292 {
293         classinfo *c;
294         classinfo *sc;
295
296         c = (classinfo *) klass;
297
298         /* for java.lang.Object, primitive and Void classes we return NULL */
299
300         if (!c->super.any)
301                 return NULL;
302
303         /* for interfaces we also return NULL */
304
305         if (c->flags & ACC_INTERFACE)
306                 return NULL;
307
308         /* we may have to resolve the super class reference */
309
310         if ((sc = resolve_classref_or_classinfo_eager(c->super, true)) == NULL)
311                 return NULL;
312
313         /* store the resolution */
314
315         c->super.cls = sc;
316
317         return (java_lang_Class *) sc;
318 }
319
320
321 /*
322  * Class:     java/lang/Class
323  * Method:    getInterfaces
324  * Signature: ()[Ljava/lang/Class;
325  */
326 java_objectarray *_Jv_java_lang_Class_getInterfaces(java_lang_Class *klass)
327 {
328         classinfo        *c;
329         classinfo        *ic;
330         java_objectarray *oa;
331         u4                i;
332
333         c = (classinfo *) klass;
334
335         if (!(c->state & CLASS_LINKED))
336                 if (!link_class(c))
337                         return NULL;
338
339         oa = builtin_anewarray(c->interfacescount, class_java_lang_Class);
340
341         if (oa == NULL)
342                 return NULL;
343
344         for (i = 0; i < c->interfacescount; i++) {
345                 ic = c->interfaces[i].cls;
346
347                 oa->data[i] = (java_objectheader *) ic;
348         }
349
350         return oa;
351 }
352
353
354 /*
355  * Class:     java/lang/Class
356  * Method:    getComponentType
357  * Signature: ()Ljava/lang/Class;
358  */
359 java_lang_Class *_Jv_java_lang_Class_getComponentType(java_lang_Class *klass)
360 {
361         classinfo       *c;
362         classinfo       *comp;
363         arraydescriptor *desc;
364         
365         c = (classinfo *) klass;
366         
367         /* XXX maybe we could find a way to do this without linking. */
368         /* This way should be safe and easy, however.                */
369
370         if (!(c->state & CLASS_LINKED))
371                 if (!link_class(c))
372                         return NULL;
373
374         desc = c->vftbl->arraydesc;
375         
376         if (desc == NULL)
377                 return NULL;
378         
379         if (desc->arraytype == ARRAYTYPE_OBJECT)
380                 comp = desc->componentvftbl->class;
381         else
382                 comp = primitivetype_table[desc->arraytype].class_primitive;
383                 
384         return (java_lang_Class *) comp;
385 }
386
387
388 /*
389  * Class:     java/lang/Class
390  * Method:    getModifiers
391  * Signature: (Z)I
392  */
393 s4 _Jv_java_lang_Class_getModifiers(java_lang_Class *klass, s4 ignoreInnerClassesAttrib)
394 {
395         classinfo             *c;
396         classref_or_classinfo  inner;
397         classref_or_classinfo  outer;
398         utf                   *innername;
399         s4                     i;
400
401         c = (classinfo *) klass;
402
403         if (!ignoreInnerClassesAttrib && (c->innerclasscount != 0)) {
404                 /* search for passed class as inner class */
405
406                 for (i = 0; i < c->innerclasscount; i++) {
407                         inner = c->innerclass[i].inner_class;
408                         outer = c->innerclass[i].outer_class;
409
410                         /* Check if inner is a classref or a real class and get
411                the name of the structure */
412
413                         innername = IS_CLASSREF(inner) ? inner.ref->name : inner.cls->name;
414
415                         /* innerclass is this class */
416
417                         if (innername == c->name) {
418                                 /* has the class actually an outer class? */
419
420                                 if (outer.any)
421                                         /* return flags got from the outer class file */
422                                         return c->innerclass[i].flags & ACC_CLASS_REFLECT_MASK;
423                                 else
424                                         return c->flags & ACC_CLASS_REFLECT_MASK;
425                         }
426                 }
427         }
428
429         /* passed class is no inner class or it was not requested */
430
431         return c->flags & ACC_CLASS_REFLECT_MASK;
432 }
433
434
435 /*
436  * Class:     java/lang/Class
437  * Method:    getDeclaringClass
438  * Signature: ()Ljava/lang/Class;
439  */
440 java_lang_Class *_Jv_java_lang_Class_getDeclaringClass(java_lang_Class *klass)
441 {
442         classinfo             *c;
443         classref_or_classinfo  inner;
444         utf                   *innername;
445         classinfo             *outer;
446         s4                     i;
447
448         c = (classinfo *) klass;
449
450         if (!_Jv_java_lang_Class_isPrimitive(klass) && (c->name->text[0] != '[')) {
451                 if (c->innerclasscount == 0)  /* no innerclasses exist */
452                         return NULL;
453     
454                 for (i = 0; i < c->innerclasscount; i++) {
455                         inner = c->innerclass[i].inner_class;
456
457                         /* check if inner_class is a classref or a real class and
458                get the class name from the structure */
459
460                         innername = IS_CLASSREF(inner) ? inner.ref->name : inner.cls->name;
461
462                         /* innerclass is this class */
463
464                         if (innername == c->name) {
465                                 /* maybe the outer class is not loaded yet */
466
467                                 if ((outer = resolve_classref_or_classinfo_eager(
468                                                                 c->innerclass[i].outer_class,
469                                                                 false)) == NULL)
470                                         return NULL;
471
472                                 if (!(outer->state & CLASS_LINKED))
473                                         if (!link_class(outer))
474                                                 return NULL;
475
476                                 return (java_lang_Class *) outer;
477                         }
478                 }
479         }
480
481         /* return NULL for arrayclasses and primitive classes */
482
483         return NULL;
484 }
485
486
487 /*
488  * Class:     java/lang/Class
489  * Method:    getDeclaredClasses
490  * Signature: (Z)[Ljava/lang/Class;
491  */
492 java_objectarray *_Jv_java_lang_Class_getDeclaredClasses(java_lang_Class *klass, s4 publicOnly)
493 {
494         classinfo             *c;
495         classref_or_classinfo  outer;
496         utf                   *outername;
497         s4                     declaredclasscount;  /* number of declared classes */
498         s4                     pos;                     /* current declared class */
499         java_objectarray      *oa;                   /* array of declared classes */
500         s4                     i;
501
502         c = (classinfo *) klass;
503         declaredclasscount = 0;
504
505         if (!_Jv_java_lang_Class_isPrimitive(klass) && (c->name->text[0] != '[')) {
506                 /* determine number of declared classes */
507
508                 for (i = 0; i < c->innerclasscount; i++) {
509                         outer = c->innerclass[i].outer_class;
510
511                         /* check if outer_class is a classref or a real class and
512                get the class name from the structure */
513
514                         outername = IS_CLASSREF(outer) ? outer.ref->name : outer.cls->name;
515
516                         /* outer class is this class */
517
518                         if ((outername == c->name) &&
519                                 ((publicOnly == 0) || (c->innerclass[i].flags & ACC_PUBLIC)))
520                                 declaredclasscount++;
521                 }
522         }
523
524         /* allocate Class[] and check for OOM */
525
526         oa = builtin_anewarray(declaredclasscount, class_java_lang_Class);
527
528         if (oa == NULL)
529                 return NULL;
530
531         for (i = 0, pos = 0; i < c->innerclasscount; i++) {
532                 outer = c->innerclass[i].outer_class;
533
534                 /* check if outer_class is a classref or a real class and
535                    get the class name from the structure */
536
537                 outername = IS_CLASSREF(outer) ? outer.ref->name : outer.cls->name;
538
539                 /* outer class is this class */
540
541                 if ((outername == c->name) &&
542                         ((publicOnly == 0) || (c->innerclass[i].flags & ACC_PUBLIC))) {
543                         classinfo *inner;
544
545                         if ((inner = resolve_classref_or_classinfo_eager(
546                                                                                            c->innerclass[i].inner_class,
547                                                                                            false)) == NULL)
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->object;
770 }
771
772 #endif /* defined(ENABLE_JAVASE) */
773
774
775 /*
776  * Class:     java/lang/Class
777  * Method:    isArray
778  * Signature: ()Z
779  */
780 s4 _Jv_java_lang_Class_isArray(java_lang_Class *klass)
781 {
782         classinfo *c;
783
784         c = (classinfo *) klass;
785
786         if (!(c->state & CLASS_LINKED))
787                 if (!link_class(c))
788                         return 0;
789
790         return (c->vftbl->arraydesc != NULL);
791 }
792
793
794 #if defined(ENABLE_JAVASE)
795
796 /*
797  * Class:     java/lang/Class
798  * Method:    throwException
799  * Signature: (Ljava/lang/Throwable;)V
800  */
801 void _Jv_java_lang_Class_throwException(java_lang_Throwable *t)
802 {
803         java_objectheader *o;
804
805         o = (java_objectheader *) t;
806
807         exceptions_set_exception(o);
808 }
809
810
811 #if 0
812 /*
813  * Class:     java/lang/Class
814  * Method:    getDeclaredAnnotations
815  * Signature: (Ljava/lang/Class;)[Ljava/lang/annotation/Annotation;
816  */
817 java_objectarray *_Jv_java_lang_Class_getDeclaredAnnotations(java_lang_Class* klass)
818 {
819 }
820 #endif
821
822
823 /*
824  * Class:     java/lang/Class
825  * Method:    getEnclosingClass
826  * Signature: (Ljava/lang/Class;)Ljava/lang/Class;
827  */
828 java_lang_Class *_Jv_java_lang_Class_getEnclosingClass(java_lang_Class *klass)
829 {
830         classinfo             *c;
831         classref_or_classinfo  cr;
832         classinfo             *ec;
833
834         c = (classinfo *) klass;
835
836         /* get enclosing class */
837
838         cr = c->enclosingclass;
839
840         if (cr.any == NULL)
841                 return NULL;
842
843         /* resolve the class if necessary */
844
845         if (IS_CLASSREF(cr)) {
846                 ec = resolve_classref_eager(cr.ref);
847
848                 if (ec == NULL)
849                         return NULL;
850         }
851         else
852                 ec = cr.cls;
853
854         return (java_lang_Class *) ec;
855 }
856
857
858 /* _Jv_java_lang_Class_getEnclosingMethod_intern *******************************
859
860    Helper function for _Jv_java_lang_Class_getEnclosingConstructor and
861    _Jv_java_lang_Class_getEnclosingMethod.
862
863 *******************************************************************************/
864
865 static methodinfo *_Jv_java_lang_Class_getEnclosingMethod_intern(classinfo *c)
866 {
867         classref_or_classinfo     cr;
868         constant_nameandtype     *cn;
869         classinfo                *ec;
870         methodinfo               *m;
871
872         /* get enclosing class and method */
873
874         cr = c->enclosingclass;
875         cn = c->enclosingmethod;
876
877         /* check for enclosing class and method */
878
879         if (cr.any == NULL)
880                 return NULL;
881
882         if (cn == NULL)
883                 return NULL;
884
885         /* resolve the class if necessary */
886
887         if (IS_CLASSREF(cr)) {
888                 ec = resolve_classref_eager(cr.ref);
889
890                 if (ec == NULL)
891                         return NULL;
892         }
893         else
894                 ec = cr.cls;
895
896         /* find method in enclosing class */
897
898         m = class_findmethod(ec, cn->name, cn->descriptor);
899
900         if (m == NULL) {
901                 exceptions_throw_internalerror("Enclosing method doesn't exist");
902                 return NULL;
903         }
904
905         return m;
906 }
907
908
909 /*
910  * Class:     java/lang/Class
911  * Method:    getEnclosingConstructor
912  * Signature: (Ljava/lang/Class;)Ljava/lang/reflect/Constructor;
913  */
914 java_lang_reflect_Constructor *_Jv_java_lang_Class_getEnclosingConstructor(java_lang_Class *klass)
915 {
916         classinfo                     *c;
917         methodinfo                    *m;
918         java_objectheader             *o;
919         java_lang_reflect_Constructor *rc;
920
921         c = (classinfo *) klass;
922
923         /* get enclosing method */
924
925         m = _Jv_java_lang_Class_getEnclosingMethod_intern(c);
926
927         if (m == NULL)
928                 return NULL;
929
930         /* check for <init> */
931
932         if (m->name != utf_init)
933                 return NULL;
934
935         /* create java.lang.reflect.Constructor object */
936
937         o = native_new_and_init(class_java_lang_reflect_Constructor);
938
939         if (o == NULL)
940                 return NULL;
941
942         /* initialize instance fields */
943
944         rc = (java_lang_reflect_Constructor *) o;
945
946         rc->clazz = (java_lang_Class *) m->class;
947         rc->slot  = m - m->class->methods;               /* calculate method slot */
948
949         return rc;
950 }
951
952
953 /*
954  * Class:     java/lang/Class
955  * Method:    getEnclosingMethod
956  * Signature: (Ljava/lang/Class;)Ljava/lang/reflect/Method;
957  */
958 java_lang_reflect_Method *_Jv_java_lang_Class_getEnclosingMethod(java_lang_Class *klass)
959 {
960         classinfo                *c;
961         methodinfo               *m;
962         java_objectheader        *o;
963         java_lang_reflect_Method *rm;
964
965         c = (classinfo *) klass;
966
967         /* get enclosing method */
968
969         m = _Jv_java_lang_Class_getEnclosingMethod_intern(c);
970
971         if (m == NULL)
972                 return NULL;
973
974         /* check for <init> */
975
976         if (m->name == utf_init)
977                 return NULL;
978
979         /* create java.lang.reflect.Method object */
980
981         o = native_new_and_init(class_java_lang_reflect_Method);
982
983         if (o == NULL)
984                 return NULL;
985
986         /* initialize instance fields */
987
988         rm = (java_lang_reflect_Method *) o;
989
990         rm->declaringClass = (java_lang_Class *) m->class;
991         rm->name           = javastring_new(m->name);
992         rm->slot           = m - m->class->methods;      /* calculate method slot */
993
994         return rm;
995 }
996
997
998 /*
999  * Class:     java/lang/Class
1000  * Method:    getClassSignature
1001  * Signature: (Ljava/lang/Class;)Ljava/lang/String;
1002  */
1003 java_lang_String *_Jv_java_lang_Class_getClassSignature(java_lang_Class* klass)
1004 {
1005         classinfo        *c;
1006         java_lang_String *s;
1007
1008         c = (classinfo *) klass;
1009
1010         if (c->signature == NULL)
1011                 return NULL;
1012
1013         s = javastring_new(c->signature);
1014
1015         /* in error case, s == NULL */
1016
1017         return s;
1018 }
1019
1020
1021 #if 0
1022 /*
1023  * Class:     java/lang/Class
1024  * Method:    isAnonymousClass
1025  * Signature: (Ljava/lang/Class;)Z
1026  */
1027 s4 _Jv_java_lang_Class_isAnonymousClass(JNIEnv *env, jclass clazz, struct java_lang_Class* par1);
1028
1029
1030 /*
1031  * Class:     java/lang/VMClass
1032  * Method:    isLocalClass
1033  * Signature: (Ljava/lang/Class;)Z
1034  */
1035 JNIEXPORT s4 JNICALL Java_java_lang_VMClass_isLocalClass(JNIEnv *env, jclass clazz, struct java_lang_Class* par1);
1036
1037
1038 /*
1039  * Class:     java/lang/VMClass
1040  * Method:    isMemberClass
1041  * Signature: (Ljava/lang/Class;)Z
1042  */
1043 JNIEXPORT s4 JNICALL Java_java_lang_VMClass_isMemberClass(JNIEnv *env, jclass clazz, struct java_lang_Class* par1);
1044 #endif
1045
1046 #endif /* ENABLE_JAVASE */
1047
1048
1049 /*
1050  * These are local overrides for various environment variables in Emacs.
1051  * Please do not remove this and leave it at the end of the file, where
1052  * Emacs will automagically detect them.
1053  * ---------------------------------------------------------------------
1054  * Local variables:
1055  * mode: c
1056  * indent-tabs-mode: t
1057  * c-basic-offset: 4
1058  * tab-width: 4
1059  * End:
1060  * vim:noexpandtab:sw=4:ts=4:
1061  */