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