* src/vm/builtin.c: Added fast_subtype_check.
[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_JAVA_RUNTIME_LIBRARY_GNU_CLASSPATH)
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_JAVA_RUNTIME_LIBRARY_OPENJDK)
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_JAVA_RUNTIME_LIBRARY_GNU_CLASSPATH)
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_JAVA_RUNTIME_LIBRARY_GNU_CLASSPATH)
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_JAVA_RUNTIME_LIBRARY_OPENJDK)
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                 result = fast_subtype_check(sub->vftbl, super->vftbl);
1595         }
1596
1597         return result;
1598 }
1599
1600
1601 /* class_is_assignable_from ****************************************************
1602
1603    Return whether an instance of the "from" class parameter would be
1604    an instance of this class "to" as well.
1605
1606    ARGUMENTS:
1607        to ..... class
1608            from ... class
1609
1610    RETURN:
1611        true .... is assignable
1612            false ... is not assignable
1613
1614 *******************************************************************************/
1615
1616 bool class_is_assignable_from(classinfo *to, classinfo *from)
1617 {
1618         if (!(to->state & CLASS_LINKED))
1619                 if (!link_class(to))
1620                         return false;
1621
1622         if (!(from->state & CLASS_LINKED))
1623                 if (!link_class(from))
1624                         return false;
1625
1626         return class_isanysubclass(from, to);
1627 }
1628
1629
1630 /* class_is_instance ***********************************************************
1631
1632    Return if the given Java object is an instance of the given class.
1633
1634    ARGUMENTS:
1635        c ... class
1636            h ... Java object
1637
1638    RETURN:
1639        true .... is instance
1640            false ... is not instance
1641
1642 *******************************************************************************/
1643
1644 bool class_is_instance(classinfo *c, java_handle_t *h)
1645 {
1646         if (!(c->state & CLASS_LINKED))
1647                 if (!link_class(c))
1648                         return false;
1649
1650         return builtin_instanceof(h, c);
1651 }
1652
1653
1654 /* class_get_componenttype *****************************************************
1655
1656    Return the component class of the given class.  If the given class
1657    is not an array, return NULL.
1658
1659 *******************************************************************************/
1660
1661 classinfo *class_get_componenttype(classinfo *c)
1662 {
1663         classinfo       *component;
1664         arraydescriptor *ad;
1665         
1666         /* XXX maybe we could find a way to do this without linking. */
1667         /* This way should be safe and easy, however.                */
1668
1669         if (!(c->state & CLASS_LINKED))
1670                 if (!link_class(c))
1671                         return NULL;
1672
1673         ad = c->vftbl->arraydesc;
1674         
1675         if (ad == NULL)
1676                 return NULL;
1677         
1678         if (ad->arraytype == ARRAYTYPE_OBJECT)
1679                 component = ad->componentvftbl->clazz;
1680         else
1681                 component = primitive_class_get_by_type(ad->arraytype);
1682                 
1683         return component;
1684 }
1685
1686
1687 /* class_get_declaredclasses ***************************************************
1688
1689    Return an array of declared classes of the given class.
1690
1691 *******************************************************************************/
1692
1693 java_handle_objectarray_t *class_get_declaredclasses(classinfo *c, bool publicOnly)
1694 {
1695         classref_or_classinfo  inner;
1696         classref_or_classinfo  outer;
1697         utf                   *outername;
1698         int                    declaredclasscount;  /* number of declared classes */
1699         int                    pos;                     /* current declared class */
1700         java_handle_objectarray_t *oa;               /* array of declared classes */
1701         int                    i;
1702         classinfo             *ic;
1703
1704         declaredclasscount = 0;
1705
1706         if (!class_is_primitive(c) && !class_is_array(c)) {
1707                 /* Determine number of declared classes. */
1708
1709                 for (i = 0; i < c->innerclasscount; i++) {
1710                         /* Get outer-class.  If the inner-class is not a member
1711                            class, the outer-class is NULL. */
1712
1713                         outer = c->innerclass[i].outer_class;
1714
1715                         if (outer.any == NULL)
1716                                 continue;
1717
1718                         /* Check if outer-class is a classref or a real class and
1719                get the class name from the structure. */
1720
1721                         outername = IS_CLASSREF(outer) ? outer.ref->name : outer.cls->name;
1722
1723                         /* Outer class is this class. */
1724
1725                         if ((outername == c->name) &&
1726                                 ((publicOnly == 0) || (c->innerclass[i].flags & ACC_PUBLIC)))
1727                                 declaredclasscount++;
1728                 }
1729         }
1730
1731         /* Allocate Class[] and check for OOM. */
1732
1733         oa = builtin_anewarray(declaredclasscount, class_java_lang_Class);
1734
1735         if (oa == NULL)
1736                 return NULL;
1737
1738         for (i = 0, pos = 0; i < c->innerclasscount; i++) {
1739                 inner = c->innerclass[i].inner_class;
1740                 outer = c->innerclass[i].outer_class;
1741
1742                 /* Get outer-class.  If the inner-class is not a member class,
1743                    the outer-class is NULL. */
1744
1745                 if (outer.any == NULL)
1746                         continue;
1747
1748                 /* Check if outer_class is a classref or a real class and get
1749                    the class name from the structure. */
1750
1751                 outername = IS_CLASSREF(outer) ? outer.ref->name : outer.cls->name;
1752
1753                 /* Outer class is this class. */
1754
1755                 if ((outername == c->name) &&
1756                         ((publicOnly == 0) || (c->innerclass[i].flags & ACC_PUBLIC))) {
1757
1758                         ic = resolve_classref_or_classinfo_eager(inner, false);
1759
1760                         if (ic == NULL)
1761                                 return NULL;
1762
1763                         if (!(ic->state & CLASS_LINKED))
1764                                 if (!link_class(ic))
1765                                         return NULL;
1766
1767                         LLNI_array_direct(oa, pos++) = (java_object_t *) ic;
1768                 }
1769         }
1770
1771         return oa;
1772 }
1773
1774
1775 /**
1776  * Return an array of declared constructors of the given class.
1777  *
1778  * @param c          class to get the constructors of
1779  * @param publicOnly show only public fields
1780  *
1781  * @return array of java.lang.reflect.Constructor
1782  */
1783 #if defined(ENABLE_JAVASE)
1784 java_handle_objectarray_t *class_get_declaredconstructors(classinfo *c, bool publicOnly)
1785 {
1786         methodinfo*                m;
1787         java_handle_objectarray_t* oa;
1788         java_handle_t*             rc;
1789         int                        count;
1790         int                        index;
1791         int                        i;
1792
1793         /* Determine number of constructors. */
1794
1795         count = 0;
1796
1797         for (i = 0; i < c->methodscount; i++) {
1798                 m = &(c->methods[i]);
1799
1800                 if (((m->flags & ACC_PUBLIC) || (publicOnly == 0)) &&
1801                         (m->name == utf_init))
1802                         count++;
1803         }
1804
1805         /* Create array of constructors. */
1806
1807         oa = builtin_anewarray(count, class_java_lang_reflect_Constructor);
1808
1809         if (oa == NULL)
1810                 return NULL;
1811
1812         /* Get the constructors and store them in the array. */
1813
1814         for (i = 0, index = 0; i < c->methodscount; i++) {
1815                 m = &(c->methods[i]);
1816
1817                 if (((m->flags & ACC_PUBLIC) || (publicOnly == 0)) &&
1818                         (m->name == utf_init)) {
1819                         /* Create Constructor object.  This is actualy a
1820                            java_lang_reflect_Constructor pointer, but we use a
1821                            java_handle_t here, because we don't have the header
1822                            available when building vmcore. */
1823
1824                         rc = reflect_constructor_new(m);
1825
1826                         /* Store object into array. */
1827
1828                         array_objectarray_element_set(oa, index, rc);
1829                         index++;
1830                 }
1831         }
1832
1833         return oa;
1834 }
1835 #endif
1836
1837
1838 /* class_get_declaredfields ****************************************************
1839
1840    Return an array of declared fields of the given class.
1841
1842    ARGUMENTS:
1843        c ............ class to get the fields of
1844            publicOnly ... show only public fields
1845
1846    RETURN:
1847        array of java.lang.reflect.Field
1848
1849 *******************************************************************************/
1850
1851 #if defined(ENABLE_JAVASE)
1852 java_handle_objectarray_t *class_get_declaredfields(classinfo *c, bool publicOnly)
1853 {
1854         java_handle_objectarray_t *oa;
1855         fieldinfo                 *f;
1856         java_handle_t             *h;
1857         int                        count;
1858         int                        index;
1859         int                        i;
1860
1861         /* Determine number of fields. */
1862
1863         count = 0;
1864
1865         for (i = 0; i < c->fieldscount; i++)
1866                 if ((c->fields[i].flags & ACC_PUBLIC) || (publicOnly == 0))
1867                         count++;
1868
1869         /* Create array of fields. */
1870
1871         oa = builtin_anewarray(count, class_java_lang_reflect_Field);
1872
1873         if (oa == NULL)
1874                 return NULL;
1875
1876         /* Get the fields and store them in the array. */
1877
1878         for (i = 0, index = 0; i < c->fieldscount; i++) {
1879                 f = &(c->fields[i]);
1880
1881                 if ((f->flags & ACC_PUBLIC) || (publicOnly == 0)) {
1882                         /* Create Field object.  This is actualy a
1883                            java_lang_reflect_Field pointer, but we use a
1884                            java_handle_t here, because we don't have the header
1885                            available when building vmcore. */
1886
1887                         h = reflect_field_new(f);
1888
1889                         /* Store object into array. */
1890
1891                         array_objectarray_element_set(oa, index, h);
1892                         index++;
1893                 }
1894         }
1895
1896         return oa;
1897 }
1898 #endif
1899
1900
1901 /* class_get_declaredmethods ***************************************************
1902
1903    Return an array of declared methods of the given class.
1904
1905    ARGUMENTS:
1906        c ............ class to get the methods of
1907            publicOnly ... show only public methods
1908
1909    RETURN:
1910        array of java.lang.reflect.Method
1911
1912 *******************************************************************************/
1913
1914 #if defined(ENABLE_JAVASE)
1915 java_handle_objectarray_t *class_get_declaredmethods(classinfo *c, bool publicOnly)
1916 {
1917         java_handle_objectarray_t *oa;         /* result: array of Method-objects */
1918         methodinfo                *m;     /* the current method to be represented */
1919         java_handle_t             *h;
1920         int                        count;
1921         int                        index;
1922         int                        i;
1923
1924         /* JOWENN: array classes do not declare methods according to mauve
1925            test.  It should be considered, if we should return to my old
1926            clone method overriding instead of declaring it as a member
1927            function. */
1928
1929         if (class_is_array(c))
1930                 return builtin_anewarray(0, class_java_lang_reflect_Method);
1931
1932         /* Determine number of methods. */
1933
1934         count = 0;
1935
1936         for (i = 0; i < c->methodscount; i++) {
1937                 m = &(c->methods[i]);
1938
1939                 if (((m->flags & ACC_PUBLIC) || (publicOnly == false)) &&
1940                         ((m->name != utf_init) && (m->name != utf_clinit)) &&
1941                         !(m->flags & ACC_MIRANDA))
1942                         count++;
1943         }
1944
1945         /* Create array of methods. */
1946
1947         oa = builtin_anewarray(count, class_java_lang_reflect_Method);
1948
1949         if (oa == NULL)
1950                 return NULL;
1951
1952         /* Get the methods and store them in the array. */
1953
1954         for (i = 0, index = 0; i < c->methodscount; i++) {
1955                 m = &(c->methods[i]);
1956
1957                 if (((m->flags & ACC_PUBLIC) || (publicOnly == false)) && 
1958                         ((m->name != utf_init) && (m->name != utf_clinit)) &&
1959                         !(m->flags & ACC_MIRANDA)) {
1960                         /* Create method object.  This is actualy a
1961                            java_lang_reflect_Method pointer, but we use a
1962                            java_handle_t here, because we don't have the header
1963                            available when building vmcore. */
1964
1965                         h = reflect_method_new(m);
1966
1967                         /* Store object into array. */
1968
1969                         array_objectarray_element_set(oa, index, h);
1970                         index++;
1971                 }
1972         }
1973
1974         return oa;
1975 }
1976 #endif
1977
1978
1979 /* class_get_declaringclass ****************************************************
1980
1981    If the class or interface given is a member of another class,
1982    return the declaring class.  For array and primitive classes return
1983    NULL.
1984
1985 *******************************************************************************/
1986
1987 classinfo *class_get_declaringclass(classinfo *c)
1988 {
1989         classref_or_classinfo  cr;
1990         classinfo             *dc;
1991
1992         /* Get declaring class. */
1993
1994         cr = c->declaringclass;
1995
1996         if (cr.any == NULL)
1997                 return NULL;
1998
1999         /* Resolve the class if necessary. */
2000
2001         if (IS_CLASSREF(cr)) {
2002 /*              dc = resolve_classref_eager(cr.ref); */
2003                 dc = resolve_classref_or_classinfo_eager(cr, true);
2004
2005                 if (dc == NULL)
2006                         return NULL;
2007
2008                 /* Store the resolved class in the class structure. */
2009
2010                 cr.cls = dc;
2011         }
2012
2013         dc = cr.cls;
2014
2015         return dc;
2016 }
2017
2018
2019 /* class_get_enclosingclass ****************************************************
2020
2021    Return the enclosing class for the given class.
2022
2023 *******************************************************************************/
2024
2025 classinfo *class_get_enclosingclass(classinfo *c)
2026 {
2027         classref_or_classinfo  cr;
2028         classinfo             *ec;
2029
2030         /* Get enclosing class. */
2031
2032         cr = c->enclosingclass;
2033
2034         if (cr.any == NULL)
2035                 return NULL;
2036
2037         /* Resolve the class if necessary. */
2038
2039         if (IS_CLASSREF(cr)) {
2040 /*              ec = resolve_classref_eager(cr.ref); */
2041                 ec = resolve_classref_or_classinfo_eager(cr, true);
2042
2043                 if (ec == NULL)
2044                         return NULL;
2045
2046                 /* Store the resolved class in the class structure. */
2047
2048                 cr.cls = ec;
2049         }
2050
2051         ec = cr.cls;
2052
2053         return ec;
2054 }
2055
2056
2057 /**
2058  * Return the enclosing constructor as java.lang.reflect.Constructor
2059  * object for the given class.
2060  *
2061  * @param c class to return the enclosing constructor for
2062  *
2063  * @return java.lang.reflect.Constructor object of the enclosing
2064  * constructor
2065  */
2066 #if defined(ENABLE_JAVASE)
2067 java_handle_t* class_get_enclosingconstructor(classinfo *c)
2068 {
2069         methodinfo*    m;
2070         java_handle_t* rc;
2071
2072         m = class_get_enclosingmethod_raw(c);
2073
2074         if (m == NULL)
2075                 return NULL;
2076
2077         /* Check for <init>. */
2078
2079         if (m->name != utf_init)
2080                 return NULL;
2081
2082         /* Create Constructor object. */
2083
2084         rc = reflect_constructor_new(m);
2085
2086         return rc;
2087 }
2088 #endif
2089
2090
2091 /* class_get_enclosingmethod ***************************************************
2092
2093    Return the enclosing method for the given class.
2094
2095    IN:
2096        c ... class to return the enclosing method for
2097
2098    RETURN:
2099        methodinfo of the enclosing method
2100
2101 *******************************************************************************/
2102
2103 methodinfo *class_get_enclosingmethod_raw(classinfo *c)
2104 {
2105         constant_nameandtype *cn;
2106         classinfo            *ec;
2107         methodinfo           *m;
2108
2109         /* get enclosing class and method */
2110
2111         ec = class_get_enclosingclass(c);
2112         cn = c->enclosingmethod;
2113
2114         /* check for enclosing class and method */
2115
2116         if (ec == NULL)
2117                 return NULL;
2118
2119         if (cn == NULL)
2120                 return NULL;
2121
2122         /* find method in enclosing class */
2123
2124         m = class_findmethod(ec, cn->name, cn->descriptor);
2125
2126         if (m == NULL) {
2127                 exceptions_throw_internalerror("Enclosing method doesn't exist");
2128                 return NULL;
2129         }
2130
2131         return m;
2132 }
2133
2134
2135 /**
2136  * Return the enclosing method as java.lang.reflect.Method object for
2137  * the given class.
2138  *
2139  * @param c class to return the enclosing method for
2140  *
2141  * @return java.lang.reflect.Method object of the enclosing method
2142  */
2143 #if defined(ENABLE_JAVASE)
2144 java_handle_t* class_get_enclosingmethod(classinfo *c)
2145 {
2146         methodinfo*    m;
2147         java_handle_t* rm;
2148
2149         m = class_get_enclosingmethod_raw(c);
2150
2151         if (m == NULL)
2152                 return NULL;
2153
2154         /* check for <init> */
2155
2156         if (m->name == utf_init)
2157                 return NULL;
2158
2159         /* create java.lang.reflect.Method object */
2160
2161         rm = reflect_method_new(m);
2162
2163         return rm;
2164 }
2165 #endif
2166
2167
2168 /* class_get_interfaces ********************************************************
2169
2170    Return an array of interfaces of the given class.
2171
2172 *******************************************************************************/
2173
2174 java_handle_objectarray_t *class_get_interfaces(classinfo *c)
2175 {
2176         classinfo                 *ic;
2177         java_handle_objectarray_t *oa;
2178         u4                         i;
2179
2180         if (!(c->state & CLASS_LINKED))
2181                 if (!link_class(c))
2182                         return NULL;
2183
2184         oa = builtin_anewarray(c->interfacescount, class_java_lang_Class);
2185
2186         if (oa == NULL)
2187                 return NULL;
2188
2189         for (i = 0; i < c->interfacescount; i++) {
2190                 ic = c->interfaces[i];
2191
2192                 LLNI_array_direct(oa, i) = (java_object_t *) ic;
2193         }
2194
2195         return oa;
2196 }
2197
2198
2199 /* class_get_annotations *******************************************************
2200
2201    Get the unparsed declared annotations in a byte array
2202    of the given class.
2203
2204    IN:
2205        c........the class of which the annotations should be returned
2206
2207    RETURN VALUE:
2208        The unparsed declared annotations in a byte array
2209        (or NULL if there aren't any).
2210
2211 *******************************************************************************/
2212
2213 java_handle_bytearray_t *class_get_annotations(classinfo *c)
2214 {
2215 #if defined(ENABLE_ANNOTATIONS)
2216         java_handle_t *annotations; /* unparsed annotations */
2217
2218         LLNI_classinfo_field_get(c, annotations, annotations);
2219
2220         return (java_handle_bytearray_t*)annotations;
2221 #else
2222         return NULL;
2223 #endif
2224 }
2225
2226
2227 /* class_get_modifiers *********************************************************
2228
2229    Get the modifier flags of the given class.
2230
2231    IN:
2232        c....the class of which the modifier flags should be returned
2233            ignoreInnerClassesAttrib
2234    RETURN VALUE:
2235        modifier flags
2236
2237 *******************************************************************************/
2238
2239 int32_t class_get_modifiers(classinfo *c, bool ignoreInnerClassesAttrib)
2240 {
2241         classref_or_classinfo  inner;
2242         classref_or_classinfo  outer;
2243         utf                   *innername;
2244         int                    i;
2245
2246         if (!ignoreInnerClassesAttrib && (c->innerclasscount != 0)) {
2247                 /* search for passed class as inner class */
2248
2249                 for (i = 0; i < c->innerclasscount; i++) {
2250                         inner = c->innerclass[i].inner_class;
2251                         outer = c->innerclass[i].outer_class;
2252
2253                         /* Check if inner is a classref or a real class and get
2254                the name of the structure */
2255
2256                         innername = IS_CLASSREF(inner) ? inner.ref->name : inner.cls->name;
2257
2258                         /* innerclass is this class */
2259
2260                         if (innername == c->name) {
2261                                 /* has the class actually an outer class? */
2262
2263                                 if (outer.any)
2264                                         /* return flags got from the outer class file */
2265                                         return c->innerclass[i].flags & ACC_CLASS_REFLECT_MASK;
2266                                 else
2267                                         return c->flags & ACC_CLASS_REFLECT_MASK;
2268                         }
2269                 }
2270         }
2271
2272         /* passed class is no inner class or it was not requested */
2273
2274         return c->flags & ACC_CLASS_REFLECT_MASK;
2275 }
2276
2277
2278 /* class_get_signature *********************************************************
2279
2280    Return the signature of the given class.  For array and primitive
2281    classes return NULL.
2282
2283 *******************************************************************************/
2284
2285 #if defined(ENABLE_JAVASE)
2286 utf *class_get_signature(classinfo *c)
2287 {
2288         /* For array and primitive classes return NULL. */
2289
2290         if (class_is_array(c) || class_is_primitive(c))
2291                 return NULL;
2292
2293         return c->signature;
2294 }
2295 #endif
2296
2297
2298 /* class_printflags ************************************************************
2299
2300    Prints flags of a class.
2301
2302 *******************************************************************************/
2303
2304 #if !defined(NDEBUG)
2305 void class_printflags(classinfo *c)
2306 {
2307         if (c == NULL) {
2308                 printf("NULL");
2309                 return;
2310         }
2311
2312         if (c->flags & ACC_PUBLIC)       printf(" PUBLIC");
2313         if (c->flags & ACC_PRIVATE)      printf(" PRIVATE");
2314         if (c->flags & ACC_PROTECTED)    printf(" PROTECTED");
2315         if (c->flags & ACC_STATIC)       printf(" STATIC");
2316         if (c->flags & ACC_FINAL)        printf(" FINAL");
2317         if (c->flags & ACC_SYNCHRONIZED) printf(" SYNCHRONIZED");
2318         if (c->flags & ACC_VOLATILE)     printf(" VOLATILE");
2319         if (c->flags & ACC_TRANSIENT)    printf(" TRANSIENT");
2320         if (c->flags & ACC_NATIVE)       printf(" NATIVE");
2321         if (c->flags & ACC_INTERFACE)    printf(" INTERFACE");
2322         if (c->flags & ACC_ABSTRACT)     printf(" ABSTRACT");
2323 }
2324 #endif
2325
2326
2327 /* class_print *****************************************************************
2328
2329    Prints classname plus flags.
2330
2331 *******************************************************************************/
2332
2333 #if !defined(NDEBUG)
2334 void class_print(classinfo *c)
2335 {
2336         if (c == NULL) {
2337                 printf("NULL");
2338                 return;
2339         }
2340
2341         utf_display_printable_ascii(c->name);
2342         class_printflags(c);
2343 }
2344 #endif
2345
2346
2347 /* class_classref_print ********************************************************
2348
2349    Prints classname plus referer class.
2350
2351 *******************************************************************************/
2352
2353 #if !defined(NDEBUG)
2354 void class_classref_print(constant_classref *cr)
2355 {
2356         if (cr == NULL) {
2357                 printf("NULL");
2358                 return;
2359         }
2360
2361         utf_display_printable_ascii(cr->name);
2362         printf("(ref.by ");
2363         if (cr->referer)
2364                 class_print(cr->referer);
2365         else
2366                 printf("NULL");
2367         printf(")");
2368 }
2369 #endif
2370
2371
2372 /* class_println ***************************************************************
2373
2374    Prints classname plus flags and new line.
2375
2376 *******************************************************************************/
2377
2378 #if !defined(NDEBUG)
2379 void class_println(classinfo *c)
2380 {
2381         class_print(c);
2382         printf("\n");
2383 }
2384 #endif
2385
2386
2387 /* class_classref_println ******************************************************
2388
2389    Prints classname plus referer class and new line.
2390
2391 *******************************************************************************/
2392
2393 #if !defined(NDEBUG)
2394 void class_classref_println(constant_classref *cr)
2395 {
2396         class_classref_print(cr);
2397         printf("\n");
2398 }
2399 #endif
2400
2401
2402 /* class_classref_or_classinfo_print *******************************************
2403
2404    Prints classname plus referer class.
2405
2406 *******************************************************************************/
2407
2408 #if !defined(NDEBUG)
2409 void class_classref_or_classinfo_print(classref_or_classinfo c)
2410 {
2411         if (c.any == NULL) {
2412                 printf("(classref_or_classinfo) NULL");
2413                 return;
2414         }
2415         if (IS_CLASSREF(c))
2416                 class_classref_print(c.ref);
2417         else
2418                 class_print(c.cls);
2419 }
2420 #endif
2421
2422
2423 /* class_classref_or_classinfo_println *****************************************
2424
2425    Prints classname plus referer class and a newline.
2426
2427 *******************************************************************************/
2428
2429 #if !defined(NDEBUG)
2430 void class_classref_or_classinfo_println(classref_or_classinfo c)
2431 {
2432         class_classref_or_classinfo_print(c);
2433         printf("\n");
2434 }
2435 #endif
2436
2437
2438 /* class_showconstantpool ******************************************************
2439
2440    Dump the constant pool of the given class to stdout.
2441
2442 *******************************************************************************/
2443
2444 #if !defined(NDEBUG)
2445 void class_showconstantpool (classinfo *c) 
2446 {
2447         u4 i;
2448         voidptr e;
2449
2450         printf ("---- dump of constant pool ----\n");
2451
2452         for (i=0; i<c->cpcount; i++) {
2453                 printf ("#%d:  ", (int) i);
2454                 
2455                 e = c -> cpinfos [i];
2456                 if (e) {
2457                         
2458                         switch (c -> cptags [i]) {
2459                         case CONSTANT_Class:
2460                                 printf ("Classreference -> ");
2461                                 utf_display_printable_ascii ( ((constant_classref*)e) -> name );
2462                                 break;
2463                         case CONSTANT_Fieldref:
2464                                 printf ("Fieldref -> ");
2465                                 field_fieldref_print((constant_FMIref *) e);
2466                                 break;
2467                         case CONSTANT_Methodref:
2468                                 printf ("Methodref -> ");
2469                                 method_methodref_print((constant_FMIref *) e);
2470                                 break;
2471                         case CONSTANT_InterfaceMethodref:
2472                                 printf ("InterfaceMethod -> ");
2473                                 method_methodref_print((constant_FMIref *) e);
2474                                 break;
2475                         case CONSTANT_String:
2476                                 printf ("String -> ");
2477                                 utf_display_printable_ascii (e);
2478                                 break;
2479                         case CONSTANT_Integer:
2480                                 printf ("Integer -> %d", (int) ( ((constant_integer*)e) -> value) );
2481                                 break;
2482                         case CONSTANT_Float:
2483                                 printf ("Float -> %f", ((constant_float*)e) -> value);
2484                                 break;
2485                         case CONSTANT_Double:
2486                                 printf ("Double -> %f", ((constant_double*)e) -> value);
2487                                 break;
2488                         case CONSTANT_Long:
2489                                 {
2490                                         u8 v = ((constant_long*)e) -> value;
2491 #if U8_AVAILABLE
2492                                         printf ("Long -> %ld", (long int) v);
2493 #else
2494                                         printf ("Long -> HI: %ld, LO: %ld\n", 
2495                                                         (long int) v.high, (long int) v.low);
2496 #endif 
2497                                 }
2498                                 break;
2499                         case CONSTANT_NameAndType:
2500                                 {
2501                                         constant_nameandtype *cnt = e;
2502                                         printf ("NameAndType: ");
2503                                         utf_display_printable_ascii (cnt->name);
2504                                         printf (" ");
2505                                         utf_display_printable_ascii (cnt->descriptor);
2506                                 }
2507                                 break;
2508                         case CONSTANT_Utf8:
2509                                 printf ("Utf8 -> ");
2510                                 utf_display_printable_ascii (e);
2511                                 break;
2512                         default: 
2513                                 log_text("Invalid type of ConstantPool-Entry");
2514                                 assert(0);
2515                         }
2516                 }
2517
2518                 printf ("\n");
2519         }
2520 }
2521 #endif /* !defined(NDEBUG) */
2522
2523
2524 /* class_showmethods ***********************************************************
2525
2526    Dump info about the fields and methods of the given class to stdout.
2527
2528 *******************************************************************************/
2529
2530 #if !defined(NDEBUG)
2531 void class_showmethods (classinfo *c)
2532 {
2533         s4 i;
2534         
2535         printf("--------- Fields and Methods ----------------\n");
2536         printf("Flags: ");
2537         class_printflags(c);
2538         printf("\n");
2539
2540         printf("This: ");
2541         utf_display_printable_ascii(c->name);
2542         printf("\n");
2543
2544         if (c->super) {
2545                 printf("Super: ");
2546                 utf_display_printable_ascii(c->super->name);
2547                 printf ("\n");
2548         }
2549
2550         printf("Index: %d\n", c->index);
2551         
2552         printf("Interfaces:\n");        
2553         for (i = 0; i < c->interfacescount; i++) {
2554                 printf("   ");
2555                 utf_display_printable_ascii(c->interfaces[i]->name);
2556                 printf (" (%d)\n", c->interfaces[i]->index);
2557         }
2558
2559         printf("Fields:\n");
2560         for (i = 0; i < c->fieldscount; i++)
2561                 field_println(&(c->fields[i]));
2562
2563         printf("Methods:\n");
2564         for (i = 0; i < c->methodscount; i++) {
2565                 methodinfo *m = &(c->methods[i]);
2566
2567                 if (!(m->flags & ACC_STATIC))
2568                         printf("vftblindex: %d   ", m->vftblindex);
2569
2570                 method_println(m);
2571         }
2572
2573         printf ("Virtual function table:\n");
2574         for (i = 0; i < c->vftbl->vftbllength; i++)
2575                 printf ("entry: %d,  %ld\n", i, (long int) (c->vftbl->table[i]));
2576 }
2577 #endif /* !defined(NDEBUG) */
2578
2579
2580 /*
2581  * These are local overrides for various environment variables in Emacs.
2582  * Please do not remove this and leave it at the end of the file, where
2583  * Emacs will automagically detect them.
2584  * ---------------------------------------------------------------------
2585  * Local variables:
2586  * mode: c
2587  * indent-tabs-mode: t
2588  * c-basic-offset: 4
2589  * tab-width: 4
2590  * End:
2591  * vim:noexpandtab:sw=4:ts=4:
2592  */