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