* Updated to jitcache-arm-x86 branch d4f6023b26c5+d1b5b1c106ac
[cacao.git] / src / vm / class.c
1 /* src/vm/class.c - class related functions
2
3    Copyright (C) 1996-2005, 2006, 2007, 2008
4    CACAOVM - Verein zur Foerderung der freien virtuellen Maschine CACAO
5
6    This file is part of CACAO.
7
8    This program is free software; you can redistribute it and/or
9    modify it under the terms of the GNU General Public License as
10    published by the Free Software Foundation; either version 2, or (at
11    your option) any later version.
12
13    This program is distributed in the hope that it will be useful, but
14    WITHOUT ANY WARRANTY; without even the implied warranty of
15    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
16    General Public License for more details.
17
18    You should have received a copy of the GNU General Public License
19    along with this program; if not, write to the Free Software
20    Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
21    02110-1301, USA.
22
23 */
24
25
26 #include "config.h"
27
28 #include <assert.h>
29 #include <stdio.h>
30 #include <stdlib.h>
31 #include <string.h>
32
33 #include "vm/types.h"
34
35 #include "arch.h"
36
37 #include "mm/memory.h"
38
39 #include "native/llni.h"
40
41 #include "threads/lock.hpp"
42 #include "threads/mutex.hpp"
43
44 #include "toolbox/logging.h"
45
46 #include "vm/array.hpp"
47 #include "vm/jit/builtin.hpp"
48 #include "vm/class.h"
49 #include "vm/classcache.h"
50 #include "vm/exceptions.hpp"
51 #include "vm/global.h"
52 #include "vm/globals.hpp"
53 #include "vm/javaobjects.hpp"
54 #include "vm/jit/jitcache.hpp"
55 #include "vm/linker.h"
56 #include "vm/loader.hpp"
57 #include "vm/options.h"
58 #include "vm/resolve.h"
59
60 #if defined(ENABLE_STATISTICS)
61 # include "vm/statistics.h"
62 #endif
63
64 #include "vm/suck.hpp"
65 #include "vm/utf8.h"
66
67 #include "vm/jit/asmpart.h"
68
69
70 /* class_set_packagename *******************************************************
71
72    Derive the package name from the class name and store it in the
73    struct.
74
75    An internal package name consists of the package name plus the
76    trailing '/', e.g. "java/lang/".
77
78    For classes in the unnamed package, the package name is set to
79    NULL.
80
81 *******************************************************************************/
82
83 void class_set_packagename(classinfo *c)
84 {
85         char *p;
86         char *start;
87
88         p     = UTF_END(c->name) - 1;
89         start = c->name->text;
90
91         if (c->name->text[0] == '[') {
92                 /* Set packagename of arrays to the element's package. */
93
94                 for (; *start == '['; start++);
95
96                 /* Skip the 'L' in arrays of references. */
97
98                 if (*start == 'L')
99                         start++;
100         }
101
102         /* Search for last '/'. */
103
104         for (; (p > start) && (*p != '/'); --p);
105
106         /* If we found a '/' we set the package name plus the trailing
107            '/'.  Otherwise we set the packagename to NULL. */
108
109         if (p > start)
110                 c->packagename = utf_new(start, p - start + 1);
111         else
112                 c->packagename = NULL;
113 }
114
115
116 /* class_create_classinfo ******************************************************
117
118    Create a new classinfo struct. The class name is set to the given utf *,
119    most other fields are initialized to zero.
120
121    Note: classname may be NULL. In this case a not-yet-named classinfo is
122          created. The name must be filled in later and class_set_packagename
123                  must be called after that.
124
125 *******************************************************************************/
126
127 classinfo *class_create_classinfo(utf *classname)
128 {
129         classinfo *c;
130
131 #if defined(ENABLE_STATISTICS)
132         if (opt_stat)
133                 size_classinfo += sizeof(classinfo);
134 #endif
135
136         /* we use a safe name for temporarily unnamed classes */
137
138         if (classname == NULL)
139                 classname = utf_not_named_yet;
140
141 #if !defined(NDEBUG)
142         if (initverbose)
143                 log_message_utf("Creating class: ", classname);
144 #endif
145
146 #if !defined(ENABLE_GC_BOEHM)
147         c = (classinfo *) heap_alloc_uncollectable(sizeof(classinfo));
148         /*c = NEW(classinfo);
149         MZERO(c, classinfo, 1);*/
150 #else
151         c = GCNEW_UNCOLLECTABLE(classinfo, 1);
152         /* GCNEW_UNCOLLECTABLE clears the allocated memory */
153 #endif
154
155         c->name = classname;
156
157         /* Set the header.vftbl of all loaded classes to the one of
158        java.lang.Class, so Java code can use a class as object. */
159
160         if (class_java_lang_Class != NULL)
161                 if (class_java_lang_Class->vftbl != NULL)
162                         c->object.header.vftbl = class_java_lang_Class->vftbl;
163
164 #if defined(ENABLE_JAVASE)
165         /* check if the class is a reference class and flag it */
166
167         if (classname == utf_java_lang_ref_SoftReference) {
168                 c->flags |= ACC_CLASS_REFERENCE_SOFT;
169         }
170         else if (classname == utf_java_lang_ref_WeakReference) {
171                 c->flags |= ACC_CLASS_REFERENCE_WEAK;
172         }
173         else if (classname == utf_java_lang_ref_PhantomReference) {
174                 c->flags |= ACC_CLASS_REFERENCE_PHANTOM;
175         }
176 #endif
177
178         if (classname != utf_not_named_yet)
179                 class_set_packagename(c);
180 #if defined (ENABLE_JITCACHE)
181     c->cache_file_fd = 0;
182 #endif
183
184         Lockword_init(&(c->object.header.lockword));
185
186         return c;
187 }
188
189
190 /* class_postset_header_vftbl **************************************************
191
192    Set the header.vftbl of all classes created before java.lang.Class
193    was linked.  This is necessary that Java code can use a class as
194    object.
195
196 *******************************************************************************/
197
198 void class_postset_header_vftbl(void)
199 {
200         classinfo *c;
201         u4 slot;
202         classcache_name_entry *nmen;
203         classcache_class_entry *clsen;
204
205         assert(class_java_lang_Class);
206
207         for (slot = 0; slot < hashtable_classcache.size; slot++) {
208                 nmen = (classcache_name_entry *) hashtable_classcache.ptr[slot];
209
210                 for (; nmen; nmen = nmen->hashlink) {
211                         /* iterate over all class entries */
212
213                         for (clsen = nmen->classes; clsen; clsen = clsen->next) {
214                                 c = clsen->classobj;
215
216                                 /* now set the the vftbl */
217
218                                 if (c->object.header.vftbl == NULL)
219                                         c->object.header.vftbl = class_java_lang_Class->vftbl;
220                         }
221                 }
222         }
223 }
224
225 /* class_define ****************************************************************
226
227    Calls the loader and defines a class in the VM.
228
229 *******************************************************************************/
230
231 classinfo *class_define(utf *name, classloader_t *cl, int32_t length, uint8_t *data, java_handle_t *pd)
232 {
233         classinfo   *c;
234         classinfo   *r;
235         classbuffer *cb;
236
237         if (name != NULL) {
238                 /* check if this class has already been defined */
239
240                 c = classcache_lookup_defined_or_initiated(cl, name);
241
242                 if (c != NULL) {
243                         exceptions_throw_linkageerror("duplicate class definition: ", c);
244                         return NULL;
245                 }
246         } 
247
248         /* create a new classinfo struct */
249
250         c = class_create_classinfo(name);
251
252 #if defined(ENABLE_STATISTICS)
253         /* measure time */
254
255         if (opt_getloadingtime)
256                 loadingtime_start();
257 #endif
258
259         /* build a classbuffer with the given data */
260
261         cb = NEW(classbuffer);
262
263         cb->clazz = c;
264         cb->size  = length;
265         cb->data  = data;
266         cb->pos   = cb->data;
267
268         /* preset the defining classloader */
269
270         c->classloader = cl;
271
272         /* load the class from this buffer */
273
274         r = load_class_from_classbuffer(cb);
275
276         /* free memory */
277
278         FREE(cb, classbuffer);
279
280 #if defined(ENABLE_STATISTICS)
281         /* measure time */
282
283         if (opt_getloadingtime)
284                 loadingtime_stop();
285 #endif
286
287         if (r == NULL) {
288                 /* If return value is NULL, we had a problem and the class is
289                    not loaded.  Now free the allocated memory, otherwise we
290                    could run into a DOS. */
291
292                 class_free(c);
293
294                 return NULL;
295         }
296
297 #if defined(ENABLE_JAVASE)
298 # if defined(WITH_JAVA_RUNTIME_LIBRARY_OPENJDK)
299         /* Store the protection domain. */
300
301         c->protectiondomain = pd;
302 # endif
303 #endif
304
305         /* Store the newly defined class in the class cache. This call
306            also checks whether a class of the same name has already been
307            defined by the same defining loader, and if so, replaces the
308            newly created class by the one defined earlier. */
309
310         /* Important: The classinfo given to classcache_store must be
311                       fully prepared because another thread may return
312                       this pointer after the lookup at to top of this
313                       function directly after the class cache lock has
314                       been released. */
315
316         c = classcache_store(cl, c, true);
317
318         return c;
319 }
320
321
322 /* class_load_attribute_sourcefile *********************************************
323
324    SourceFile_attribute {
325        u2 attribute_name_index;
326        u4 attribute_length;
327            u2 sourcefile_index;
328    }
329
330 *******************************************************************************/
331
332 static bool class_load_attribute_sourcefile(classbuffer *cb)
333 {
334         classinfo *c;
335         u4         attribute_length;
336         u2         sourcefile_index;
337         utf       *sourcefile;
338
339         /* get classinfo */
340
341         c = cb->clazz;
342
343         /* check buffer size */
344
345         if (!suck_check_classbuffer_size(cb, 4 + 2))
346                 return false;
347
348         /* check attribute length */
349
350         attribute_length = suck_u4(cb);
351
352         if (attribute_length != 2) {
353                 exceptions_throw_classformaterror(c, "Wrong size for VALUE attribute");
354                 return false;
355         }
356
357         /* there can be no more than one SourceFile attribute */
358
359         if (c->sourcefile != NULL) {
360                 exceptions_throw_classformaterror(c, "Multiple SourceFile attributes");
361                 return false;
362         }
363
364         /* get sourcefile */
365
366         sourcefile_index = suck_u2(cb);
367         sourcefile = class_getconstant(c, sourcefile_index, CONSTANT_Utf8);
368
369         if (sourcefile == NULL)
370                 return false;
371
372         /* store sourcefile */
373
374         c->sourcefile = sourcefile;
375
376         return true;
377 }
378
379
380 /* class_load_attribute_enclosingmethod ****************************************
381
382    EnclosingMethod_attribute {
383        u2 attribute_name_index;
384        u4 attribute_length;
385            u2 class_index;
386            u2 method_index;
387    }
388
389 *******************************************************************************/
390
391 #if defined(ENABLE_JAVASE)
392 static bool class_load_attribute_enclosingmethod(classbuffer *cb)
393 {
394         classinfo             *c;
395         u4                     attribute_length;
396         u2                     class_index;
397         u2                     method_index;
398         classref_or_classinfo  cr;
399         constant_nameandtype  *cn;
400
401         /* get classinfo */
402
403         c = cb->clazz;
404
405         /* check buffer size */
406
407         if (!suck_check_classbuffer_size(cb, 4 + 2 + 2))
408                 return false;
409
410         /* check attribute length */
411
412         attribute_length = suck_u4(cb);
413
414         if (attribute_length != 4) {
415                 exceptions_throw_classformaterror(c, "Wrong size for VALUE attribute");
416                 return false;
417         }
418
419         /* there can be no more than one EnclosingMethod attribute */
420
421         if (c->enclosingmethod != NULL) {
422                 exceptions_throw_classformaterror(c, "Multiple EnclosingMethod attributes");
423                 return false;
424         }
425
426         /* get class index */
427
428         class_index = suck_u2(cb);
429         cr.ref = innerclass_getconstant(c, class_index, CONSTANT_Class);
430
431         /* get method index */
432
433         method_index = suck_u2(cb);
434         cn = innerclass_getconstant(c, method_index, CONSTANT_NameAndType);
435
436         /* store info in classinfo */
437
438         c->enclosingclass.any = cr.any;
439         c->enclosingmethod    = cn;
440
441         return true;
442 }
443 #endif /* defined(ENABLE_JAVASE) */
444
445
446 /* class_load_attributes *******************************************************
447
448    Read attributes from ClassFile.
449
450    attribute_info {
451        u2 attribute_name_index;
452        u4 attribute_length;
453        u1 info[attribute_length];
454    }
455
456    InnerClasses_attribute {
457        u2 attribute_name_index;
458        u4 attribute_length;
459    }
460
461 *******************************************************************************/
462
463 bool class_load_attributes(classbuffer *cb)
464 {
465         classinfo             *c;
466         uint16_t               attributes_count;
467         uint16_t               attribute_name_index;
468         utf                   *attribute_name;
469         innerclassinfo        *info;
470         classref_or_classinfo  inner;
471         classref_or_classinfo  outer;
472         utf                   *name;
473         uint16_t               flags;
474         int                    i, j;
475
476         c = cb->clazz;
477
478         /* get attributes count */
479
480         if (!suck_check_classbuffer_size(cb, 2))
481                 return false;
482
483         attributes_count = suck_u2(cb);
484
485         for (i = 0; i < attributes_count; i++) {
486                 /* get attribute name */
487
488                 if (!suck_check_classbuffer_size(cb, 2))
489                         return false;
490
491                 attribute_name_index = suck_u2(cb);
492                 attribute_name =
493                         class_getconstant(c, attribute_name_index, CONSTANT_Utf8);
494
495                 if (attribute_name == NULL)
496                         return false;
497
498                 if (attribute_name == utf_InnerClasses) {
499                         /* InnerClasses */
500
501                         if (c->innerclass != NULL) {
502                                 exceptions_throw_classformaterror(c, "Multiple InnerClasses attributes");
503                                 return false;
504                         }
505                                 
506                         if (!suck_check_classbuffer_size(cb, 4 + 2))
507                                 return false;
508
509                         /* skip attribute length */
510                         suck_u4(cb);
511
512                         /* number of records */
513                         c->innerclasscount = suck_u2(cb);
514
515                         if (!suck_check_classbuffer_size(cb, (2 + 2 + 2 + 2) * c->innerclasscount))
516                                 return false;
517
518                         /* allocate memory for innerclass structure */
519                         c->innerclass = MNEW(innerclassinfo, c->innerclasscount);
520
521                         for (j = 0; j < c->innerclasscount; j++) {
522                                 /* The innerclass structure contains a class with an encoded
523                                    name, its defining scope, its simple name and a bitmask of
524                                    the access flags. */
525                                                                 
526                                 info = c->innerclass + j;
527
528                                 inner.ref = innerclass_getconstant(c, suck_u2(cb), CONSTANT_Class);
529                                 outer.ref = innerclass_getconstant(c, suck_u2(cb), CONSTANT_Class);
530                                 name      = innerclass_getconstant(c, suck_u2(cb), CONSTANT_Utf8);
531                                 flags     = suck_u2(cb);
532
533                                 /* If the current inner-class is the currently loaded
534                                    class check for some special flags. */
535
536                                 if (inner.ref->name == c->name) {
537                                         /* If an inner-class is not a member, its
538                                            outer-class is NULL. */
539
540                                         if (outer.ref != NULL) {
541                                                 c->flags |= ACC_CLASS_MEMBER;
542
543                                                 /* A member class doesn't have an
544                                                    EnclosingMethod attribute, so set the
545                                                    enclosing-class to be the same as the
546                                                    declaring-class. */
547
548                                                 c->declaringclass = outer;
549                                                 c->enclosingclass = outer;
550                                         }
551
552                                         /* If an inner-class is anonymous, its name is
553                                            NULL. */
554
555                                         if (name == NULL)
556                                                 c->flags |= ACC_CLASS_ANONYMOUS;
557                                 }
558
559                                 info->inner_class = inner;
560                                 info->outer_class = outer;
561                                 info->name        = name;
562                                 info->flags       = flags;
563                         }
564                 }
565                 else if (attribute_name == utf_SourceFile) {
566                         /* SourceFile */
567
568                         if (!class_load_attribute_sourcefile(cb))
569                                 return false;
570                 }
571 #if defined(ENABLE_JAVASE)
572                 else if (attribute_name == utf_EnclosingMethod) {
573                         /* EnclosingMethod */
574
575                         if (!class_load_attribute_enclosingmethod(cb))
576                                 return false;
577                 }
578                 else if (attribute_name == utf_Signature) {
579                         /* Signature */
580
581                         if (!loader_load_attribute_signature(cb, &(c->signature)))
582                                 return false;
583                 }
584 #endif
585
586 #if defined(ENABLE_ANNOTATIONS)
587                 else if (attribute_name == utf_RuntimeVisibleAnnotations) {
588                         /* RuntimeVisibleAnnotations */
589                         if (!annotation_load_class_attribute_runtimevisibleannotations(cb))
590                                 return false;
591                 }
592                 else if (attribute_name == utf_RuntimeInvisibleAnnotations) {
593                         /* RuntimeInvisibleAnnotations */
594                         if (!annotation_load_class_attribute_runtimeinvisibleannotations(cb))
595                                 return false;
596                 }
597 #endif
598
599                 else {
600                         /* unknown attribute */
601
602                         if (!loader_skip_attribute_body(cb))
603                                 return false;
604                 }
605         }
606
607         return true;
608 }
609
610
611 /* class_freepool **************************************************************
612
613         Frees all resources used by this classes Constant Pool.
614
615 *******************************************************************************/
616
617 static void class_freecpool(classinfo *c)
618 {
619         u4 idx;
620         u4 tag;
621         void* info;
622         
623         if (c->cptags && c->cpinfos) {
624                 for (idx = 0; idx < c->cpcount; idx++) {
625                         tag = c->cptags[idx];
626                         info = c->cpinfos[idx];
627                 
628                         if (info != NULL) {
629                                 switch (tag) {
630                                 case CONSTANT_Fieldref:
631                                 case CONSTANT_Methodref:
632                                 case CONSTANT_InterfaceMethodref:
633                                         FREE(info, constant_FMIref);
634                                         break;
635                                 case CONSTANT_Integer:
636                                         FREE(info, constant_integer);
637                                         break;
638                                 case CONSTANT_Float:
639                                         FREE(info, constant_float);
640                                         break;
641                                 case CONSTANT_Long:
642                                         FREE(info, constant_long);
643                                         break;
644                                 case CONSTANT_Double:
645                                         FREE(info, constant_double);
646                                         break;
647                                 case CONSTANT_NameAndType:
648                                         FREE(info, constant_nameandtype);
649                                         break;
650                                 }
651                         }
652                 }
653         }
654
655         if (c->cptags)
656                 MFREE(c->cptags, u1, c->cpcount);
657
658         if (c->cpinfos)
659                 MFREE(c->cpinfos, void*, c->cpcount);
660 }
661
662
663 /* class_getconstant ***********************************************************
664
665    Retrieves the value at position 'pos' of the constantpool of a
666    class. If the type of the value is other than 'ctype', an error is
667    thrown.
668
669 *******************************************************************************/
670
671 void* class_getconstant(classinfo *c, u4 pos, u4 ctype)
672 {
673         /* check index and type of constantpool entry */
674         /* (pos == 0 is caught by type comparison) */
675
676         if ((pos >= c->cpcount) || (c->cptags[pos] != ctype)) {
677                 exceptions_throw_classformaterror(c, "Illegal constant pool index");
678                 return NULL;
679         }
680
681         return c->cpinfos[pos];
682 }
683
684
685 /* innerclass_getconstant ******************************************************
686
687    Like class_getconstant, but if cptags is ZERO, null is returned.
688         
689 *******************************************************************************/
690
691 void* innerclass_getconstant(classinfo *c, u4 pos, u4 ctype)
692 {
693         /* invalid position in constantpool */
694
695         if (pos >= c->cpcount) {
696                 exceptions_throw_classformaterror(c, "Illegal constant pool index");
697                 return NULL;
698         }
699
700         /* constantpool entry of type 0 */      
701
702         if (c->cptags[pos] == 0)
703                 return NULL;
704
705         /* check type of constantpool entry */
706
707         if (c->cptags[pos] != ctype) {
708                 exceptions_throw_classformaterror(c, "Illegal constant pool index");
709                 return NULL;
710         }
711                 
712         return c->cpinfos[pos];
713 }
714
715
716 /* class_free ******************************************************************
717
718    Frees all resources used by the class.
719
720 *******************************************************************************/
721
722 void class_free(classinfo *c)
723 {
724         s4 i;
725         vftbl_t *v;
726
727 #if defined(ENABLE_JITCACHE)
728 /* TODO: Find a way around the linker problem */
729 /*    jitcache_freeclass(c);*/
730 #endif
731
732         class_freecpool(c);
733
734         if (c->interfaces != NULL)
735                 MFREE(c->interfaces, classinfo*, c->interfacescount);
736
737         if (c->fields) {
738                 for (i = 0; i < c->fieldscount; i++)
739                         field_free(&(c->fields[i]));
740                 MFREE(c->fields, fieldinfo, c->fieldscount);
741         }
742         
743         if (c->methods) {
744                 for (i = 0; i < c->methodscount; i++)
745                         method_free(&(c->methods[i]));
746                 MFREE(c->methods, methodinfo, c->methodscount);
747         }
748
749         if ((v = c->vftbl) != NULL) {
750                 if (v->arraydesc)
751                         mem_free(v->arraydesc,sizeof(arraydescriptor));
752                 
753                 for (i = 0; i < v->interfacetablelength; i++) {
754                         MFREE(v->interfacetable[-i], methodptr, v->interfacevftbllength[i]);
755                 }
756                 MFREE(v->interfacevftbllength, s4, v->interfacetablelength);
757
758                 i = sizeof(vftbl_t) + sizeof(methodptr) * (v->vftbllength - 1) +
759                     sizeof(methodptr*) * (v->interfacetablelength -
760                                          (v->interfacetablelength > 0));
761                 v = (vftbl_t*) (((methodptr*) v) -
762                                                 (v->interfacetablelength - 1) * (v->interfacetablelength > 1));
763                 mem_free(v, i);
764         }
765
766         if (c->innerclass)
767                 MFREE(c->innerclass, innerclassinfo, c->innerclasscount);
768
769         /*      if (c->classvftbl)
770                 mem_free(c->header.vftbl, sizeof(vftbl) + sizeof(methodptr)*(c->vftbl->vftbllength-1)); */
771         
772 /*      GCFREE(c); */
773 }
774
775
776 /* get_array_class *************************************************************
777
778    Returns the array class with the given name for the given
779    classloader, or NULL if an exception occurred.
780
781    Note: This function does eager loading. 
782
783 *******************************************************************************/
784
785 static classinfo *get_array_class(utf *name,classloader_t *initloader,
786                                                                                         classloader_t *defloader,bool link)
787 {
788         classinfo *c;
789         
790         /* lookup this class in the classcache */
791         c = classcache_lookup(initloader,name);
792         if (!c)
793                 c = classcache_lookup_defined(defloader,name);
794
795         if (!c) {
796                 /* we have to create it */
797                 c = class_create_classinfo(name);
798                 c = load_newly_created_array(c,initloader);
799                 if (c == NULL)
800                         return NULL;
801         }
802
803         assert(c);
804         assert(c->state & CLASS_LOADED);
805         assert(c->classloader == defloader);
806
807         if (link && !(c->state & CLASS_LINKED))
808                 if (!link_class(c))
809                         return NULL;
810
811         assert(!link || (c->state & CLASS_LINKED));
812
813         return c;
814 }
815
816
817 /* class_array_of **************************************************************
818
819    Returns an array class with the given component class. The array
820    class is dynamically created if neccessary.
821
822 *******************************************************************************/
823
824 classinfo *class_array_of(classinfo *component, bool link)
825 {
826         classloader_t     *cl;
827     s4                 namelen;
828     char              *namebuf;
829         utf               *u;
830         classinfo         *c;
831
832         cl = component->classloader;
833
834     /* Assemble the array class name */
835     namelen = component->name->blength;
836     
837     if (component->name->text[0] == '[') {
838         /* the component is itself an array */
839         namebuf = MNEW(char, namelen + 1);
840         namebuf[0] = '[';
841         MCOPY(namebuf + 1, component->name->text, char, namelen);
842         namelen++;
843     }
844         else {
845         /* the component is a non-array class */
846         namebuf = MNEW(char, namelen + 3);
847         namebuf[0] = '[';
848         namebuf[1] = 'L';
849         MCOPY(namebuf + 2, component->name->text, char, namelen);
850         namebuf[2 + namelen] = ';';
851         namelen += 3;
852     }
853
854         u = utf_new(namebuf, namelen);
855
856         MFREE(namebuf, char, namelen);
857
858         c = get_array_class(u, cl, cl, link);
859
860         return c;
861 }
862
863
864 /* class_multiarray_of *********************************************************
865
866    Returns an array class with the given dimension and element class.
867    The array class is dynamically created if neccessary.
868
869 *******************************************************************************/
870
871 classinfo *class_multiarray_of(s4 dim, classinfo *element, bool link)
872 {
873     s4 namelen;
874     char *namebuf;
875         classinfo *c;
876
877         if (dim < 1) {
878                 log_text("Invalid array dimension requested");
879                 assert(0);
880         }
881
882     /* Assemble the array class name */
883     namelen = element->name->blength;
884     
885     if (element->name->text[0] == '[') {
886         /* the element is itself an array */
887         namebuf = MNEW(char, namelen + dim);
888         memcpy(namebuf + dim, element->name->text, namelen);
889         namelen += dim;
890     }
891     else {
892         /* the element is a non-array class */
893         namebuf = MNEW(char, namelen + 2 + dim);
894         namebuf[dim] = 'L';
895         memcpy(namebuf + dim + 1, element->name->text, namelen);
896         namelen += (2 + dim);
897         namebuf[namelen - 1] = ';';
898     }
899         memset(namebuf, '[', dim);
900
901         utf* u = utf_new(namebuf, namelen);
902
903         MFREE(namebuf, char, namelen);
904
905         c = get_array_class(u,
906                                                 element->classloader,
907                                                 element->classloader,
908                                                 link);
909
910         return c;
911 }
912
913
914 /* class_lookup_classref *******************************************************
915
916    Looks up the constant_classref for a given classname in the classref
917    tables of a class.
918
919    IN:
920        cls..............the class containing the reference
921            name.............the name of the class refered to
922
923     RETURN VALUE:
924            a pointer to a constant_classref, or 
925            NULL if the reference was not found
926    
927 *******************************************************************************/
928
929 constant_classref *class_lookup_classref(classinfo *cls, utf *name)
930 {
931         constant_classref *ref;
932         extra_classref *xref;
933         int count;
934
935         assert(cls);
936         assert(name);
937         assert(!cls->classrefcount || cls->classrefs);
938         
939         /* first search the main classref table */
940         count = cls->classrefcount;
941         ref = cls->classrefs;
942         for (; count; --count, ++ref)
943                 if (ref->name == name)
944                         return ref;
945
946         /* next try the list of extra classrefs */
947         for (xref = cls->extclassrefs; xref; xref = xref->next) {
948                 if (xref->classref.name == name)
949                         return &(xref->classref);
950         }
951
952         /* not found */
953         return NULL;
954 }
955
956
957 /* class_get_classref **********************************************************
958
959    Returns the constant_classref for a given classname.
960
961    IN:
962        cls..............the class containing the reference
963            name.............the name of the class refered to
964
965    RETURN VALUE:
966        a pointer to a constant_classref (never NULL)
967
968    NOTE:
969        The given name is not checked for validity!
970    
971 *******************************************************************************/
972
973 constant_classref *class_get_classref(classinfo *cls, utf *name)
974 {
975         constant_classref *ref;
976         extra_classref *xref;
977
978         assert(cls);
979         assert(name);
980
981         ref = class_lookup_classref(cls,name);
982         if (ref)
983                 return ref;
984
985         xref = NEW(extra_classref);
986         CLASSREF_INIT(xref->classref,cls,name);
987
988         xref->next = cls->extclassrefs;
989         cls->extclassrefs = xref;
990
991         return &(xref->classref);
992 }
993
994
995 /* class_get_self_classref *****************************************************
996
997    Returns the constant_classref to the class itself.
998
999    IN:
1000        cls..............the class containing the reference
1001
1002    RETURN VALUE:
1003        a pointer to a constant_classref (never NULL)
1004
1005 *******************************************************************************/
1006
1007 constant_classref *class_get_self_classref(classinfo *cls)
1008 {
1009         /* XXX this should be done in a faster way. Maybe always make */
1010         /* the classref of index 0 a self reference.                  */
1011         return class_get_classref(cls,cls->name);
1012 }
1013
1014 /* class_get_classref_multiarray_of ********************************************
1015
1016    Returns an array type reference with the given dimension and element class
1017    reference.
1018
1019    IN:
1020        dim..............the requested dimension
1021                             dim must be in [1;255]. This is NOT checked!
1022            ref..............the component class reference
1023
1024    RETURN VALUE:
1025        a pointer to the class reference for the array type
1026
1027    NOTE:
1028        The referer of `ref` is used as the referer for the new classref.
1029
1030 *******************************************************************************/
1031
1032 constant_classref *class_get_classref_multiarray_of(s4 dim, constant_classref *ref)
1033 {
1034     s4 namelen;
1035     char *namebuf;
1036         constant_classref *cr;
1037
1038         assert(ref);
1039         assert(dim >= 1 && dim <= 255);
1040
1041     /* Assemble the array class name */
1042     namelen = ref->name->blength;
1043     
1044     if (ref->name->text[0] == '[') {
1045         /* the element is itself an array */
1046         namebuf = MNEW(char, namelen + dim);
1047         memcpy(namebuf + dim, ref->name->text, namelen);
1048         namelen += dim;
1049     }
1050     else {
1051         /* the element is a non-array class */
1052         namebuf = MNEW(char, namelen + 2 + dim);
1053         namebuf[dim] = 'L';
1054         memcpy(namebuf + dim + 1, ref->name->text, namelen);
1055         namelen += (2 + dim);
1056         namebuf[namelen - 1] = ';';
1057     }
1058         memset(namebuf, '[', dim);
1059
1060         utf* u = utf_new(namebuf, namelen);
1061
1062         MFREE(namebuf, char, namelen);
1063
1064     cr = class_get_classref(ref->referer, u);
1065
1066         return cr;
1067 }
1068
1069
1070 /* class_get_classref_component_of *********************************************
1071
1072    Returns the component classref of a given array type reference
1073
1074    IN:
1075        ref..............the array type reference
1076
1077    RETURN VALUE:
1078        a reference to the component class, or
1079            NULL if `ref` is not an object array type reference
1080
1081    NOTE:
1082        The referer of `ref` is used as the referer for the new classref.
1083
1084 *******************************************************************************/
1085
1086 constant_classref *class_get_classref_component_of(constant_classref *ref)
1087 {
1088         s4 namelen;
1089         char *name;
1090         
1091         assert(ref);
1092
1093         name = ref->name->text;
1094         if (*name++ != '[')
1095                 return NULL;
1096         
1097         namelen = ref->name->blength - 1;
1098         if (*name == 'L') {
1099                 name++;
1100                 namelen -= 2;
1101         }
1102         else if (*name != '[') {
1103                 return NULL;
1104         }
1105
1106     return class_get_classref(ref->referer, utf_new(name, namelen));
1107 }
1108
1109
1110 /* class_findmethod ************************************************************
1111         
1112    Searches a 'classinfo' structure for a method having the given name
1113    and descriptor. If descriptor is NULL, it is ignored.
1114
1115 *******************************************************************************/
1116
1117 methodinfo *class_findmethod(classinfo *c, utf *name, utf *desc)
1118 {
1119         methodinfo *m;
1120         s4          i;
1121
1122         for (i = 0; i < c->methodscount; i++) {
1123                 m = &(c->methods[i]);
1124
1125                 if ((m->name == name) && ((desc == NULL) || (m->descriptor == desc)))
1126                         return m;
1127         }
1128
1129         return NULL;
1130 }
1131
1132
1133 /* class_resolvemethod *********************************************************
1134         
1135    Searches a class and it's super classes for a method.
1136
1137    Superinterfaces are *not* searched.
1138
1139 *******************************************************************************/
1140
1141 methodinfo *class_resolvemethod(classinfo *c, utf *name, utf *desc)
1142 {
1143         methodinfo *m;
1144
1145         while (c) {
1146                 m = class_findmethod(c, name, desc);
1147
1148                 if (m)
1149                         return m;
1150
1151                 /* JVM Specification bug: 
1152
1153                    It is important NOT to resolve special <init> and <clinit>
1154                    methods to super classes or interfaces; yet, this is not
1155                    explicited in the specification.  Section 5.4.3.3 should be
1156                    updated appropriately.  */
1157
1158                 if (name == utf_init || name == utf_clinit)
1159                         return NULL;
1160
1161                 c = c->super;
1162         }
1163
1164         return NULL;
1165 }
1166
1167
1168 /* class_resolveinterfacemethod_intern *****************************************
1169
1170    Internally used helper function. Do not use this directly.
1171
1172 *******************************************************************************/
1173
1174 static methodinfo *class_resolveinterfacemethod_intern(classinfo *c,
1175                                                                                                            utf *name, utf *desc)
1176 {
1177         methodinfo *m;
1178         s4          i;
1179
1180         /* try to find the method in the class */
1181
1182         m = class_findmethod(c, name, desc);
1183
1184         if (m != NULL)
1185                 return m;
1186
1187         /* No method found?  Try the super interfaces. */
1188
1189         for (i = 0; i < c->interfacescount; i++) {
1190                 m = class_resolveinterfacemethod_intern(c->interfaces[i], name, desc);
1191
1192                 if (m != NULL)
1193                         return m;
1194         }
1195
1196         /* no method found */
1197
1198         return NULL;
1199 }
1200
1201
1202 /* class_resolveclassmethod ****************************************************
1203         
1204    Resolves a reference from REFERER to a method with NAME and DESC in
1205    class C.
1206
1207    If the method cannot be resolved the return value is NULL. If
1208    EXCEPT is true *exceptionptr is set, too.
1209
1210 *******************************************************************************/
1211
1212 methodinfo *class_resolveclassmethod(classinfo *c, utf *name, utf *desc,
1213                                                                          classinfo *referer, bool throwexception)
1214 {
1215         classinfo  *cls;
1216         methodinfo *m;
1217         s4          i;
1218
1219 /*      if (c->flags & ACC_INTERFACE) { */
1220 /*              if (throwexception) */
1221 /*                      *exceptionptr = */
1222 /*                              new_exception(string_java_lang_IncompatibleClassChangeError); */
1223 /*              return NULL; */
1224 /*      } */
1225
1226         /* try class c and its superclasses */
1227
1228         cls = c;
1229
1230         m = class_resolvemethod(cls, name, desc);
1231
1232         if (m != NULL)
1233                 goto found;
1234
1235         /* Try the super interfaces. */
1236
1237         for (i = 0; i < c->interfacescount; i++) {
1238                 m = class_resolveinterfacemethod_intern(c->interfaces[i], name, desc);
1239
1240                 if (m != NULL)
1241                         goto found;
1242         }
1243         
1244         if (throwexception)
1245                 exceptions_throw_nosuchmethoderror(c, name, desc);
1246
1247         return NULL;
1248
1249  found:
1250         if ((m->flags & ACC_ABSTRACT) && !(c->flags & ACC_ABSTRACT)) {
1251                 if (throwexception)
1252                         exceptions_throw_abstractmethoderror();
1253
1254                 return NULL;
1255         }
1256
1257         /* XXX check access rights */
1258
1259         return m;
1260 }
1261
1262
1263 /* class_resolveinterfacemethod ************************************************
1264
1265    Resolves a reference from REFERER to a method with NAME and DESC in
1266    interface C.
1267
1268    If the method cannot be resolved the return value is NULL. If
1269    EXCEPT is true *exceptionptr is set, too.
1270
1271 *******************************************************************************/
1272
1273 methodinfo *class_resolveinterfacemethod(classinfo *c, utf *name, utf *desc,
1274                                                                                  classinfo *referer, bool throwexception)
1275 {
1276         methodinfo *mi;
1277
1278         if (!(c->flags & ACC_INTERFACE)) {
1279                 if (throwexception)
1280                         exceptions_throw_incompatibleclasschangeerror(c, "Not an interface");
1281
1282                 return NULL;
1283         }
1284
1285         mi = class_resolveinterfacemethod_intern(c, name, desc);
1286
1287         if (mi != NULL)
1288                 return mi;
1289
1290         /* try class java.lang.Object */
1291
1292         mi = class_findmethod(class_java_lang_Object, name, desc);
1293
1294         if (mi != NULL)
1295                 return mi;
1296
1297         if (throwexception)
1298                 exceptions_throw_nosuchmethoderror(c, name, desc);
1299
1300         return NULL;
1301 }
1302
1303
1304 /* class_findfield *************************************************************
1305         
1306    Searches for field with specified name and type in a classinfo
1307    structure. If no such field is found NULL is returned.
1308
1309 *******************************************************************************/
1310
1311 fieldinfo *class_findfield(classinfo *c, utf *name, utf *desc)
1312 {
1313         s4 i;
1314
1315         for (i = 0; i < c->fieldscount; i++)
1316                 if ((c->fields[i].name == name) && (c->fields[i].descriptor == desc))
1317                         return &(c->fields[i]);
1318
1319         if (c->super != NULL)
1320                 return class_findfield(c->super, name, desc);
1321
1322         return NULL;
1323 }
1324
1325
1326 /* class_findfield_approx ******************************************************
1327         
1328    Searches in 'classinfo'-structure for a field with the specified
1329    name.
1330
1331 *******************************************************************************/
1332  
1333 fieldinfo *class_findfield_by_name(classinfo* c, utf* name)
1334 {
1335         for (int32_t i = 0; i < c->fieldscount; i++) {
1336                 fieldinfo* f = &(c->fields[i]);
1337
1338                 if (f->name == name)
1339                         return f;
1340         }
1341
1342         // Field not found.
1343         exceptions_throw_nosuchfielderror(c, name);
1344         return NULL;
1345 }
1346
1347
1348 /****************** Function: class_resolvefield_int ***************************
1349
1350     This is an internally used helper function. Do not use this directly.
1351
1352         Tries to resolve a field having the given name and type.
1353     If the field cannot be resolved, NULL is returned.
1354
1355 *******************************************************************************/
1356
1357 static fieldinfo *class_resolvefield_int(classinfo *c, utf *name, utf *desc)
1358 {
1359         fieldinfo *fi;
1360         s4         i;
1361
1362         /* search for field in class c */
1363
1364         for (i = 0; i < c->fieldscount; i++) { 
1365                 if ((c->fields[i].name == name) && (c->fields[i].descriptor == desc)) {
1366                         return &(c->fields[i]);
1367                 }
1368     }
1369
1370         /* Try super interfaces recursively. */
1371
1372         for (i = 0; i < c->interfacescount; i++) {
1373                 fi = class_resolvefield_int(c->interfaces[i], name, desc);
1374
1375                 if (fi != NULL)
1376                         return fi;
1377         }
1378
1379         /* Try super class. */
1380
1381         if (c->super != NULL)
1382                 return class_resolvefield_int(c->super, name, desc);
1383
1384         /* not found */
1385
1386         return NULL;
1387 }
1388
1389
1390 /********************* Function: class_resolvefield ***************************
1391         
1392         Resolves a reference from REFERER to a field with NAME and DESC in class C.
1393
1394     If the field cannot be resolved, an exception is thrown and the
1395     return value is NULL.
1396
1397 *******************************************************************************/
1398
1399 fieldinfo *class_resolvefield(classinfo *c, utf *name, utf *desc, classinfo *referer)
1400 {
1401         fieldinfo *fi;
1402
1403         fi = class_resolvefield_int(c, name, desc);
1404
1405         if (!fi) {
1406                 exceptions_throw_nosuchfielderror(c, name);
1407                 return NULL;
1408         }
1409
1410         /* XXX check access rights */
1411
1412         return fi;
1413 }
1414
1415
1416 /* class_issubclass ************************************************************
1417
1418    Checks if sub is a descendant of super.
1419         
1420 *******************************************************************************/
1421
1422 bool class_issubclass(classinfo *sub, classinfo *super)
1423 {
1424         classinfo *c;
1425
1426         c = sub;
1427
1428         for (;;) {
1429                 /* We reached java/lang/Object and did not find the requested
1430                    super class. */
1431
1432                 if (c == NULL)
1433                         return false;
1434
1435                 /* We found the requested super class. */
1436
1437                 if (c == super)
1438                         return true;
1439
1440                 c = c->super;
1441         }
1442 }
1443
1444
1445 /* class_isanysubclass *********************************************************
1446
1447    Checks a subclass relation between two classes. Implemented
1448    interfaces are interpreted as super classes.
1449
1450    Return value: 1 ... sub is subclass of super
1451                  0 ... otherwise
1452
1453 *******************************************************************************/
1454
1455 bool class_isanysubclass(classinfo *sub, classinfo *super)
1456 {
1457         uint32_t diffval;
1458         bool     result;
1459
1460         /* This is the trivial case. */
1461
1462         if (sub == super)
1463                 return true;
1464
1465         /* Primitive classes are only subclasses of themselves. */
1466
1467         if (class_is_primitive(sub) || class_is_primitive(super))
1468                 return false;
1469
1470         /* Check for interfaces. */
1471
1472         if (super->flags & ACC_INTERFACE) {
1473                 result = (sub->vftbl->interfacetablelength > super->index) &&
1474                         (sub->vftbl->interfacetable[-super->index] != NULL);
1475         }
1476         else {
1477                 /* java.lang.Object is the only super class of any
1478                    interface. */
1479
1480                 if (sub->flags & ACC_INTERFACE)
1481                         return (super == class_java_lang_Object);
1482
1483                 Mutex_lock(linker_classrenumber_mutex);
1484
1485                 diffval = sub->vftbl->baseval - super->vftbl->baseval;
1486                 result  = diffval <= (uint32_t) super->vftbl->diffval;
1487
1488                 Mutex_unlock(linker_classrenumber_mutex);
1489         }
1490
1491         return result;
1492 }
1493
1494
1495 /* class_is_assignable_from ****************************************************
1496
1497    Return whether an instance of the "from" class parameter would be
1498    an instance of this class "to" as well.
1499
1500    ARGUMENTS:
1501        to ..... class
1502            from ... class
1503
1504    RETURN:
1505        true .... is assignable
1506            false ... is not assignable
1507
1508 *******************************************************************************/
1509
1510 bool class_is_assignable_from(classinfo *to, classinfo *from)
1511 {
1512         if (!(to->state & CLASS_LINKED))
1513                 if (!link_class(to))
1514                         return false;
1515
1516         if (!(from->state & CLASS_LINKED))
1517                 if (!link_class(from))
1518                         return false;
1519
1520         return class_isanysubclass(from, to);
1521 }
1522
1523
1524 /* class_is_instance ***********************************************************
1525
1526    Return if the given Java object is an instance of the given class.
1527
1528    ARGUMENTS:
1529        c ... class
1530            h ... Java object
1531
1532    RETURN:
1533        true .... is instance
1534            false ... is not instance
1535
1536 *******************************************************************************/
1537
1538 bool class_is_instance(classinfo *c, java_handle_t *h)
1539 {
1540         if (!(c->state & CLASS_LINKED))
1541                 if (!link_class(c))
1542                         return false;
1543
1544         return builtin_instanceof(h, c);
1545 }
1546
1547
1548 /* class_get_componenttype *****************************************************
1549
1550    Return the component class of the given class.  If the given class
1551    is not an array, return NULL.
1552
1553 *******************************************************************************/
1554
1555 classinfo *class_get_componenttype(classinfo *c)
1556 {
1557         classinfo       *component;
1558         arraydescriptor *ad;
1559         
1560         /* XXX maybe we could find a way to do this without linking. */
1561         /* This way should be safe and easy, however.                */
1562
1563         if (!(c->state & CLASS_LINKED))
1564                 if (!link_class(c))
1565                         return NULL;
1566
1567         ad = c->vftbl->arraydesc;
1568         
1569         if (ad == NULL)
1570                 return NULL;
1571         
1572         if (ad->arraytype == ARRAYTYPE_OBJECT)
1573                 component = ad->componentvftbl->clazz;
1574         else
1575                 component = Primitive_get_class_by_type(ad->arraytype);
1576                 
1577         return component;
1578 }
1579
1580
1581 /* class_get_declaredclasses ***************************************************
1582
1583    Return an array of declared classes of the given class.
1584
1585 *******************************************************************************/
1586
1587 java_handle_objectarray_t *class_get_declaredclasses(classinfo *c, bool publicOnly)
1588 {
1589         classref_or_classinfo  inner;
1590         classref_or_classinfo  outer;
1591         utf                   *outername;
1592         int                    declaredclasscount;  /* number of declared classes */
1593         int                    pos;                     /* current declared class */
1594         java_handle_objectarray_t *oa;               /* array of declared classes */
1595         int                    i;
1596         classinfo             *ic;
1597
1598         declaredclasscount = 0;
1599
1600         if (!class_is_primitive(c) && !class_is_array(c)) {
1601                 /* Determine number of declared classes. */
1602
1603                 for (i = 0; i < c->innerclasscount; i++) {
1604                         /* Get outer-class.  If the inner-class is not a member
1605                            class, the outer-class is NULL. */
1606
1607                         outer = c->innerclass[i].outer_class;
1608
1609                         if (outer.any == NULL)
1610                                 continue;
1611
1612                         /* Check if outer-class is a classref or a real class and
1613                get the class name from the structure. */
1614
1615                         outername = IS_CLASSREF(outer) ? outer.ref->name : outer.cls->name;
1616
1617                         /* Outer class is this class. */
1618
1619                         if ((outername == c->name) &&
1620                                 ((publicOnly == 0) || (c->innerclass[i].flags & ACC_PUBLIC)))
1621                                 declaredclasscount++;
1622                 }
1623         }
1624
1625         /* Allocate Class[] and check for OOM. */
1626
1627         oa = builtin_anewarray(declaredclasscount, class_java_lang_Class);
1628
1629         if (oa == NULL)
1630                 return NULL;
1631
1632         for (i = 0, pos = 0; i < c->innerclasscount; i++) {
1633                 inner = c->innerclass[i].inner_class;
1634                 outer = c->innerclass[i].outer_class;
1635
1636                 /* Get outer-class.  If the inner-class is not a member class,
1637                    the outer-class is NULL. */
1638
1639                 if (outer.any == NULL)
1640                         continue;
1641
1642                 /* Check if outer_class is a classref or a real class and get
1643                    the class name from the structure. */
1644
1645                 outername = IS_CLASSREF(outer) ? outer.ref->name : outer.cls->name;
1646
1647                 /* Outer class is this class. */
1648
1649                 if ((outername == c->name) &&
1650                         ((publicOnly == 0) || (c->innerclass[i].flags & ACC_PUBLIC))) {
1651
1652                         ic = resolve_classref_or_classinfo_eager(inner, false);
1653
1654                         if (ic == NULL)
1655                                 return NULL;
1656
1657                         if (!(ic->state & CLASS_LINKED))
1658                                 if (!link_class(ic))
1659                                         return NULL;
1660
1661                         LLNI_array_direct(oa, pos++) = (java_object_t *) ic;
1662                 }
1663         }
1664
1665         return oa;
1666 }
1667
1668
1669 /**
1670  * Return an array of declared constructors of the given class.
1671  *
1672  * @param c          class to get the constructors of
1673  * @param publicOnly show only public fields
1674  *
1675  * @return array of java.lang.reflect.Constructor
1676  */
1677 #if defined(ENABLE_JAVASE)
1678 java_handle_objectarray_t *class_get_declaredconstructors(classinfo *c, bool publicOnly)
1679 {
1680         methodinfo*                m;
1681         java_handle_objectarray_t* oa;
1682         java_handle_t*             rc;
1683         int                        count;
1684         int                        index;
1685         int                        i;
1686
1687         /* Determine number of constructors. */
1688
1689         count = 0;
1690
1691         for (i = 0; i < c->methodscount; i++) {
1692                 m = &(c->methods[i]);
1693
1694                 if (((m->flags & ACC_PUBLIC) || (publicOnly == 0)) &&
1695                         (m->name == utf_init))
1696                         count++;
1697         }
1698
1699         /* Create array of constructors. */
1700
1701         oa = builtin_anewarray(count, class_java_lang_reflect_Constructor);
1702
1703         if (oa == NULL)
1704                 return NULL;
1705
1706         /* Get the constructors and store them in the array. */
1707
1708         for (i = 0, index = 0; i < c->methodscount; i++) {
1709                 m = &(c->methods[i]);
1710
1711                 if (((m->flags & ACC_PUBLIC) || (publicOnly == 0)) &&
1712                         (m->name == utf_init)) {
1713                         // Create a java.lang.reflect.Constructor object.
1714
1715                         rc = java_lang_reflect_Constructor_create(m);
1716
1717                         /* Store object into array. */
1718
1719                         array_objectarray_element_set(oa, index, rc);
1720                         index++;
1721                 }
1722         }
1723
1724         return oa;
1725 }
1726 #endif
1727
1728
1729 /* class_get_declaredfields ****************************************************
1730
1731    Return an array of declared fields of the given class.
1732
1733    ARGUMENTS:
1734        c ............ class to get the fields of
1735            publicOnly ... show only public fields
1736
1737    RETURN:
1738        array of java.lang.reflect.Field
1739
1740 *******************************************************************************/
1741
1742 #if defined(ENABLE_JAVASE)
1743 java_handle_objectarray_t *class_get_declaredfields(classinfo *c, bool publicOnly)
1744 {
1745         java_handle_objectarray_t *oa;
1746         fieldinfo                 *f;
1747         java_handle_t             *h;
1748         int                        count;
1749         int                        index;
1750         int                        i;
1751
1752         /* Determine number of fields. */
1753
1754         count = 0;
1755
1756         for (i = 0; i < c->fieldscount; i++)
1757                 if ((c->fields[i].flags & ACC_PUBLIC) || (publicOnly == 0))
1758                         count++;
1759
1760         /* Create array of fields. */
1761
1762         oa = builtin_anewarray(count, class_java_lang_reflect_Field);
1763
1764         if (oa == NULL)
1765                 return NULL;
1766
1767         /* Get the fields and store them in the array. */
1768
1769         for (i = 0, index = 0; i < c->fieldscount; i++) {
1770                 f = &(c->fields[i]);
1771
1772                 if ((f->flags & ACC_PUBLIC) || (publicOnly == 0)) {
1773                         // Create a java.lang.reflect.Field object.
1774
1775                         h = java_lang_reflect_Field_create(f);
1776
1777                         /* Store object into array. */
1778
1779                         array_objectarray_element_set(oa, index, h);
1780                         index++;
1781                 }
1782         }
1783
1784         return oa;
1785 }
1786 #endif
1787
1788
1789 /* class_get_declaredmethods ***************************************************
1790
1791    Return an array of declared methods of the given class.
1792
1793    ARGUMENTS:
1794        c ............ class to get the methods of
1795            publicOnly ... show only public methods
1796
1797    RETURN:
1798        array of java.lang.reflect.Method
1799
1800 *******************************************************************************/
1801
1802 #if defined(ENABLE_JAVASE)
1803 java_handle_objectarray_t *class_get_declaredmethods(classinfo *c, bool publicOnly)
1804 {
1805         java_handle_objectarray_t *oa;         /* result: array of Method-objects */
1806         methodinfo                *m;     /* the current method to be represented */
1807         java_handle_t             *h;
1808         int                        count;
1809         int                        index;
1810         int                        i;
1811
1812         /* JOWENN: array classes do not declare methods according to mauve
1813            test.  It should be considered, if we should return to my old
1814            clone method overriding instead of declaring it as a member
1815            function. */
1816
1817         if (class_is_array(c))
1818                 return builtin_anewarray(0, class_java_lang_reflect_Method);
1819
1820         /* Determine number of methods. */
1821
1822         count = 0;
1823
1824         for (i = 0; i < c->methodscount; i++) {
1825                 m = &(c->methods[i]);
1826
1827                 if (((m->flags & ACC_PUBLIC) || (publicOnly == false)) &&
1828                         ((m->name != utf_init) && (m->name != utf_clinit)) &&
1829                         !(m->flags & ACC_MIRANDA))
1830                         count++;
1831         }
1832
1833         /* Create array of methods. */
1834
1835         oa = builtin_anewarray(count, class_java_lang_reflect_Method);
1836
1837         if (oa == NULL)
1838                 return NULL;
1839
1840         /* Get the methods and store them in the array. */
1841
1842         for (i = 0, index = 0; i < c->methodscount; i++) {
1843                 m = &(c->methods[i]);
1844
1845                 if (((m->flags & ACC_PUBLIC) || (publicOnly == false)) && 
1846                         ((m->name != utf_init) && (m->name != utf_clinit)) &&
1847                         !(m->flags & ACC_MIRANDA)) {
1848                         // Create java.lang.reflect.Method object.
1849
1850                         h = java_lang_reflect_Method_create(m);
1851
1852                         /* Store object into array. */
1853
1854                         array_objectarray_element_set(oa, index, h);
1855                         index++;
1856                 }
1857         }
1858
1859         return oa;
1860 }
1861 #endif
1862
1863
1864 /* class_get_declaringclass ****************************************************
1865
1866    If the class or interface given is a member of another class,
1867    return the declaring class.  For array and primitive classes return
1868    NULL.
1869
1870 *******************************************************************************/
1871
1872 classinfo *class_get_declaringclass(classinfo *c)
1873 {
1874         classref_or_classinfo  cr;
1875         classinfo             *dc;
1876
1877         /* Get declaring class. */
1878
1879         cr = c->declaringclass;
1880
1881         if (cr.any == NULL)
1882                 return NULL;
1883
1884         /* Resolve the class if necessary. */
1885
1886         if (IS_CLASSREF(cr)) {
1887 /*              dc = resolve_classref_eager(cr.ref); */
1888                 dc = resolve_classref_or_classinfo_eager(cr, true);
1889
1890                 if (dc == NULL)
1891                         return NULL;
1892
1893                 /* Store the resolved class in the class structure. */
1894
1895                 cr.cls = dc;
1896         }
1897
1898         dc = cr.cls;
1899
1900         return dc;
1901 }
1902
1903
1904 /* class_get_enclosingclass ****************************************************
1905
1906    Return the enclosing class for the given class.
1907
1908 *******************************************************************************/
1909
1910 classinfo *class_get_enclosingclass(classinfo *c)
1911 {
1912         classref_or_classinfo  cr;
1913         classinfo             *ec;
1914
1915         /* Get enclosing class. */
1916
1917         cr = c->enclosingclass;
1918
1919         if (cr.any == NULL)
1920                 return NULL;
1921
1922         /* Resolve the class if necessary. */
1923
1924         if (IS_CLASSREF(cr)) {
1925 /*              ec = resolve_classref_eager(cr.ref); */
1926                 ec = resolve_classref_or_classinfo_eager(cr, true);
1927
1928                 if (ec == NULL)
1929                         return NULL;
1930
1931                 /* Store the resolved class in the class structure. */
1932
1933                 cr.cls = ec;
1934         }
1935
1936         ec = cr.cls;
1937
1938         return ec;
1939 }
1940
1941
1942 /**
1943  * Return the enclosing constructor as java.lang.reflect.Constructor
1944  * object for the given class.
1945  *
1946  * @param c class to return the enclosing constructor for
1947  *
1948  * @return java.lang.reflect.Constructor object of the enclosing
1949  * constructor
1950  */
1951 #if defined(ENABLE_JAVASE)
1952 java_handle_t* class_get_enclosingconstructor(classinfo *c)
1953 {
1954         methodinfo*    m;
1955         java_handle_t* rc;
1956
1957         m = class_get_enclosingmethod_raw(c);
1958
1959         if (m == NULL)
1960                 return NULL;
1961
1962         /* Check for <init>. */
1963
1964         if (m->name != utf_init)
1965                 return NULL;
1966
1967         // Create a java.lang.reflect.Constructor object.
1968
1969         rc = java_lang_reflect_Constructor_create(m);
1970
1971         return rc;
1972 }
1973 #endif
1974
1975
1976 /* class_get_enclosingmethod ***************************************************
1977
1978    Return the enclosing method for the given class.
1979
1980    IN:
1981        c ... class to return the enclosing method for
1982
1983    RETURN:
1984        methodinfo of the enclosing method
1985
1986 *******************************************************************************/
1987
1988 methodinfo *class_get_enclosingmethod_raw(classinfo *c)
1989 {
1990         constant_nameandtype *cn;
1991         classinfo            *ec;
1992         methodinfo           *m;
1993
1994         /* get enclosing class and method */
1995
1996         ec = class_get_enclosingclass(c);
1997         cn = c->enclosingmethod;
1998
1999         /* check for enclosing class and method */
2000
2001         if (ec == NULL)
2002                 return NULL;
2003
2004         if (cn == NULL)
2005                 return NULL;
2006
2007         /* find method in enclosing class */
2008
2009         m = class_findmethod(ec, cn->name, cn->descriptor);
2010
2011         if (m == NULL) {
2012                 exceptions_throw_internalerror("Enclosing method doesn't exist");
2013                 return NULL;
2014         }
2015
2016         return m;
2017 }
2018
2019
2020 /**
2021  * Return the enclosing method as java.lang.reflect.Method object for
2022  * the given class.
2023  *
2024  * @param c class to return the enclosing method for
2025  *
2026  * @return java.lang.reflect.Method object of the enclosing method
2027  */
2028 #if defined(ENABLE_JAVASE)
2029 java_handle_t* class_get_enclosingmethod(classinfo *c)
2030 {
2031         methodinfo*    m;
2032         java_handle_t* rm;
2033
2034         m = class_get_enclosingmethod_raw(c);
2035
2036         if (m == NULL)
2037                 return NULL;
2038
2039         /* check for <init> */
2040
2041         if (m->name == utf_init)
2042                 return NULL;
2043
2044         // Create a java.lang.reflect.Method object.
2045
2046         rm = java_lang_reflect_Method_create(m);
2047
2048         return rm;
2049 }
2050 #endif
2051
2052
2053 /* class_get_interfaces ********************************************************
2054
2055    Return an array of interfaces of the given class.
2056
2057 *******************************************************************************/
2058
2059 java_handle_objectarray_t *class_get_interfaces(classinfo *c)
2060 {
2061         classinfo                 *ic;
2062         java_handle_objectarray_t *oa;
2063         u4                         i;
2064
2065         if (!(c->state & CLASS_LINKED))
2066                 if (!link_class(c))
2067                         return NULL;
2068
2069         oa = builtin_anewarray(c->interfacescount, class_java_lang_Class);
2070
2071         if (oa == NULL)
2072                 return NULL;
2073
2074         for (i = 0; i < c->interfacescount; i++) {
2075                 ic = c->interfaces[i];
2076
2077                 LLNI_array_direct(oa, i) = (java_object_t *) ic;
2078         }
2079
2080         return oa;
2081 }
2082
2083
2084 /* class_get_annotations *******************************************************
2085
2086    Get the unparsed declared annotations in a byte array
2087    of the given class.
2088
2089    IN:
2090        c........the class of which the annotations should be returned
2091
2092    RETURN VALUE:
2093        The unparsed declared annotations in a byte array
2094        (or NULL if there aren't any).
2095
2096 *******************************************************************************/
2097
2098 java_handle_bytearray_t *class_get_annotations(classinfo *c)
2099 {
2100 #if defined(ENABLE_ANNOTATIONS)
2101         java_handle_t *annotations; /* unparsed annotations */
2102
2103         LLNI_classinfo_field_get(c, annotations, annotations);
2104
2105         return (java_handle_bytearray_t*)annotations;
2106 #else
2107         return NULL;
2108 #endif
2109 }
2110
2111
2112 /* class_get_modifiers *********************************************************
2113
2114    Get the modifier flags of the given class.
2115
2116    IN:
2117        c....the class of which the modifier flags should be returned
2118            ignoreInnerClassesAttrib
2119    RETURN VALUE:
2120        modifier flags
2121
2122 *******************************************************************************/
2123
2124 int32_t class_get_modifiers(classinfo *c, bool ignoreInnerClassesAttrib)
2125 {
2126         classref_or_classinfo  inner;
2127         classref_or_classinfo  outer;
2128         utf                   *innername;
2129         int                    i;
2130
2131         if (!ignoreInnerClassesAttrib && (c->innerclasscount != 0)) {
2132                 /* search for passed class as inner class */
2133
2134                 for (i = 0; i < c->innerclasscount; i++) {
2135                         inner = c->innerclass[i].inner_class;
2136                         outer = c->innerclass[i].outer_class;
2137
2138                         /* Check if inner is a classref or a real class and get
2139                the name of the structure */
2140
2141                         innername = IS_CLASSREF(inner) ? inner.ref->name : inner.cls->name;
2142
2143                         /* innerclass is this class */
2144
2145                         if (innername == c->name) {
2146                                 /* has the class actually an outer class? */
2147
2148                                 if (outer.any)
2149                                         /* return flags got from the outer class file */
2150                                         return c->innerclass[i].flags & ACC_CLASS_REFLECT_MASK;
2151                                 else
2152                                         return c->flags & ACC_CLASS_REFLECT_MASK;
2153                         }
2154                 }
2155         }
2156
2157         /* passed class is no inner class or it was not requested */
2158
2159         return c->flags & ACC_CLASS_REFLECT_MASK;
2160 }
2161
2162
2163 /* class_get_signature *********************************************************
2164
2165    Return the signature of the given class.  For array and primitive
2166    classes return NULL.
2167
2168 *******************************************************************************/
2169
2170 #if defined(ENABLE_JAVASE)
2171 utf *class_get_signature(classinfo *c)
2172 {
2173         /* For array and primitive classes return NULL. */
2174
2175         if (class_is_array(c) || class_is_primitive(c))
2176                 return NULL;
2177
2178         return c->signature;
2179 }
2180 #endif
2181
2182
2183 /* class_printflags ************************************************************
2184
2185    Prints flags of a class.
2186
2187 *******************************************************************************/
2188
2189 #if !defined(NDEBUG)
2190 void class_printflags(classinfo *c)
2191 {
2192         if (c == NULL) {
2193                 printf("NULL");
2194                 return;
2195         }
2196
2197         if (c->flags & ACC_PUBLIC)       printf(" PUBLIC");
2198         if (c->flags & ACC_PRIVATE)      printf(" PRIVATE");
2199         if (c->flags & ACC_PROTECTED)    printf(" PROTECTED");
2200         if (c->flags & ACC_STATIC)       printf(" STATIC");
2201         if (c->flags & ACC_FINAL)        printf(" FINAL");
2202         if (c->flags & ACC_SYNCHRONIZED) printf(" SYNCHRONIZED");
2203         if (c->flags & ACC_VOLATILE)     printf(" VOLATILE");
2204         if (c->flags & ACC_TRANSIENT)    printf(" TRANSIENT");
2205         if (c->flags & ACC_NATIVE)       printf(" NATIVE");
2206         if (c->flags & ACC_INTERFACE)    printf(" INTERFACE");
2207         if (c->flags & ACC_ABSTRACT)     printf(" ABSTRACT");
2208 }
2209 #endif
2210
2211
2212 /* class_print *****************************************************************
2213
2214    Prints classname plus flags.
2215
2216 *******************************************************************************/
2217
2218 #if !defined(NDEBUG)
2219 void class_print(classinfo *c)
2220 {
2221         if (c == NULL) {
2222                 printf("NULL");
2223                 return;
2224         }
2225
2226         utf_display_printable_ascii(c->name);
2227         class_printflags(c);
2228 }
2229 #endif
2230
2231
2232 /* class_classref_print ********************************************************
2233
2234    Prints classname plus referer class.
2235
2236 *******************************************************************************/
2237
2238 #if !defined(NDEBUG)
2239 void class_classref_print(constant_classref *cr)
2240 {
2241         if (cr == NULL) {
2242                 printf("NULL");
2243                 return;
2244         }
2245
2246         utf_display_printable_ascii(cr->name);
2247         printf("(ref.by ");
2248         if (cr->referer)
2249                 class_print(cr->referer);
2250         else
2251                 printf("NULL");
2252         printf(")");
2253 }
2254 #endif
2255
2256
2257 /* class_println ***************************************************************
2258
2259    Prints classname plus flags and new line.
2260
2261 *******************************************************************************/
2262
2263 #if !defined(NDEBUG)
2264 void class_println(classinfo *c)
2265 {
2266         class_print(c);
2267         printf("\n");
2268 }
2269 #endif
2270
2271
2272 /* class_classref_println ******************************************************
2273
2274    Prints classname plus referer class and new line.
2275
2276 *******************************************************************************/
2277
2278 #if !defined(NDEBUG)
2279 void class_classref_println(constant_classref *cr)
2280 {
2281         class_classref_print(cr);
2282         printf("\n");
2283 }
2284 #endif
2285
2286
2287 /* class_classref_or_classinfo_print *******************************************
2288
2289    Prints classname plus referer class.
2290
2291 *******************************************************************************/
2292
2293 #if !defined(NDEBUG)
2294 void class_classref_or_classinfo_print(classref_or_classinfo c)
2295 {
2296         if (c.any == NULL) {
2297                 printf("(classref_or_classinfo) NULL");
2298                 return;
2299         }
2300         if (IS_CLASSREF(c))
2301                 class_classref_print(c.ref);
2302         else
2303                 class_print(c.cls);
2304 }
2305 #endif
2306
2307
2308 /* class_classref_or_classinfo_println *****************************************
2309
2310    Prints classname plus referer class and a newline.
2311
2312 *******************************************************************************/
2313
2314 #if !defined(NDEBUG)
2315 void class_classref_or_classinfo_println(classref_or_classinfo c)
2316 {
2317         class_classref_or_classinfo_print(c);
2318         printf("\n");
2319 }
2320 #endif
2321
2322
2323 /* class_showconstantpool ******************************************************
2324
2325    Dump the constant pool of the given class to stdout.
2326
2327 *******************************************************************************/
2328
2329 #if !defined(NDEBUG)
2330 void class_showconstantpool (classinfo *c) 
2331 {
2332         u4 i;
2333         void* e;
2334
2335         printf ("---- dump of constant pool ----\n");
2336
2337         for (i=0; i<c->cpcount; i++) {
2338                 printf ("#%d:  ", (int) i);
2339                 
2340                 e = c -> cpinfos [i];
2341                 if (e) {
2342                         
2343                         switch (c -> cptags [i]) {
2344                         case CONSTANT_Class:
2345                                 printf ("Classreference -> ");
2346                                 utf_display_printable_ascii ( ((constant_classref*)e) -> name );
2347                                 break;
2348                         case CONSTANT_Fieldref:
2349                                 printf ("Fieldref -> ");
2350                                 field_fieldref_print((constant_FMIref *) e);
2351                                 break;
2352                         case CONSTANT_Methodref:
2353                                 printf ("Methodref -> ");
2354                                 method_methodref_print((constant_FMIref *) e);
2355                                 break;
2356                         case CONSTANT_InterfaceMethodref:
2357                                 printf ("InterfaceMethod -> ");
2358                                 method_methodref_print((constant_FMIref *) e);
2359                                 break;
2360                         case CONSTANT_String:
2361                                 printf ("String -> ");
2362                                 utf_display_printable_ascii (e);
2363                                 break;
2364                         case CONSTANT_Integer:
2365                                 printf ("Integer -> %d", (int) ( ((constant_integer*)e) -> value) );
2366                                 break;
2367                         case CONSTANT_Float:
2368                                 printf ("Float -> %f", ((constant_float*)e) -> value);
2369                                 break;
2370                         case CONSTANT_Double:
2371                                 printf ("Double -> %f", ((constant_double*)e) -> value);
2372                                 break;
2373                         case CONSTANT_Long:
2374                                 printf ("Long -> %ld", (long int) ((constant_long*)e) -> value);
2375                                 break;
2376                         case CONSTANT_NameAndType:
2377                                 {
2378                                         constant_nameandtype *cnt = e;
2379                                         printf ("NameAndType: ");
2380                                         utf_display_printable_ascii (cnt->name);
2381                                         printf (" ");
2382                                         utf_display_printable_ascii (cnt->descriptor);
2383                                 }
2384                                 break;
2385                         case CONSTANT_Utf8:
2386                                 printf ("Utf8 -> ");
2387                                 utf_display_printable_ascii (e);
2388                                 break;
2389                         default: 
2390                                 log_text("Invalid type of ConstantPool-Entry");
2391                                 assert(0);
2392                         }
2393                 }
2394
2395                 printf ("\n");
2396         }
2397 }
2398 #endif /* !defined(NDEBUG) */
2399
2400
2401 /* class_showmethods ***********************************************************
2402
2403    Dump info about the fields and methods of the given class to stdout.
2404
2405 *******************************************************************************/
2406
2407 #if !defined(NDEBUG)
2408 void class_showmethods (classinfo *c)
2409 {
2410         s4 i;
2411         
2412         printf("--------- Fields and Methods ----------------\n");
2413         printf("Flags: ");
2414         class_printflags(c);
2415         printf("\n");
2416
2417         printf("This: ");
2418         utf_display_printable_ascii(c->name);
2419         printf("\n");
2420
2421         if (c->super) {
2422                 printf("Super: ");
2423                 utf_display_printable_ascii(c->super->name);
2424                 printf ("\n");
2425         }
2426
2427         printf("Index: %d\n", c->index);
2428         
2429         printf("Interfaces:\n");        
2430         for (i = 0; i < c->interfacescount; i++) {
2431                 printf("   ");
2432                 utf_display_printable_ascii(c->interfaces[i]->name);
2433                 printf (" (%d)\n", c->interfaces[i]->index);
2434         }
2435
2436         printf("Fields:\n");
2437         for (i = 0; i < c->fieldscount; i++)
2438                 field_println(&(c->fields[i]));
2439
2440         printf("Methods:\n");
2441         for (i = 0; i < c->methodscount; i++) {
2442                 methodinfo *m = &(c->methods[i]);
2443
2444                 if (!(m->flags & ACC_STATIC))
2445                         printf("vftblindex: %d   ", m->vftblindex);
2446
2447                 method_println(m);
2448         }
2449
2450         printf ("Virtual function table:\n");
2451         for (i = 0; i < c->vftbl->vftbllength; i++)
2452                 printf ("entry: %d,  %ld\n", i, (long int) (c->vftbl->table[i]));
2453 }
2454 #endif /* !defined(NDEBUG) */
2455
2456
2457 /*
2458  * These are local overrides for various environment variables in Emacs.
2459  * Please do not remove this and leave it at the end of the file, where
2460  * Emacs will automagically detect them.
2461  * ---------------------------------------------------------------------
2462  * Local variables:
2463  * mode: c
2464  * indent-tabs-mode: t
2465  * c-basic-offset: 4
2466  * tab-width: 4
2467  * End:
2468  * vim:noexpandtab:sw=4:ts=4:
2469  */