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