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