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