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