f08f784f5df986ef0154bed20e4c0d4812dfae50
[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.hpp"
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         void* 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, void*, 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 void* 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 void* 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         for (int32_t i = 0; i < c->fieldscount; i++) {
1342                 fieldinfo* f = &(c->fields[i]);
1343
1344                 if (f->name == name)
1345                         return f;
1346         }
1347
1348         // Field not found.
1349         exceptions_throw_nosuchfielderror(c, name);
1350         return NULL;
1351 }
1352
1353
1354 /****************** Function: class_resolvefield_int ***************************
1355
1356     This is an internally used helper function. Do not use this directly.
1357
1358         Tries to resolve a field having the given name and type.
1359     If the field cannot be resolved, NULL is returned.
1360
1361 *******************************************************************************/
1362
1363 static fieldinfo *class_resolvefield_int(classinfo *c, utf *name, utf *desc)
1364 {
1365         fieldinfo *fi;
1366         s4         i;
1367
1368         /* search for field in class c */
1369
1370         for (i = 0; i < c->fieldscount; i++) { 
1371                 if ((c->fields[i].name == name) && (c->fields[i].descriptor == desc)) {
1372                         return &(c->fields[i]);
1373                 }
1374     }
1375
1376         /* Try super interfaces recursively. */
1377
1378         for (i = 0; i < c->interfacescount; i++) {
1379                 fi = class_resolvefield_int(c->interfaces[i], name, desc);
1380
1381                 if (fi != NULL)
1382                         return fi;
1383         }
1384
1385         /* Try super class. */
1386
1387         if (c->super != NULL)
1388                 return class_resolvefield_int(c->super, name, desc);
1389
1390         /* not found */
1391
1392         return NULL;
1393 }
1394
1395
1396 /********************* Function: class_resolvefield ***************************
1397         
1398         Resolves a reference from REFERER to a field with NAME and DESC in class C.
1399
1400     If the field cannot be resolved, an exception is thrown and the
1401     return value is NULL.
1402
1403 *******************************************************************************/
1404
1405 fieldinfo *class_resolvefield(classinfo *c, utf *name, utf *desc, classinfo *referer)
1406 {
1407         fieldinfo *fi;
1408
1409         fi = class_resolvefield_int(c, name, desc);
1410
1411         if (!fi) {
1412                 exceptions_throw_nosuchfielderror(c, name);
1413                 return NULL;
1414         }
1415
1416         /* XXX check access rights */
1417
1418         return fi;
1419 }
1420
1421
1422 /* class_issubclass ************************************************************
1423
1424    Checks if sub is a descendant of super.
1425         
1426 *******************************************************************************/
1427
1428 bool class_issubclass(classinfo *sub, classinfo *super)
1429 {
1430         classinfo *c;
1431
1432         c = sub;
1433
1434         for (;;) {
1435                 /* We reached java/lang/Object and did not find the requested
1436                    super class. */
1437
1438                 if (c == NULL)
1439                         return false;
1440
1441                 /* We found the requested super class. */
1442
1443                 if (c == super)
1444                         return true;
1445
1446                 c = c->super;
1447         }
1448 }
1449
1450
1451 /* class_isanysubclass *********************************************************
1452
1453    Checks a subclass relation between two classes. Implemented
1454    interfaces are interpreted as super classes.
1455
1456    Return value: 1 ... sub is subclass of super
1457                  0 ... otherwise
1458
1459 *******************************************************************************/
1460
1461 bool class_isanysubclass(classinfo *sub, classinfo *super)
1462 {
1463         uint32_t diffval;
1464         bool     result;
1465
1466         /* This is the trivial case. */
1467
1468         if (sub == super)
1469                 return true;
1470
1471         /* Primitive classes are only subclasses of themselves. */
1472
1473         if (class_is_primitive(sub) || class_is_primitive(super))
1474                 return false;
1475
1476         /* Check for interfaces. */
1477
1478         if (super->flags & ACC_INTERFACE) {
1479                 result = (sub->vftbl->interfacetablelength > super->index) &&
1480                         (sub->vftbl->interfacetable[-super->index] != NULL);
1481         }
1482         else {
1483                 /* java.lang.Object is the only super class of any
1484                    interface. */
1485
1486                 if (sub->flags & ACC_INTERFACE)
1487                         return (super == class_java_lang_Object);
1488
1489                 LOCK_MONITOR_ENTER(linker_classrenumber_lock);
1490
1491                 diffval = sub->vftbl->baseval - super->vftbl->baseval;
1492                 result  = diffval <= (uint32_t) super->vftbl->diffval;
1493
1494                 LOCK_MONITOR_EXIT(linker_classrenumber_lock);
1495         }
1496
1497         return result;
1498 }
1499
1500
1501 /* class_is_assignable_from ****************************************************
1502
1503    Return whether an instance of the "from" class parameter would be
1504    an instance of this class "to" as well.
1505
1506    ARGUMENTS:
1507        to ..... class
1508            from ... class
1509
1510    RETURN:
1511        true .... is assignable
1512            false ... is not assignable
1513
1514 *******************************************************************************/
1515
1516 bool class_is_assignable_from(classinfo *to, classinfo *from)
1517 {
1518         if (!(to->state & CLASS_LINKED))
1519                 if (!link_class(to))
1520                         return false;
1521
1522         if (!(from->state & CLASS_LINKED))
1523                 if (!link_class(from))
1524                         return false;
1525
1526         return class_isanysubclass(from, to);
1527 }
1528
1529
1530 /* class_is_instance ***********************************************************
1531
1532    Return if the given Java object is an instance of the given class.
1533
1534    ARGUMENTS:
1535        c ... class
1536            h ... Java object
1537
1538    RETURN:
1539        true .... is instance
1540            false ... is not instance
1541
1542 *******************************************************************************/
1543
1544 bool class_is_instance(classinfo *c, java_handle_t *h)
1545 {
1546         if (!(c->state & CLASS_LINKED))
1547                 if (!link_class(c))
1548                         return false;
1549
1550         return builtin_instanceof(h, c);
1551 }
1552
1553
1554 /* class_get_componenttype *****************************************************
1555
1556    Return the component class of the given class.  If the given class
1557    is not an array, return NULL.
1558
1559 *******************************************************************************/
1560
1561 classinfo *class_get_componenttype(classinfo *c)
1562 {
1563         classinfo       *component;
1564         arraydescriptor *ad;
1565         
1566         /* XXX maybe we could find a way to do this without linking. */
1567         /* This way should be safe and easy, however.                */
1568
1569         if (!(c->state & CLASS_LINKED))
1570                 if (!link_class(c))
1571                         return NULL;
1572
1573         ad = c->vftbl->arraydesc;
1574         
1575         if (ad == NULL)
1576                 return NULL;
1577         
1578         if (ad->arraytype == ARRAYTYPE_OBJECT)
1579                 component = ad->componentvftbl->clazz;
1580         else
1581                 component = Primitive_get_class_by_type(ad->arraytype);
1582                 
1583         return component;
1584 }
1585
1586
1587 /* class_get_declaredclasses ***************************************************
1588
1589    Return an array of declared classes of the given class.
1590
1591 *******************************************************************************/
1592
1593 java_handle_objectarray_t *class_get_declaredclasses(classinfo *c, bool publicOnly)
1594 {
1595         classref_or_classinfo  inner;
1596         classref_or_classinfo  outer;
1597         utf                   *outername;
1598         int                    declaredclasscount;  /* number of declared classes */
1599         int                    pos;                     /* current declared class */
1600         java_handle_objectarray_t *oa;               /* array of declared classes */
1601         int                    i;
1602         classinfo             *ic;
1603
1604         declaredclasscount = 0;
1605
1606         if (!class_is_primitive(c) && !class_is_array(c)) {
1607                 /* Determine number of declared classes. */
1608
1609                 for (i = 0; i < c->innerclasscount; i++) {
1610                         /* Get outer-class.  If the inner-class is not a member
1611                            class, the outer-class is NULL. */
1612
1613                         outer = c->innerclass[i].outer_class;
1614
1615                         if (outer.any == NULL)
1616                                 continue;
1617
1618                         /* Check if outer-class is a classref or a real class and
1619                get the class name from the structure. */
1620
1621                         outername = IS_CLASSREF(outer) ? outer.ref->name : outer.cls->name;
1622
1623                         /* Outer class is this class. */
1624
1625                         if ((outername == c->name) &&
1626                                 ((publicOnly == 0) || (c->innerclass[i].flags & ACC_PUBLIC)))
1627                                 declaredclasscount++;
1628                 }
1629         }
1630
1631         /* Allocate Class[] and check for OOM. */
1632
1633         oa = builtin_anewarray(declaredclasscount, class_java_lang_Class);
1634
1635         if (oa == NULL)
1636                 return NULL;
1637
1638         for (i = 0, pos = 0; i < c->innerclasscount; i++) {
1639                 inner = c->innerclass[i].inner_class;
1640                 outer = c->innerclass[i].outer_class;
1641
1642                 /* Get outer-class.  If the inner-class is not a member class,
1643                    the outer-class is NULL. */
1644
1645                 if (outer.any == NULL)
1646                         continue;
1647
1648                 /* Check if outer_class is a classref or a real class and get
1649                    the class name from the structure. */
1650
1651                 outername = IS_CLASSREF(outer) ? outer.ref->name : outer.cls->name;
1652
1653                 /* Outer class is this class. */
1654
1655                 if ((outername == c->name) &&
1656                         ((publicOnly == 0) || (c->innerclass[i].flags & ACC_PUBLIC))) {
1657
1658                         ic = resolve_classref_or_classinfo_eager(inner, false);
1659
1660                         if (ic == NULL)
1661                                 return NULL;
1662
1663                         if (!(ic->state & CLASS_LINKED))
1664                                 if (!link_class(ic))
1665                                         return NULL;
1666
1667                         LLNI_array_direct(oa, pos++) = (java_object_t *) ic;
1668                 }
1669         }
1670
1671         return oa;
1672 }
1673
1674
1675 /**
1676  * Return an array of declared constructors of the given class.
1677  *
1678  * @param c          class to get the constructors of
1679  * @param publicOnly show only public fields
1680  *
1681  * @return array of java.lang.reflect.Constructor
1682  */
1683 #if defined(ENABLE_JAVASE)
1684 java_handle_objectarray_t *class_get_declaredconstructors(classinfo *c, bool publicOnly)
1685 {
1686         methodinfo*                m;
1687         java_handle_objectarray_t* oa;
1688         java_handle_t*             rc;
1689         int                        count;
1690         int                        index;
1691         int                        i;
1692
1693         /* Determine number of constructors. */
1694
1695         count = 0;
1696
1697         for (i = 0; i < c->methodscount; i++) {
1698                 m = &(c->methods[i]);
1699
1700                 if (((m->flags & ACC_PUBLIC) || (publicOnly == 0)) &&
1701                         (m->name == utf_init))
1702                         count++;
1703         }
1704
1705         /* Create array of constructors. */
1706
1707         oa = builtin_anewarray(count, class_java_lang_reflect_Constructor);
1708
1709         if (oa == NULL)
1710                 return NULL;
1711
1712         /* Get the constructors and store them in the array. */
1713
1714         for (i = 0, index = 0; i < c->methodscount; i++) {
1715                 m = &(c->methods[i]);
1716
1717                 if (((m->flags & ACC_PUBLIC) || (publicOnly == 0)) &&
1718                         (m->name == utf_init)) {
1719                         /* Create Constructor object.  This is actualy a
1720                            java_lang_reflect_Constructor pointer, but we use a
1721                            java_handle_t here, because we don't have the header
1722                            available when building vmcore. */
1723
1724                         rc = reflect_constructor_new(m);
1725
1726                         /* Store object into array. */
1727
1728                         array_objectarray_element_set(oa, index, rc);
1729                         index++;
1730                 }
1731         }
1732
1733         return oa;
1734 }
1735 #endif
1736
1737
1738 /* class_get_declaredfields ****************************************************
1739
1740    Return an array of declared fields of the given class.
1741
1742    ARGUMENTS:
1743        c ............ class to get the fields of
1744            publicOnly ... show only public fields
1745
1746    RETURN:
1747        array of java.lang.reflect.Field
1748
1749 *******************************************************************************/
1750
1751 #if defined(ENABLE_JAVASE)
1752 java_handle_objectarray_t *class_get_declaredfields(classinfo *c, bool publicOnly)
1753 {
1754         java_handle_objectarray_t *oa;
1755         fieldinfo                 *f;
1756         java_handle_t             *h;
1757         int                        count;
1758         int                        index;
1759         int                        i;
1760
1761         /* Determine number of fields. */
1762
1763         count = 0;
1764
1765         for (i = 0; i < c->fieldscount; i++)
1766                 if ((c->fields[i].flags & ACC_PUBLIC) || (publicOnly == 0))
1767                         count++;
1768
1769         /* Create array of fields. */
1770
1771         oa = builtin_anewarray(count, class_java_lang_reflect_Field);
1772
1773         if (oa == NULL)
1774                 return NULL;
1775
1776         /* Get the fields and store them in the array. */
1777
1778         for (i = 0, index = 0; i < c->fieldscount; i++) {
1779                 f = &(c->fields[i]);
1780
1781                 if ((f->flags & ACC_PUBLIC) || (publicOnly == 0)) {
1782                         /* Create Field object.  This is actualy a
1783                            java_lang_reflect_Field pointer, but we use a
1784                            java_handle_t here, because we don't have the header
1785                            available when building vmcore. */
1786
1787                         h = reflect_field_new(f);
1788
1789                         /* Store object into array. */
1790
1791                         array_objectarray_element_set(oa, index, h);
1792                         index++;
1793                 }
1794         }
1795
1796         return oa;
1797 }
1798 #endif
1799
1800
1801 /* class_get_declaredmethods ***************************************************
1802
1803    Return an array of declared methods of the given class.
1804
1805    ARGUMENTS:
1806        c ............ class to get the methods of
1807            publicOnly ... show only public methods
1808
1809    RETURN:
1810        array of java.lang.reflect.Method
1811
1812 *******************************************************************************/
1813
1814 #if defined(ENABLE_JAVASE)
1815 java_handle_objectarray_t *class_get_declaredmethods(classinfo *c, bool publicOnly)
1816 {
1817         java_handle_objectarray_t *oa;         /* result: array of Method-objects */
1818         methodinfo                *m;     /* the current method to be represented */
1819         java_handle_t             *h;
1820         int                        count;
1821         int                        index;
1822         int                        i;
1823
1824         /* JOWENN: array classes do not declare methods according to mauve
1825            test.  It should be considered, if we should return to my old
1826            clone method overriding instead of declaring it as a member
1827            function. */
1828
1829         if (class_is_array(c))
1830                 return builtin_anewarray(0, class_java_lang_reflect_Method);
1831
1832         /* Determine number of methods. */
1833
1834         count = 0;
1835
1836         for (i = 0; i < c->methodscount; i++) {
1837                 m = &(c->methods[i]);
1838
1839                 if (((m->flags & ACC_PUBLIC) || (publicOnly == false)) &&
1840                         ((m->name != utf_init) && (m->name != utf_clinit)) &&
1841                         !(m->flags & ACC_MIRANDA))
1842                         count++;
1843         }
1844
1845         /* Create array of methods. */
1846
1847         oa = builtin_anewarray(count, class_java_lang_reflect_Method);
1848
1849         if (oa == NULL)
1850                 return NULL;
1851
1852         /* Get the methods and store them in the array. */
1853
1854         for (i = 0, index = 0; i < c->methodscount; i++) {
1855                 m = &(c->methods[i]);
1856
1857                 if (((m->flags & ACC_PUBLIC) || (publicOnly == false)) && 
1858                         ((m->name != utf_init) && (m->name != utf_clinit)) &&
1859                         !(m->flags & ACC_MIRANDA)) {
1860                         /* Create method object.  This is actualy a
1861                            java_lang_reflect_Method pointer, but we use a
1862                            java_handle_t here, because we don't have the header
1863                            available when building vmcore. */
1864
1865                         h = reflect_method_new(m);
1866
1867                         /* Store object into array. */
1868
1869                         array_objectarray_element_set(oa, index, h);
1870                         index++;
1871                 }
1872         }
1873
1874         return oa;
1875 }
1876 #endif
1877
1878
1879 /* class_get_declaringclass ****************************************************
1880
1881    If the class or interface given is a member of another class,
1882    return the declaring class.  For array and primitive classes return
1883    NULL.
1884
1885 *******************************************************************************/
1886
1887 classinfo *class_get_declaringclass(classinfo *c)
1888 {
1889         classref_or_classinfo  cr;
1890         classinfo             *dc;
1891
1892         /* Get declaring class. */
1893
1894         cr = c->declaringclass;
1895
1896         if (cr.any == NULL)
1897                 return NULL;
1898
1899         /* Resolve the class if necessary. */
1900
1901         if (IS_CLASSREF(cr)) {
1902 /*              dc = resolve_classref_eager(cr.ref); */
1903                 dc = resolve_classref_or_classinfo_eager(cr, true);
1904
1905                 if (dc == NULL)
1906                         return NULL;
1907
1908                 /* Store the resolved class in the class structure. */
1909
1910                 cr.cls = dc;
1911         }
1912
1913         dc = cr.cls;
1914
1915         return dc;
1916 }
1917
1918
1919 /* class_get_enclosingclass ****************************************************
1920
1921    Return the enclosing class for the given class.
1922
1923 *******************************************************************************/
1924
1925 classinfo *class_get_enclosingclass(classinfo *c)
1926 {
1927         classref_or_classinfo  cr;
1928         classinfo             *ec;
1929
1930         /* Get enclosing class. */
1931
1932         cr = c->enclosingclass;
1933
1934         if (cr.any == NULL)
1935                 return NULL;
1936
1937         /* Resolve the class if necessary. */
1938
1939         if (IS_CLASSREF(cr)) {
1940 /*              ec = resolve_classref_eager(cr.ref); */
1941                 ec = resolve_classref_or_classinfo_eager(cr, true);
1942
1943                 if (ec == NULL)
1944                         return NULL;
1945
1946                 /* Store the resolved class in the class structure. */
1947
1948                 cr.cls = ec;
1949         }
1950
1951         ec = cr.cls;
1952
1953         return ec;
1954 }
1955
1956
1957 /**
1958  * Return the enclosing constructor as java.lang.reflect.Constructor
1959  * object for the given class.
1960  *
1961  * @param c class to return the enclosing constructor for
1962  *
1963  * @return java.lang.reflect.Constructor object of the enclosing
1964  * constructor
1965  */
1966 #if defined(ENABLE_JAVASE)
1967 java_handle_t* class_get_enclosingconstructor(classinfo *c)
1968 {
1969         methodinfo*    m;
1970         java_handle_t* rc;
1971
1972         m = class_get_enclosingmethod_raw(c);
1973
1974         if (m == NULL)
1975                 return NULL;
1976
1977         /* Check for <init>. */
1978
1979         if (m->name != utf_init)
1980                 return NULL;
1981
1982         /* Create Constructor object. */
1983
1984         rc = reflect_constructor_new(m);
1985
1986         return rc;
1987 }
1988 #endif
1989
1990
1991 /* class_get_enclosingmethod ***************************************************
1992
1993    Return the enclosing method for the given class.
1994
1995    IN:
1996        c ... class to return the enclosing method for
1997
1998    RETURN:
1999        methodinfo of the enclosing method
2000
2001 *******************************************************************************/
2002
2003 methodinfo *class_get_enclosingmethod_raw(classinfo *c)
2004 {
2005         constant_nameandtype *cn;
2006         classinfo            *ec;
2007         methodinfo           *m;
2008
2009         /* get enclosing class and method */
2010
2011         ec = class_get_enclosingclass(c);
2012         cn = c->enclosingmethod;
2013
2014         /* check for enclosing class and method */
2015
2016         if (ec == NULL)
2017                 return NULL;
2018
2019         if (cn == NULL)
2020                 return NULL;
2021
2022         /* find method in enclosing class */
2023
2024         m = class_findmethod(ec, cn->name, cn->descriptor);
2025
2026         if (m == NULL) {
2027                 exceptions_throw_internalerror("Enclosing method doesn't exist");
2028                 return NULL;
2029         }
2030
2031         return m;
2032 }
2033
2034
2035 /**
2036  * Return the enclosing method as java.lang.reflect.Method object for
2037  * the given class.
2038  *
2039  * @param c class to return the enclosing method for
2040  *
2041  * @return java.lang.reflect.Method object of the enclosing method
2042  */
2043 #if defined(ENABLE_JAVASE)
2044 java_handle_t* class_get_enclosingmethod(classinfo *c)
2045 {
2046         methodinfo*    m;
2047         java_handle_t* rm;
2048
2049         m = class_get_enclosingmethod_raw(c);
2050
2051         if (m == NULL)
2052                 return NULL;
2053
2054         /* check for <init> */
2055
2056         if (m->name == utf_init)
2057                 return NULL;
2058
2059         /* create java.lang.reflect.Method object */
2060
2061         rm = reflect_method_new(m);
2062
2063         return rm;
2064 }
2065 #endif
2066
2067
2068 /* class_get_interfaces ********************************************************
2069
2070    Return an array of interfaces of the given class.
2071
2072 *******************************************************************************/
2073
2074 java_handle_objectarray_t *class_get_interfaces(classinfo *c)
2075 {
2076         classinfo                 *ic;
2077         java_handle_objectarray_t *oa;
2078         u4                         i;
2079
2080         if (!(c->state & CLASS_LINKED))
2081                 if (!link_class(c))
2082                         return NULL;
2083
2084         oa = builtin_anewarray(c->interfacescount, class_java_lang_Class);
2085
2086         if (oa == NULL)
2087                 return NULL;
2088
2089         for (i = 0; i < c->interfacescount; i++) {
2090                 ic = c->interfaces[i];
2091
2092                 LLNI_array_direct(oa, i) = (java_object_t *) ic;
2093         }
2094
2095         return oa;
2096 }
2097
2098
2099 /* class_get_annotations *******************************************************
2100
2101    Get the unparsed declared annotations in a byte array
2102    of the given class.
2103
2104    IN:
2105        c........the class of which the annotations should be returned
2106
2107    RETURN VALUE:
2108        The unparsed declared annotations in a byte array
2109        (or NULL if there aren't any).
2110
2111 *******************************************************************************/
2112
2113 java_handle_bytearray_t *class_get_annotations(classinfo *c)
2114 {
2115 #if defined(ENABLE_ANNOTATIONS)
2116         java_handle_t *annotations; /* unparsed annotations */
2117
2118         LLNI_classinfo_field_get(c, annotations, annotations);
2119
2120         return (java_handle_bytearray_t*)annotations;
2121 #else
2122         return NULL;
2123 #endif
2124 }
2125
2126
2127 /* class_get_modifiers *********************************************************
2128
2129    Get the modifier flags of the given class.
2130
2131    IN:
2132        c....the class of which the modifier flags should be returned
2133            ignoreInnerClassesAttrib
2134    RETURN VALUE:
2135        modifier flags
2136
2137 *******************************************************************************/
2138
2139 int32_t class_get_modifiers(classinfo *c, bool ignoreInnerClassesAttrib)
2140 {
2141         classref_or_classinfo  inner;
2142         classref_or_classinfo  outer;
2143         utf                   *innername;
2144         int                    i;
2145
2146         if (!ignoreInnerClassesAttrib && (c->innerclasscount != 0)) {
2147                 /* search for passed class as inner class */
2148
2149                 for (i = 0; i < c->innerclasscount; i++) {
2150                         inner = c->innerclass[i].inner_class;
2151                         outer = c->innerclass[i].outer_class;
2152
2153                         /* Check if inner is a classref or a real class and get
2154                the name of the structure */
2155
2156                         innername = IS_CLASSREF(inner) ? inner.ref->name : inner.cls->name;
2157
2158                         /* innerclass is this class */
2159
2160                         if (innername == c->name) {
2161                                 /* has the class actually an outer class? */
2162
2163                                 if (outer.any)
2164                                         /* return flags got from the outer class file */
2165                                         return c->innerclass[i].flags & ACC_CLASS_REFLECT_MASK;
2166                                 else
2167                                         return c->flags & ACC_CLASS_REFLECT_MASK;
2168                         }
2169                 }
2170         }
2171
2172         /* passed class is no inner class or it was not requested */
2173
2174         return c->flags & ACC_CLASS_REFLECT_MASK;
2175 }
2176
2177
2178 /* class_get_signature *********************************************************
2179
2180    Return the signature of the given class.  For array and primitive
2181    classes return NULL.
2182
2183 *******************************************************************************/
2184
2185 #if defined(ENABLE_JAVASE)
2186 utf *class_get_signature(classinfo *c)
2187 {
2188         /* For array and primitive classes return NULL. */
2189
2190         if (class_is_array(c) || class_is_primitive(c))
2191                 return NULL;
2192
2193         return c->signature;
2194 }
2195 #endif
2196
2197
2198 /* class_printflags ************************************************************
2199
2200    Prints flags of a class.
2201
2202 *******************************************************************************/
2203
2204 #if !defined(NDEBUG)
2205 void class_printflags(classinfo *c)
2206 {
2207         if (c == NULL) {
2208                 printf("NULL");
2209                 return;
2210         }
2211
2212         if (c->flags & ACC_PUBLIC)       printf(" PUBLIC");
2213         if (c->flags & ACC_PRIVATE)      printf(" PRIVATE");
2214         if (c->flags & ACC_PROTECTED)    printf(" PROTECTED");
2215         if (c->flags & ACC_STATIC)       printf(" STATIC");
2216         if (c->flags & ACC_FINAL)        printf(" FINAL");
2217         if (c->flags & ACC_SYNCHRONIZED) printf(" SYNCHRONIZED");
2218         if (c->flags & ACC_VOLATILE)     printf(" VOLATILE");
2219         if (c->flags & ACC_TRANSIENT)    printf(" TRANSIENT");
2220         if (c->flags & ACC_NATIVE)       printf(" NATIVE");
2221         if (c->flags & ACC_INTERFACE)    printf(" INTERFACE");
2222         if (c->flags & ACC_ABSTRACT)     printf(" ABSTRACT");
2223 }
2224 #endif
2225
2226
2227 /* class_print *****************************************************************
2228
2229    Prints classname plus flags.
2230
2231 *******************************************************************************/
2232
2233 #if !defined(NDEBUG)
2234 void class_print(classinfo *c)
2235 {
2236         if (c == NULL) {
2237                 printf("NULL");
2238                 return;
2239         }
2240
2241         utf_display_printable_ascii(c->name);
2242         class_printflags(c);
2243 }
2244 #endif
2245
2246
2247 /* class_classref_print ********************************************************
2248
2249    Prints classname plus referer class.
2250
2251 *******************************************************************************/
2252
2253 #if !defined(NDEBUG)
2254 void class_classref_print(constant_classref *cr)
2255 {
2256         if (cr == NULL) {
2257                 printf("NULL");
2258                 return;
2259         }
2260
2261         utf_display_printable_ascii(cr->name);
2262         printf("(ref.by ");
2263         if (cr->referer)
2264                 class_print(cr->referer);
2265         else
2266                 printf("NULL");
2267         printf(")");
2268 }
2269 #endif
2270
2271
2272 /* class_println ***************************************************************
2273
2274    Prints classname plus flags and new line.
2275
2276 *******************************************************************************/
2277
2278 #if !defined(NDEBUG)
2279 void class_println(classinfo *c)
2280 {
2281         class_print(c);
2282         printf("\n");
2283 }
2284 #endif
2285
2286
2287 /* class_classref_println ******************************************************
2288
2289    Prints classname plus referer class and new line.
2290
2291 *******************************************************************************/
2292
2293 #if !defined(NDEBUG)
2294 void class_classref_println(constant_classref *cr)
2295 {
2296         class_classref_print(cr);
2297         printf("\n");
2298 }
2299 #endif
2300
2301
2302 /* class_classref_or_classinfo_print *******************************************
2303
2304    Prints classname plus referer class.
2305
2306 *******************************************************************************/
2307
2308 #if !defined(NDEBUG)
2309 void class_classref_or_classinfo_print(classref_or_classinfo c)
2310 {
2311         if (c.any == NULL) {
2312                 printf("(classref_or_classinfo) NULL");
2313                 return;
2314         }
2315         if (IS_CLASSREF(c))
2316                 class_classref_print(c.ref);
2317         else
2318                 class_print(c.cls);
2319 }
2320 #endif
2321
2322
2323 /* class_classref_or_classinfo_println *****************************************
2324
2325    Prints classname plus referer class and a newline.
2326
2327 *******************************************************************************/
2328
2329 #if !defined(NDEBUG)
2330 void class_classref_or_classinfo_println(classref_or_classinfo c)
2331 {
2332         class_classref_or_classinfo_print(c);
2333         printf("\n");
2334 }
2335 #endif
2336
2337
2338 /* class_showconstantpool ******************************************************
2339
2340    Dump the constant pool of the given class to stdout.
2341
2342 *******************************************************************************/
2343
2344 #if !defined(NDEBUG)
2345 void class_showconstantpool (classinfo *c) 
2346 {
2347         u4 i;
2348         void* e;
2349
2350         printf ("---- dump of constant pool ----\n");
2351
2352         for (i=0; i<c->cpcount; i++) {
2353                 printf ("#%d:  ", (int) i);
2354                 
2355                 e = c -> cpinfos [i];
2356                 if (e) {
2357                         
2358                         switch (c -> cptags [i]) {
2359                         case CONSTANT_Class:
2360                                 printf ("Classreference -> ");
2361                                 utf_display_printable_ascii ( ((constant_classref*)e) -> name );
2362                                 break;
2363                         case CONSTANT_Fieldref:
2364                                 printf ("Fieldref -> ");
2365                                 field_fieldref_print((constant_FMIref *) e);
2366                                 break;
2367                         case CONSTANT_Methodref:
2368                                 printf ("Methodref -> ");
2369                                 method_methodref_print((constant_FMIref *) e);
2370                                 break;
2371                         case CONSTANT_InterfaceMethodref:
2372                                 printf ("InterfaceMethod -> ");
2373                                 method_methodref_print((constant_FMIref *) e);
2374                                 break;
2375                         case CONSTANT_String:
2376                                 printf ("String -> ");
2377                                 utf_display_printable_ascii (e);
2378                                 break;
2379                         case CONSTANT_Integer:
2380                                 printf ("Integer -> %d", (int) ( ((constant_integer*)e) -> value) );
2381                                 break;
2382                         case CONSTANT_Float:
2383                                 printf ("Float -> %f", ((constant_float*)e) -> value);
2384                                 break;
2385                         case CONSTANT_Double:
2386                                 printf ("Double -> %f", ((constant_double*)e) -> value);
2387                                 break;
2388                         case CONSTANT_Long:
2389                                 {
2390                                         u8 v = ((constant_long*)e) -> value;
2391 #if U8_AVAILABLE
2392                                         printf ("Long -> %ld", (long int) v);
2393 #else
2394                                         printf ("Long -> HI: %ld, LO: %ld\n", 
2395                                                         (long int) v.high, (long int) v.low);
2396 #endif 
2397                                 }
2398                                 break;
2399                         case CONSTANT_NameAndType:
2400                                 {
2401                                         constant_nameandtype *cnt = e;
2402                                         printf ("NameAndType: ");
2403                                         utf_display_printable_ascii (cnt->name);
2404                                         printf (" ");
2405                                         utf_display_printable_ascii (cnt->descriptor);
2406                                 }
2407                                 break;
2408                         case CONSTANT_Utf8:
2409                                 printf ("Utf8 -> ");
2410                                 utf_display_printable_ascii (e);
2411                                 break;
2412                         default: 
2413                                 log_text("Invalid type of ConstantPool-Entry");
2414                                 assert(0);
2415                         }
2416                 }
2417
2418                 printf ("\n");
2419         }
2420 }
2421 #endif /* !defined(NDEBUG) */
2422
2423
2424 /* class_showmethods ***********************************************************
2425
2426    Dump info about the fields and methods of the given class to stdout.
2427
2428 *******************************************************************************/
2429
2430 #if !defined(NDEBUG)
2431 void class_showmethods (classinfo *c)
2432 {
2433         s4 i;
2434         
2435         printf("--------- Fields and Methods ----------------\n");
2436         printf("Flags: ");
2437         class_printflags(c);
2438         printf("\n");
2439
2440         printf("This: ");
2441         utf_display_printable_ascii(c->name);
2442         printf("\n");
2443
2444         if (c->super) {
2445                 printf("Super: ");
2446                 utf_display_printable_ascii(c->super->name);
2447                 printf ("\n");
2448         }
2449
2450         printf("Index: %d\n", c->index);
2451         
2452         printf("Interfaces:\n");        
2453         for (i = 0; i < c->interfacescount; i++) {
2454                 printf("   ");
2455                 utf_display_printable_ascii(c->interfaces[i]->name);
2456                 printf (" (%d)\n", c->interfaces[i]->index);
2457         }
2458
2459         printf("Fields:\n");
2460         for (i = 0; i < c->fieldscount; i++)
2461                 field_println(&(c->fields[i]));
2462
2463         printf("Methods:\n");
2464         for (i = 0; i < c->methodscount; i++) {
2465                 methodinfo *m = &(c->methods[i]);
2466
2467                 if (!(m->flags & ACC_STATIC))
2468                         printf("vftblindex: %d   ", m->vftblindex);
2469
2470                 method_println(m);
2471         }
2472
2473         printf ("Virtual function table:\n");
2474         for (i = 0; i < c->vftbl->vftbllength; i++)
2475                 printf ("entry: %d,  %ld\n", i, (long int) (c->vftbl->table[i]));
2476 }
2477 #endif /* !defined(NDEBUG) */
2478
2479
2480 /*
2481  * These are local overrides for various environment variables in Emacs.
2482  * Please do not remove this and leave it at the end of the file, where
2483  * Emacs will automagically detect them.
2484  * ---------------------------------------------------------------------
2485  * Local variables:
2486  * mode: c
2487  * indent-tabs-mode: t
2488  * c-basic-offset: 4
2489  * tab-width: 4
2490  * End:
2491  * vim:noexpandtab:sw=4:ts=4:
2492  */