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