Merged revisions 8137-8178 via svnmerge from
[cacao.git] / src / vmcore / class.c
1 /* src/vmcore/class.c - class related functions
2
3    Copyright (C) 1996-2005, 2006, 2007 R. Grafl, A. Krall, C. Kruegel,
4    C. Oates, R. Obermaisser, M. Platter, M. Probst, S. Ring,
5    E. Steiner, C. Thalinger, D. Thuernbeck, P. Tomsich, C. Ullrich,
6    J. Wenninger, Institut f. Computersprachen - TU Wien
7
8    This file is part of CACAO.
9
10    This program is free software; you can redistribute it and/or
11    modify it under the terms of the GNU General Public License as
12    published by the Free Software Foundation; either version 2, or (at
13    your option) any later version.
14
15    This program is distributed in the hope that it will be useful, but
16    WITHOUT ANY WARRANTY; without even the implied warranty of
17    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
18    General Public License for more details.
19
20    You should have received a copy of the GNU General Public License
21    along with this program; if not, write to the Free Software
22    Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
23    02110-1301, USA.
24
25    $Id: class.c 8179 2007-07-05 11:21:08Z michi $
26
27 */
28
29
30 #include "config.h"
31
32 #include <assert.h>
33 #include <stdio.h>
34 #include <stdlib.h>
35 #include <string.h>
36
37 #include "vm/types.h"
38
39 #include "arch.h"
40
41 #include "mm/memory.h"
42
43 #include "threads/lock-common.h"
44
45 #include "toolbox/logging.h"
46
47 #include "vm/exceptions.h"
48 #include "vm/global.h"
49
50 #include "vm/jit/asmpart.h"
51
52 #include "vmcore/class.h"
53 #include "vmcore/classcache.h"
54 #include "vmcore/loader.h"
55 #include "vmcore/options.h"
56
57 #if defined(ENABLE_STATISTICS)
58 # include "vmcore/statistics.h"
59 #endif
60
61 #include "vmcore/suck.h"
62 #include "vmcore/utf8.h"
63
64
65 /* global variables ***********************************************************/
66
67 list_t unlinkedclasses;                 /* this is only used for eager class  */
68                                         /* loading                            */
69
70
71 /* frequently used classes ****************************************************/
72
73 /* important system classes */
74
75 classinfo *class_java_lang_Object;
76 classinfo *class_java_lang_Class;
77 classinfo *class_java_lang_ClassLoader;
78 classinfo *class_java_lang_Cloneable;
79 classinfo *class_java_lang_SecurityManager;
80 classinfo *class_java_lang_String;
81 classinfo *class_java_lang_System;
82 classinfo *class_java_lang_Thread;
83 classinfo *class_java_lang_ThreadGroup;
84 classinfo *class_java_lang_VMSystem;
85 classinfo *class_java_lang_VMThread;
86 classinfo *class_java_io_Serializable;
87
88
89 /* system exception classes required in cacao */
90
91 classinfo *class_java_lang_Throwable;
92 classinfo *class_java_lang_Error;
93 classinfo *class_java_lang_LinkageError;
94 classinfo *class_java_lang_NoClassDefFoundError;
95 classinfo *class_java_lang_OutOfMemoryError;
96 classinfo *class_java_lang_VirtualMachineError;
97
98 #if defined(WITH_CLASSPATH_GNU)
99 classinfo *class_java_lang_VMThrowable;
100 #endif
101
102 classinfo *class_java_lang_Exception;
103 classinfo *class_java_lang_ClassCastException;
104 classinfo *class_java_lang_ClassNotFoundException;
105
106 #if defined(ENABLE_JAVASE)
107 classinfo *class_java_lang_Void;
108 #endif
109 classinfo *class_java_lang_Boolean;
110 classinfo *class_java_lang_Byte;
111 classinfo *class_java_lang_Character;
112 classinfo *class_java_lang_Short;
113 classinfo *class_java_lang_Integer;
114 classinfo *class_java_lang_Long;
115 classinfo *class_java_lang_Float;
116 classinfo *class_java_lang_Double;
117
118
119 /* some runtime exception */
120
121 classinfo *class_java_lang_NullPointerException;
122
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
134 classinfo *arrayclass_java_lang_Object;
135 #endif
136
137
138 /* pseudo classes for the typechecker */
139
140 classinfo *pseudo_class_Arraystub;
141 classinfo *pseudo_class_Null;
142 classinfo *pseudo_class_New;
143
144
145 /* class_set_packagename *******************************************************
146
147    Derive the package name from the class name and store it in the struct.
148
149 *******************************************************************************/
150
151 void class_set_packagename(classinfo *c)
152 {
153         char *p = UTF_END(c->name) - 1;
154         char *start = c->name->text;
155
156         /* set the package name */
157         /* classes in the unnamed package keep packagename == NULL */
158
159         if (c->name->text[0] == '[') {
160                 /* set packagename of arrays to the element's package */
161
162                 for (; *start == '['; start++);
163
164                 /* skip the 'L' in arrays of references */
165                 if (*start == 'L')
166                         start++;
167
168                 for (; (p > start) && (*p != '/'); --p);
169
170                 c->packagename = utf_new(start, p - start);
171
172         } else {
173                 for (; (p > start) && (*p != '/'); --p);
174
175                 c->packagename = utf_new(start, p - start);
176         }
177 }
178
179
180 /* class_create_classinfo ******************************************************
181
182    Create a new classinfo struct. The class name is set to the given utf *,
183    most other fields are initialized to zero.
184
185    Note: classname may be NULL. In this case a not-yet-named classinfo is
186          created. The name must be filled in later and class_set_packagename
187                  must be called after that.
188
189 *******************************************************************************/
190
191 classinfo *class_create_classinfo(utf *classname)
192 {
193         classinfo *c;
194
195 #if defined(ENABLE_STATISTICS)
196         if (opt_stat)
197                 size_classinfo += sizeof(classinfo);
198 #endif
199
200         /* we use a safe name for temporarily unnamed classes */
201
202         if (classname == NULL)
203                 classname = utf_not_named_yet;
204
205 #if !defined(NDEBUG)
206         if (initverbose)
207                 log_message_utf("Creating class: ", classname);
208 #endif
209
210         /* GCNEW_UNCOLLECTABLE clears the allocated memory */
211
212 #if defined(ENABLE_GC_CACAO)
213         c = (classinfo *) heap_alloc_uncollectable(sizeof(classinfo));
214 #else
215         c = GCNEW_UNCOLLECTABLE(classinfo, 1);
216         /*c=NEW(classinfo);*/
217 #endif
218         c->name = classname;
219
220         /* Set the header.vftbl of all loaded classes to the one of
221        java.lang.Class, so Java code can use a class as object. */
222
223         if (class_java_lang_Class != NULL)
224                 if (class_java_lang_Class->vftbl != NULL)
225                         c->object.header.vftbl = class_java_lang_Class->vftbl;
226
227 #if defined(ENABLE_JAVASE)
228         /* check if the class is a reference class and flag it */
229
230         if (classname == utf_java_lang_ref_SoftReference) {
231                 c->flags |= ACC_CLASS_REFERENCE_SOFT;
232         }
233         else if (classname == utf_java_lang_ref_WeakReference) {
234                 c->flags |= ACC_CLASS_REFERENCE_WEAK;
235         }
236         else if (classname == utf_java_lang_ref_PhantomReference) {
237                 c->flags |= ACC_CLASS_REFERENCE_PHANTOM;
238         }
239 #endif
240
241         if (classname != utf_not_named_yet)
242                 class_set_packagename(c);
243
244         LOCK_INIT_OBJECT_LOCK(&c->object.header);
245
246         return c;
247 }
248
249
250 /* class_postset_header_vftbl **************************************************
251
252    Set the header.vftbl of all classes created before java.lang.Class
253    was linked.  This is necessary that Java code can use a class as
254    object.
255
256 *******************************************************************************/
257
258 void class_postset_header_vftbl(void)
259 {
260         classinfo *c;
261         u4 slot;
262         classcache_name_entry *nmen;
263         classcache_class_entry *clsen;
264
265         assert(class_java_lang_Class);
266
267         for (slot = 0; slot < hashtable_classcache.size; slot++) {
268                 nmen = (classcache_name_entry *) hashtable_classcache.ptr[slot];
269
270                 for (; nmen; nmen = nmen->hashlink) {
271                         /* iterate over all class entries */
272
273                         for (clsen = nmen->classes; clsen; clsen = clsen->next) {
274                                 c = clsen->classobj;
275
276                                 /* now set the the vftbl */
277
278                                 if (c->object.header.vftbl == NULL)
279                                         c->object.header.vftbl = class_java_lang_Class->vftbl;
280                         }
281                 }
282         }
283 }
284
285 /* class_define ****************************************************************
286
287    Calls the loader and defines a class in the VM.
288
289 *******************************************************************************/
290
291 classinfo *class_define(utf *name, classloader *cl, s4 length, u1 *data)
292 {
293         classinfo   *c;
294         classinfo   *r;
295         classbuffer *cb;
296
297         if (name != NULL) {
298                 /* check if this class has already been defined */
299
300                 c = classcache_lookup_defined_or_initiated(cl, name);
301
302                 if (c != NULL) {
303                         exceptions_throw_linkageerror("duplicate class definition: ", c);
304                         return NULL;
305                 }
306         } 
307
308         /* create a new classinfo struct */
309
310         c = class_create_classinfo(name);
311
312 #if defined(ENABLE_STATISTICS)
313         /* measure time */
314
315         if (opt_getloadingtime)
316                 loadingtime_start();
317 #endif
318
319         /* build a classbuffer with the given data */
320
321         cb = NEW(classbuffer);
322
323         cb->class = c;
324         cb->size  = length;
325         cb->data  = data;
326         cb->pos   = cb->data;
327
328         /* preset the defining classloader */
329
330         c->classloader = cl;
331
332         /* load the class from this buffer */
333
334         r = load_class_from_classbuffer(cb);
335
336         /* free memory */
337
338         FREE(cb, classbuffer);
339
340 #if defined(ENABLE_STATISTICS)
341         /* measure time */
342
343         if (opt_getloadingtime)
344                 loadingtime_stop();
345 #endif
346
347         if (r == NULL) {
348                 /* If return value is NULL, we had a problem and the class is
349                    not loaded.  Now free the allocated memory, otherwise we
350                    could run into a DOS. */
351
352                 class_free(c);
353
354                 return NULL;
355         }
356
357         /* Store the newly defined class in the class cache. This call
358            also checks whether a class of the same name has already been
359            defined by the same defining loader, and if so, replaces the
360            newly created class by the one defined earlier. */
361
362         /* Important: The classinfo given to classcache_store must be
363                       fully prepared because another thread may return
364                       this pointer after the lookup at to top of this
365                       function directly after the class cache lock has
366                       been released. */
367
368         c = classcache_store(cl, c, true);
369
370         return c;
371 }
372
373
374 /* class_load_attribute_sourcefile *********************************************
375
376    SourceFile_attribute {
377        u2 attribute_name_index;
378        u4 attribute_length;
379            u2 sourcefile_index;
380    }
381
382 *******************************************************************************/
383
384 static bool class_load_attribute_sourcefile(classbuffer *cb)
385 {
386         classinfo *c;
387         u4         attribute_length;
388         u2         sourcefile_index;
389         utf       *sourcefile;
390
391         /* get classinfo */
392
393         c = cb->class;
394
395         /* check buffer size */
396
397         if (!suck_check_classbuffer_size(cb, 4 + 2))
398                 return false;
399
400         /* check attribute length */
401
402         attribute_length = suck_u4(cb);
403
404         if (attribute_length != 2) {
405                 exceptions_throw_classformaterror(c, "Wrong size for VALUE attribute");
406                 return false;
407         }
408
409         /* there can be no more than one SourceFile attribute */
410
411         if (c->sourcefile != NULL) {
412                 exceptions_throw_classformaterror(c, "Multiple SourceFile attributes");
413                 return false;
414         }
415
416         /* get sourcefile */
417
418         sourcefile_index = suck_u2(cb);
419         sourcefile = class_getconstant(c, sourcefile_index, CONSTANT_Utf8);
420
421         if (sourcefile == NULL)
422                 return false;
423
424         /* store sourcefile */
425
426         c->sourcefile = sourcefile;
427
428         return true;
429 }
430
431
432 /* class_load_attribute_enclosingmethod ****************************************
433
434    EnclosingMethod_attribute {
435        u2 attribute_name_index;
436        u4 attribute_length;
437            u2 class_index;
438            u2 method_index;
439    }
440
441 *******************************************************************************/
442
443 #if defined(ENABLE_JAVASE)
444 static bool class_load_attribute_enclosingmethod(classbuffer *cb)
445 {
446         classinfo             *c;
447         u4                     attribute_length;
448         u2                     class_index;
449         u2                     method_index;
450         classref_or_classinfo  cr;
451         constant_nameandtype  *cn;
452
453         /* get classinfo */
454
455         c = cb->class;
456
457         /* check buffer size */
458
459         if (!suck_check_classbuffer_size(cb, 4 + 2 + 2))
460                 return false;
461
462         /* check attribute length */
463
464         attribute_length = suck_u4(cb);
465
466         if (attribute_length != 4) {
467                 exceptions_throw_classformaterror(c, "Wrong size for VALUE attribute");
468                 return false;
469         }
470
471         /* there can be no more than one EnclosingMethod attribute */
472
473         if (c->enclosingmethod != NULL) {
474                 exceptions_throw_classformaterror(c, "Multiple EnclosingMethod attributes");
475                 return false;
476         }
477
478         /* get class index */
479
480         class_index = suck_u2(cb);
481         cr.ref = innerclass_getconstant(c, class_index, CONSTANT_Class);
482
483         /* get method index */
484
485         method_index = suck_u2(cb);
486         cn = innerclass_getconstant(c, method_index, CONSTANT_NameAndType);
487
488         /* store info in classinfo */
489
490         c->enclosingclass.any = cr.any;
491         c->enclosingmethod    = cn;
492
493         return true;
494 }
495 #endif /* defined(ENABLE_JAVASE) */
496
497
498 /* class_load_attributes *******************************************************
499
500    Read attributes from ClassFile.
501
502    attribute_info {
503        u2 attribute_name_index;
504        u4 attribute_length;
505        u1 info[attribute_length];
506    }
507
508    InnerClasses_attribute {
509        u2 attribute_name_index;
510        u4 attribute_length;
511    }
512
513 *******************************************************************************/
514
515 bool class_load_attributes(classbuffer *cb)
516 {
517         classinfo *c;
518         u4         i, j;
519         u2         attributes_count;
520         u2         attribute_name_index;
521         utf       *attribute_name;
522
523         c = cb->class;
524
525         /* get attributes count */
526
527         if (!suck_check_classbuffer_size(cb, 2))
528                 return false;
529
530         attributes_count = suck_u2(cb);
531
532         for (i = 0; i < attributes_count; i++) {
533                 /* get attribute name */
534
535                 if (!suck_check_classbuffer_size(cb, 2))
536                         return false;
537
538                 attribute_name_index = suck_u2(cb);
539                 attribute_name =
540                         class_getconstant(c, attribute_name_index, CONSTANT_Utf8);
541
542                 if (attribute_name == NULL)
543                         return false;
544
545                 if (attribute_name == utf_InnerClasses) {
546                         /* InnerClasses */
547
548                         if (c->innerclass != NULL) {
549                                 exceptions_throw_classformaterror(c, "Multiple InnerClasses attributes");
550                                 return false;
551                         }
552                                 
553                         if (!suck_check_classbuffer_size(cb, 4 + 2))
554                                 return false;
555
556                         /* skip attribute length */
557                         suck_u4(cb);
558
559                         /* number of records */
560                         c->innerclasscount = suck_u2(cb);
561
562                         if (!suck_check_classbuffer_size(cb, (2 + 2 + 2 + 2) * c->innerclasscount))
563                                 return false;
564
565                         /* allocate memory for innerclass structure */
566                         c->innerclass = MNEW(innerclassinfo, c->innerclasscount);
567
568                         for (j = 0; j < c->innerclasscount; j++) {
569                                 /* The innerclass structure contains a class with an encoded
570                                    name, its defining scope, its simple name and a bitmask of
571                                    the access flags. If an inner class is not a member, its
572                                    outer_class is NULL, if a class is anonymous, its name is
573                                    NULL. */
574                                                                 
575                                 innerclassinfo *info = c->innerclass + j;
576
577                                 info->inner_class.ref =
578                                         innerclass_getconstant(c, suck_u2(cb), CONSTANT_Class);
579                                 info->outer_class.ref =
580                                         innerclass_getconstant(c, suck_u2(cb), CONSTANT_Class);
581                                 info->name =
582                                         innerclass_getconstant(c, suck_u2(cb), CONSTANT_Utf8);
583                                 info->flags = suck_u2(cb);
584                         }
585                 }
586                 else if (attribute_name == utf_SourceFile) {
587                         /* SourceFile */
588
589                         if (!class_load_attribute_sourcefile(cb))
590                                 return false;
591                 }
592 #if defined(ENABLE_JAVASE)
593                 else if (attribute_name == utf_EnclosingMethod) {
594                         /* EnclosingMethod */
595
596                         if (!class_load_attribute_enclosingmethod(cb))
597                                 return false;
598                 }
599                 else if (attribute_name == utf_Signature) {
600                         /* Signature */
601
602                         if (!loader_load_attribute_signature(cb, &(c->signature)))
603                                 return false;
604                 }
605 #if 0
606                 /* XXX We can't do a release with that enabled */
607
608                 else if (attribute_name == utf_RuntimeVisibleAnnotations) {
609                         /* RuntimeVisibleAnnotations */
610
611                         if (!annotation_load_attribute_runtimevisibleannotations(cb))
612                                 return false;
613                 }
614 #endif
615 #endif
616                 else {
617                         /* unknown attribute */
618
619                         if (!loader_skip_attribute_body(cb))
620                                 return false;
621                 }
622         }
623
624         return true;
625 }
626
627
628 /* class_freepool **************************************************************
629
630         Frees all resources used by this classes Constant Pool.
631
632 *******************************************************************************/
633
634 static void class_freecpool(classinfo *c)
635 {
636         u4 idx;
637         u4 tag;
638         voidptr info;
639         
640         if (c->cptags && c->cpinfos) {
641                 for (idx = 0; idx < c->cpcount; idx++) {
642                         tag = c->cptags[idx];
643                         info = c->cpinfos[idx];
644                 
645                         if (info != NULL) {
646                                 switch (tag) {
647                                 case CONSTANT_Fieldref:
648                                 case CONSTANT_Methodref:
649                                 case CONSTANT_InterfaceMethodref:
650                                         FREE(info, constant_FMIref);
651                                         break;
652                                 case CONSTANT_Integer:
653                                         FREE(info, constant_integer);
654                                         break;
655                                 case CONSTANT_Float:
656                                         FREE(info, constant_float);
657                                         break;
658                                 case CONSTANT_Long:
659                                         FREE(info, constant_long);
660                                         break;
661                                 case CONSTANT_Double:
662                                         FREE(info, constant_double);
663                                         break;
664                                 case CONSTANT_NameAndType:
665                                         FREE(info, constant_nameandtype);
666                                         break;
667                                 }
668                         }
669                 }
670         }
671
672         if (c->cptags)
673                 MFREE(c->cptags, u1, c->cpcount);
674
675         if (c->cpinfos)
676                 MFREE(c->cpinfos, voidptr, c->cpcount);
677 }
678
679
680 /* class_getconstant ***********************************************************
681
682    Retrieves the value at position 'pos' of the constantpool of a
683    class. If the type of the value is other than 'ctype', an error is
684    thrown.
685
686 *******************************************************************************/
687
688 voidptr class_getconstant(classinfo *c, u4 pos, u4 ctype)
689 {
690         /* check index and type of constantpool entry */
691         /* (pos == 0 is caught by type comparison) */
692
693         if ((pos >= c->cpcount) || (c->cptags[pos] != ctype)) {
694                 exceptions_throw_classformaterror(c, "Illegal constant pool index");
695                 return NULL;
696         }
697
698         return c->cpinfos[pos];
699 }
700
701
702 /* innerclass_getconstant ******************************************************
703
704    Like class_getconstant, but if cptags is ZERO, null is returned.
705         
706 *******************************************************************************/
707
708 voidptr innerclass_getconstant(classinfo *c, u4 pos, u4 ctype)
709 {
710         /* invalid position in constantpool */
711
712         if (pos >= c->cpcount) {
713                 exceptions_throw_classformaterror(c, "Illegal constant pool index");
714                 return NULL;
715         }
716
717         /* constantpool entry of type 0 */      
718
719         if (c->cptags[pos] == 0)
720                 return NULL;
721
722         /* check type of constantpool entry */
723
724         if (c->cptags[pos] != ctype) {
725                 exceptions_throw_classformaterror(c, "Illegal constant pool index");
726                 return NULL;
727         }
728                 
729         return c->cpinfos[pos];
730 }
731
732
733 /* class_free ******************************************************************
734
735    Frees all resources used by the class.
736
737 *******************************************************************************/
738
739 void class_free(classinfo *c)
740 {
741         s4 i;
742         vftbl_t *v;
743                 
744         class_freecpool(c);
745
746         if (c->interfaces)
747                 MFREE(c->interfaces, classinfo*, c->interfacescount);
748
749         if (c->fields) {
750                 for (i = 0; i < c->fieldscount; i++)
751                         field_free(&(c->fields[i]));
752 #if defined(ENABLE_CACAO_GC)
753                 MFREE(c->fields, fieldinfo, c->fieldscount);
754 #endif
755         }
756         
757         if (c->methods) {
758                 for (i = 0; i < c->methodscount; i++)
759                         method_free(&(c->methods[i]));
760                 MFREE(c->methods, methodinfo, c->methodscount);
761         }
762
763         if ((v = c->vftbl) != NULL) {
764                 if (v->arraydesc)
765                         mem_free(v->arraydesc,sizeof(arraydescriptor));
766                 
767                 for (i = 0; i < v->interfacetablelength; i++) {
768                         MFREE(v->interfacetable[-i], methodptr, v->interfacevftbllength[i]);
769                 }
770                 MFREE(v->interfacevftbllength, s4, v->interfacetablelength);
771
772                 i = sizeof(vftbl_t) + sizeof(methodptr) * (v->vftbllength - 1) +
773                     sizeof(methodptr*) * (v->interfacetablelength -
774                                          (v->interfacetablelength > 0));
775                 v = (vftbl_t*) (((methodptr*) v) -
776                                                 (v->interfacetablelength - 1) * (v->interfacetablelength > 1));
777                 mem_free(v, i);
778         }
779
780         if (c->innerclass)
781                 MFREE(c->innerclass, innerclassinfo, c->innerclasscount);
782
783         /*      if (c->classvftbl)
784                 mem_free(c->header.vftbl, sizeof(vftbl) + sizeof(methodptr)*(c->vftbl->vftbllength-1)); */
785         
786 /*      GCFREE(c); */
787 }
788
789
790 /* get_array_class *************************************************************
791
792    Returns the array class with the given name for the given
793    classloader, or NULL if an exception occurred.
794
795    Note: This function does eager loading. 
796
797 *******************************************************************************/
798
799 static classinfo *get_array_class(utf *name,classloader *initloader,
800                                                                                         classloader *defloader,bool link)
801 {
802         classinfo *c;
803         
804         /* lookup this class in the classcache */
805         c = classcache_lookup(initloader,name);
806         if (!c)
807                 c = classcache_lookup_defined(defloader,name);
808
809         if (!c) {
810                 /* we have to create it */
811                 c = class_create_classinfo(name);
812                 c = load_newly_created_array(c,initloader);
813                 if (c == NULL)
814                         return NULL;
815         }
816
817         assert(c);
818         assert(c->state & CLASS_LOADED);
819         assert(c->classloader == defloader);
820
821         if (link && !(c->state & CLASS_LINKED))
822                 if (!link_class(c))
823                         return NULL;
824
825         assert(!link || (c->state & CLASS_LINKED));
826
827         return c;
828 }
829
830
831 /* class_array_of **************************************************************
832
833    Returns an array class with the given component class. The array
834    class is dynamically created if neccessary.
835
836 *******************************************************************************/
837
838 classinfo *class_array_of(classinfo *component, bool link)
839 {
840         classloader       *cl;
841     s4                 namelen;
842     char              *namebuf;
843         utf               *u;
844         classinfo         *c;
845         s4                 dumpsize;
846
847         cl = component->classloader;
848
849         dumpsize = dump_size();
850
851     /* Assemble the array class name */
852     namelen = component->name->blength;
853     
854     if (component->name->text[0] == '[') {
855         /* the component is itself an array */
856         namebuf = DMNEW(char, namelen + 1);
857         namebuf[0] = '[';
858         MCOPY(namebuf + 1, component->name->text, char, namelen);
859         namelen++;
860     }
861         else {
862         /* the component is a non-array class */
863         namebuf = DMNEW(char, namelen + 3);
864         namebuf[0] = '[';
865         namebuf[1] = 'L';
866         MCOPY(namebuf + 2, component->name->text, char, namelen);
867         namebuf[2 + namelen] = ';';
868         namelen += 3;
869     }
870
871         u = utf_new(namebuf, namelen);
872
873         c = get_array_class(u, cl, cl, link);
874
875         dump_release(dumpsize);
876
877         return c;
878 }
879
880
881 /* class_multiarray_of *********************************************************
882
883    Returns an array class with the given dimension and element class.
884    The array class is dynamically created if neccessary.
885
886 *******************************************************************************/
887
888 classinfo *class_multiarray_of(s4 dim, classinfo *element, bool link)
889 {
890     s4 namelen;
891     char *namebuf;
892         s4 dumpsize;
893         classinfo *c;
894
895         dumpsize = dump_size();
896
897         if (dim < 1) {
898                 log_text("Invalid array dimension requested");
899                 assert(0);
900         }
901
902     /* Assemble the array class name */
903     namelen = element->name->blength;
904     
905     if (element->name->text[0] == '[') {
906         /* the element is itself an array */
907         namebuf = DMNEW(char, namelen + dim);
908         memcpy(namebuf + dim, element->name->text, namelen);
909         namelen += dim;
910     }
911     else {
912         /* the element is a non-array class */
913         namebuf = DMNEW(char, namelen + 2 + dim);
914         namebuf[dim] = 'L';
915         memcpy(namebuf + dim + 1, element->name->text, namelen);
916         namelen += (2 + dim);
917         namebuf[namelen - 1] = ';';
918     }
919         memset(namebuf, '[', dim);
920
921         c = get_array_class(utf_new(namebuf, namelen),
922                                                 element->classloader,
923                                                 element->classloader,
924                                                 link);
925
926         dump_release(dumpsize);
927
928         return c;
929 }
930
931
932 /* class_lookup_classref *******************************************************
933
934    Looks up the constant_classref for a given classname in the classref
935    tables of a class.
936
937    IN:
938        cls..............the class containing the reference
939            name.............the name of the class refered to
940
941     RETURN VALUE:
942            a pointer to a constant_classref, or 
943            NULL if the reference was not found
944    
945 *******************************************************************************/
946
947 constant_classref *class_lookup_classref(classinfo *cls, utf *name)
948 {
949         constant_classref *ref;
950         extra_classref *xref;
951         int count;
952
953         assert(cls);
954         assert(name);
955         assert(!cls->classrefcount || cls->classrefs);
956         
957         /* first search the main classref table */
958         count = cls->classrefcount;
959         ref = cls->classrefs;
960         for (; count; --count, ++ref)
961                 if (ref->name == name)
962                         return ref;
963
964         /* next try the list of extra classrefs */
965         for (xref = cls->extclassrefs; xref; xref = xref->next) {
966                 if (xref->classref.name == name)
967                         return &(xref->classref);
968         }
969
970         /* not found */
971         return NULL;
972 }
973
974
975 /* class_get_classref **********************************************************
976
977    Returns the constant_classref for a given classname.
978
979    IN:
980        cls..............the class containing the reference
981            name.............the name of the class refered to
982
983    RETURN VALUE:
984        a pointer to a constant_classref (never NULL)
985
986    NOTE:
987        The given name is not checked for validity!
988    
989 *******************************************************************************/
990
991 constant_classref *class_get_classref(classinfo *cls, utf *name)
992 {
993         constant_classref *ref;
994         extra_classref *xref;
995
996         assert(cls);
997         assert(name);
998
999         ref = class_lookup_classref(cls,name);
1000         if (ref)
1001                 return ref;
1002
1003         xref = NEW(extra_classref);
1004         CLASSREF_INIT(xref->classref,cls,name);
1005
1006         xref->next = cls->extclassrefs;
1007         cls->extclassrefs = xref;
1008
1009         return &(xref->classref);
1010 }
1011
1012
1013 /* class_get_self_classref *****************************************************
1014
1015    Returns the constant_classref to the class itself.
1016
1017    IN:
1018        cls..............the class containing the reference
1019
1020    RETURN VALUE:
1021        a pointer to a constant_classref (never NULL)
1022
1023 *******************************************************************************/
1024
1025 constant_classref *class_get_self_classref(classinfo *cls)
1026 {
1027         /* XXX this should be done in a faster way. Maybe always make */
1028         /* the classref of index 0 a self reference.                  */
1029         return class_get_classref(cls,cls->name);
1030 }
1031
1032 /* class_get_classref_multiarray_of ********************************************
1033
1034    Returns an array type reference with the given dimension and element class
1035    reference.
1036
1037    IN:
1038        dim..............the requested dimension
1039                             dim must be in [1;255]. This is NOT checked!
1040            ref..............the component class reference
1041
1042    RETURN VALUE:
1043        a pointer to the class reference for the array type
1044
1045    NOTE:
1046        The referer of `ref` is used as the referer for the new classref.
1047
1048 *******************************************************************************/
1049
1050 constant_classref *class_get_classref_multiarray_of(s4 dim, constant_classref *ref)
1051 {
1052     s4 namelen;
1053     char *namebuf;
1054         s4 dumpsize;
1055         constant_classref *cr;
1056
1057         assert(ref);
1058         assert(dim >= 1 && dim <= 255);
1059
1060         dumpsize = dump_size();
1061
1062     /* Assemble the array class name */
1063     namelen = ref->name->blength;
1064     
1065     if (ref->name->text[0] == '[') {
1066         /* the element is itself an array */
1067         namebuf = DMNEW(char, namelen + dim);
1068         memcpy(namebuf + dim, ref->name->text, namelen);
1069         namelen += dim;
1070     }
1071     else {
1072         /* the element is a non-array class */
1073         namebuf = DMNEW(char, namelen + 2 + dim);
1074         namebuf[dim] = 'L';
1075         memcpy(namebuf + dim + 1, ref->name->text, namelen);
1076         namelen += (2 + dim);
1077         namebuf[namelen - 1] = ';';
1078     }
1079         memset(namebuf, '[', dim);
1080
1081     cr = class_get_classref(ref->referer,utf_new(namebuf, namelen));
1082
1083         dump_release(dumpsize);
1084
1085         return cr;
1086 }
1087
1088
1089 /* class_get_classref_component_of *********************************************
1090
1091    Returns the component classref of a given array type reference
1092
1093    IN:
1094        ref..............the array type reference
1095
1096    RETURN VALUE:
1097        a reference to the component class, or
1098            NULL if `ref` is not an object array type reference
1099
1100    NOTE:
1101        The referer of `ref` is used as the referer for the new classref.
1102
1103 *******************************************************************************/
1104
1105 constant_classref *class_get_classref_component_of(constant_classref *ref)
1106 {
1107         s4 namelen;
1108         char *name;
1109         
1110         assert(ref);
1111
1112         name = ref->name->text;
1113         if (*name++ != '[')
1114                 return NULL;
1115         
1116         namelen = ref->name->blength - 1;
1117         if (*name == 'L') {
1118                 name++;
1119                 namelen -= 2;
1120         }
1121         else if (*name != '[') {
1122                 return NULL;
1123         }
1124
1125     return class_get_classref(ref->referer, utf_new(name, namelen));
1126 }
1127
1128
1129 /* class_findmethod ************************************************************
1130         
1131    Searches a 'classinfo' structure for a method having the given name
1132    and descriptor. If descriptor is NULL, it is ignored.
1133
1134 *******************************************************************************/
1135
1136 methodinfo *class_findmethod(classinfo *c, utf *name, utf *desc)
1137 {
1138         methodinfo *m;
1139         s4          i;
1140
1141         for (i = 0; i < c->methodscount; i++) {
1142                 m = &(c->methods[i]);
1143
1144                 if ((m->name == name) && ((desc == NULL) || (m->descriptor == desc)))
1145                         return m;
1146         }
1147
1148         return NULL;
1149 }
1150
1151
1152 /* class_resolvemethod *********************************************************
1153         
1154    Searches a class and it's super classes for a method.
1155
1156    Superinterfaces are *not* searched.
1157
1158 *******************************************************************************/
1159
1160 methodinfo *class_resolvemethod(classinfo *c, utf *name, utf *desc)
1161 {
1162         methodinfo *m;
1163
1164         while (c) {
1165                 m = class_findmethod(c, name, desc);
1166
1167                 if (m)
1168                         return m;
1169
1170                 /* JVM Specification bug: 
1171
1172                    It is important NOT to resolve special <init> and <clinit>
1173                    methods to super classes or interfaces; yet, this is not
1174                    explicited in the specification.  Section 5.4.3.3 should be
1175                    updated appropriately.  */
1176
1177                 if (name == utf_init || name == utf_clinit)
1178                         return NULL;
1179
1180                 c = c->super.cls;
1181         }
1182
1183         return NULL;
1184 }
1185
1186
1187 /* class_resolveinterfacemethod_intern *****************************************
1188
1189    Internally used helper function. Do not use this directly.
1190
1191 *******************************************************************************/
1192
1193 static methodinfo *class_resolveinterfacemethod_intern(classinfo *c,
1194                                                                                                            utf *name, utf *desc)
1195 {
1196         methodinfo *m;
1197         s4          i;
1198
1199         /* try to find the method in the class */
1200
1201         m = class_findmethod(c, name, desc);
1202
1203         if (m != NULL)
1204                 return m;
1205
1206         /* no method found? try the superinterfaces */
1207
1208         for (i = 0; i < c->interfacescount; i++) {
1209                 m = class_resolveinterfacemethod_intern(c->interfaces[i].cls,
1210                                                                                                         name, desc);
1211
1212                 if (m != NULL)
1213                         return m;
1214         }
1215
1216         /* no method found */
1217
1218         return NULL;
1219 }
1220
1221
1222 /* class_resolveclassmethod ****************************************************
1223         
1224    Resolves a reference from REFERER to a method with NAME and DESC in
1225    class C.
1226
1227    If the method cannot be resolved the return value is NULL. If
1228    EXCEPT is true *exceptionptr is set, too.
1229
1230 *******************************************************************************/
1231
1232 methodinfo *class_resolveclassmethod(classinfo *c, utf *name, utf *desc,
1233                                                                          classinfo *referer, bool throwexception)
1234 {
1235         classinfo  *cls;
1236         methodinfo *m;
1237         s4          i;
1238
1239 /*      if (c->flags & ACC_INTERFACE) { */
1240 /*              if (throwexception) */
1241 /*                      *exceptionptr = */
1242 /*                              new_exception(string_java_lang_IncompatibleClassChangeError); */
1243 /*              return NULL; */
1244 /*      } */
1245
1246         /* try class c and its superclasses */
1247
1248         cls = c;
1249
1250         m = class_resolvemethod(cls, name, desc);
1251
1252         if (m != NULL)
1253                 goto found;
1254
1255         /* try the superinterfaces */
1256
1257         for (i = 0; i < c->interfacescount; i++) {
1258                 m = class_resolveinterfacemethod_intern(c->interfaces[i].cls,
1259                                                                                                 name, desc);
1260
1261                 if (m != NULL)
1262                         goto found;
1263         }
1264         
1265         if (throwexception)
1266                 exceptions_throw_nosuchmethoderror(c, name, desc);
1267
1268         return NULL;
1269
1270  found:
1271         if ((m->flags & ACC_ABSTRACT) && !(c->flags & ACC_ABSTRACT)) {
1272                 if (throwexception)
1273                         exceptions_throw_abstractmethoderror();
1274
1275                 return NULL;
1276         }
1277
1278         /* XXX check access rights */
1279
1280         return m;
1281 }
1282
1283
1284 /* class_resolveinterfacemethod ************************************************
1285
1286    Resolves a reference from REFERER to a method with NAME and DESC in
1287    interface C.
1288
1289    If the method cannot be resolved the return value is NULL. If
1290    EXCEPT is true *exceptionptr is set, too.
1291
1292 *******************************************************************************/
1293
1294 methodinfo *class_resolveinterfacemethod(classinfo *c, utf *name, utf *desc,
1295                                                                                  classinfo *referer, bool throwexception)
1296 {
1297         methodinfo *mi;
1298
1299         if (!(c->flags & ACC_INTERFACE)) {
1300                 if (throwexception)
1301                         exceptions_throw_incompatibleclasschangeerror(c, "Not an interface");
1302
1303                 return NULL;
1304         }
1305
1306         mi = class_resolveinterfacemethod_intern(c, name, desc);
1307
1308         if (mi != NULL)
1309                 return mi;
1310
1311         /* try class java.lang.Object */
1312
1313         mi = class_findmethod(class_java_lang_Object, name, desc);
1314
1315         if (mi != NULL)
1316                 return mi;
1317
1318         if (throwexception)
1319                 exceptions_throw_nosuchmethoderror(c, name, desc);
1320
1321         return NULL;
1322 }
1323
1324
1325 /* class_findfield *************************************************************
1326         
1327    Searches for field with specified name and type in a classinfo
1328    structure. If no such field is found NULL is returned.
1329
1330 *******************************************************************************/
1331
1332 fieldinfo *class_findfield(classinfo *c, utf *name, utf *desc)
1333 {
1334         s4 i;
1335
1336         for (i = 0; i < c->fieldscount; i++)
1337                 if ((c->fields[i].name == name) && (c->fields[i].descriptor == desc))
1338                         return &(c->fields[i]);
1339
1340         if (c->super.cls)
1341                 return class_findfield(c->super.cls, name, desc);
1342
1343         return NULL;
1344 }
1345
1346
1347 /* class_findfield_approx ******************************************************
1348         
1349    Searches in 'classinfo'-structure for a field with the specified
1350    name.
1351
1352 *******************************************************************************/
1353  
1354 fieldinfo *class_findfield_by_name(classinfo *c, utf *name)
1355 {
1356         s4 i;
1357
1358         /* get field index */
1359
1360         i = class_findfield_index_by_name(c, name);
1361
1362         /* field was not found, return */
1363
1364         if (i == -1)
1365                 return NULL;
1366
1367         /* return field address */
1368
1369         return &(c->fields[i]);
1370 }
1371
1372
1373 s4 class_findfield_index_by_name(classinfo *c, utf *name)
1374 {
1375         s4 i;
1376
1377         for (i = 0; i < c->fieldscount; i++) {
1378                 /* compare field names */
1379
1380                 if ((c->fields[i].name == name))
1381                         return i;
1382         }
1383
1384         /* field was not found, raise exception */      
1385
1386         exceptions_throw_nosuchfielderror(c, name);
1387
1388         return -1;
1389 }
1390
1391
1392 /****************** Function: class_resolvefield_int ***************************
1393
1394     This is an internally used helper function. Do not use this directly.
1395
1396         Tries to resolve a field having the given name and type.
1397     If the field cannot be resolved, NULL is returned.
1398
1399 *******************************************************************************/
1400
1401 static fieldinfo *class_resolvefield_int(classinfo *c, utf *name, utf *desc)
1402 {
1403         fieldinfo *fi;
1404         s4         i;
1405
1406         /* search for field in class c */
1407
1408         for (i = 0; i < c->fieldscount; i++) { 
1409                 if ((c->fields[i].name == name) && (c->fields[i].descriptor == desc)) {
1410                         return &(c->fields[i]);
1411                 }
1412     }
1413
1414         /* try superinterfaces recursively */
1415
1416         for (i = 0; i < c->interfacescount; i++) {
1417                 fi = class_resolvefield_int(c->interfaces[i].cls, name, desc);
1418                 if (fi)
1419                         return fi;
1420         }
1421
1422         /* try superclass */
1423
1424         if (c->super.cls)
1425                 return class_resolvefield_int(c->super.cls, name, desc);
1426
1427         /* not found */
1428
1429         return NULL;
1430 }
1431
1432
1433 /********************* Function: class_resolvefield ***************************
1434         
1435         Resolves a reference from REFERER to a field with NAME and DESC in class C.
1436
1437     If the field cannot be resolved the return value is NULL. If EXCEPT is
1438     true *exceptionptr is set, too.
1439
1440 *******************************************************************************/
1441
1442 fieldinfo *class_resolvefield(classinfo *c, utf *name, utf *desc,
1443                                                           classinfo *referer, bool throwexception)
1444 {
1445         fieldinfo *fi;
1446
1447         fi = class_resolvefield_int(c, name, desc);
1448
1449         if (!fi) {
1450                 if (throwexception)
1451                         exceptions_throw_nosuchfielderror(c, name);
1452
1453                 return NULL;
1454         }
1455
1456         /* XXX check access rights */
1457
1458         return fi;
1459 }
1460
1461
1462 /* class_issubclass ************************************************************
1463
1464    Checks if sub is a descendant of super.
1465         
1466 *******************************************************************************/
1467
1468 bool class_issubclass(classinfo *sub, classinfo *super)
1469 {
1470         for (;;) {
1471                 if (!sub)
1472                         return false;
1473
1474                 if (sub == super)
1475                         return true;
1476
1477                 sub = sub->super.cls;
1478         }
1479 }
1480
1481
1482 /* class_isanysubclass *********************************************************
1483
1484    Checks a subclass relation between two classes. Implemented
1485    interfaces are interpreted as super classes.
1486
1487    Return value: 1 ... sub is subclass of super
1488                  0 ... otherwise
1489
1490 *******************************************************************************/
1491
1492 bool class_isanysubclass(classinfo *sub, classinfo *super)
1493 {
1494         castinfo classvalues;
1495         u4       diffval;
1496         bool     result;
1497
1498         /* This is the trivial case. */
1499
1500         if (sub == super)
1501                 return true;
1502
1503         /* Primitive classes are only subclasses of themselves. */
1504
1505         if ((sub->flags & ACC_CLASS_PRIMITIVE) ||
1506                 (super->flags & ACC_CLASS_PRIMITIVE))
1507                 return false;
1508
1509         /* Check for interfaces. */
1510
1511         if (super->flags & ACC_INTERFACE) {
1512                 result = (sub->vftbl->interfacetablelength > super->index) &&
1513                         (sub->vftbl->interfacetable[-super->index] != NULL);
1514         }
1515         else {
1516                 /* java.lang.Object is the only super class of any
1517                    interface. */
1518
1519                 if (sub->flags & ACC_INTERFACE)
1520                         return (super == class_java_lang_Object);
1521
1522                 ASM_GETCLASSVALUES_ATOMIC(super->vftbl, sub->vftbl, &classvalues);
1523
1524                 diffval = classvalues.sub_baseval - classvalues.super_baseval;
1525                 result  = diffval <= (u4) classvalues.super_diffval;
1526         }
1527
1528         return result;
1529 }
1530
1531
1532 /* class_is_array **************************************************************
1533
1534    Checks if the given class is an array class.
1535
1536 *******************************************************************************/
1537
1538 bool class_is_array(classinfo *c)
1539 {
1540         if (!(c->state & CLASS_LINKED))
1541                 if (!link_class(c))
1542                         return false;
1543
1544         return (c->vftbl->arraydesc != NULL);
1545 }
1546
1547
1548 /* class_is_interface **********************************************************
1549
1550    Checks if the given class is an interface.
1551
1552 *******************************************************************************/
1553
1554 bool class_is_interface(classinfo *c)
1555 {
1556         if (c->flags & ACC_INTERFACE)
1557                 return true;
1558
1559         return false;
1560 }
1561
1562
1563 /* class_printflags ************************************************************
1564
1565    Prints flags of a class.
1566
1567 *******************************************************************************/
1568
1569 #if !defined(NDEBUG)
1570 void class_printflags(classinfo *c)
1571 {
1572         if (c == NULL) {
1573                 printf("NULL");
1574                 return;
1575         }
1576
1577         if (c->flags & ACC_PUBLIC)       printf(" PUBLIC");
1578         if (c->flags & ACC_PRIVATE)      printf(" PRIVATE");
1579         if (c->flags & ACC_PROTECTED)    printf(" PROTECTED");
1580         if (c->flags & ACC_STATIC)       printf(" STATIC");
1581         if (c->flags & ACC_FINAL)        printf(" FINAL");
1582         if (c->flags & ACC_SYNCHRONIZED) printf(" SYNCHRONIZED");
1583         if (c->flags & ACC_VOLATILE)     printf(" VOLATILE");
1584         if (c->flags & ACC_TRANSIENT)    printf(" TRANSIENT");
1585         if (c->flags & ACC_NATIVE)       printf(" NATIVE");
1586         if (c->flags & ACC_INTERFACE)    printf(" INTERFACE");
1587         if (c->flags & ACC_ABSTRACT)     printf(" ABSTRACT");
1588 }
1589 #endif
1590
1591
1592 /* class_print *****************************************************************
1593
1594    Prints classname plus flags.
1595
1596 *******************************************************************************/
1597
1598 #if !defined(NDEBUG)
1599 void class_print(classinfo *c)
1600 {
1601         if (c == NULL) {
1602                 printf("NULL");
1603                 return;
1604         }
1605
1606         utf_display_printable_ascii(c->name);
1607         class_printflags(c);
1608 }
1609 #endif
1610
1611
1612 /* class_classref_print ********************************************************
1613
1614    Prints classname plus referer class.
1615
1616 *******************************************************************************/
1617
1618 #if !defined(NDEBUG)
1619 void class_classref_print(constant_classref *cr)
1620 {
1621         if (cr == NULL) {
1622                 printf("NULL");
1623                 return;
1624         }
1625
1626         utf_display_printable_ascii(cr->name);
1627         printf("(ref.by ");
1628         if (cr->referer)
1629                 class_print(cr->referer);
1630         else
1631                 printf("NULL");
1632         printf(")");
1633 }
1634 #endif
1635
1636
1637 /* class_println ***************************************************************
1638
1639    Prints classname plus flags and new line.
1640
1641 *******************************************************************************/
1642
1643 #if !defined(NDEBUG)
1644 void class_println(classinfo *c)
1645 {
1646         class_print(c);
1647         printf("\n");
1648 }
1649 #endif
1650
1651
1652 /* class_classref_println ******************************************************
1653
1654    Prints classname plus referer class and new line.
1655
1656 *******************************************************************************/
1657
1658 #if !defined(NDEBUG)
1659 void class_classref_println(constant_classref *cr)
1660 {
1661         class_classref_print(cr);
1662         printf("\n");
1663 }
1664 #endif
1665
1666
1667 /* class_classref_or_classinfo_print *******************************************
1668
1669    Prints classname plus referer class.
1670
1671 *******************************************************************************/
1672
1673 #if !defined(NDEBUG)
1674 void class_classref_or_classinfo_print(classref_or_classinfo c)
1675 {
1676         if (c.any == NULL) {
1677                 printf("(classref_or_classinfo) NULL");
1678                 return;
1679         }
1680         if (IS_CLASSREF(c))
1681                 class_classref_print(c.ref);
1682         else
1683                 class_print(c.cls);
1684 }
1685 #endif
1686
1687
1688 /* class_classref_or_classinfo_println *****************************************
1689
1690    Prints classname plus referer class and a newline.
1691
1692 *******************************************************************************/
1693
1694 void class_classref_or_classinfo_println(classref_or_classinfo c)
1695 {
1696         class_classref_or_classinfo_println(c);
1697         printf("\n");
1698 }
1699
1700
1701 /* class_showconstantpool ******************************************************
1702
1703    Dump the constant pool of the given class to stdout.
1704
1705 *******************************************************************************/
1706
1707 #if !defined(NDEBUG)
1708 void class_showconstantpool (classinfo *c) 
1709 {
1710         u4 i;
1711         voidptr e;
1712
1713         printf ("---- dump of constant pool ----\n");
1714
1715         for (i=0; i<c->cpcount; i++) {
1716                 printf ("#%d:  ", (int) i);
1717                 
1718                 e = c -> cpinfos [i];
1719                 if (e) {
1720                         
1721                         switch (c -> cptags [i]) {
1722                         case CONSTANT_Class:
1723                                 printf ("Classreference -> ");
1724                                 utf_display_printable_ascii ( ((constant_classref*)e) -> name );
1725                                 break;
1726                         case CONSTANT_Fieldref:
1727                                 printf ("Fieldref -> ");
1728                                 field_fieldref_print((constant_FMIref *) e);
1729                                 break;
1730                         case CONSTANT_Methodref:
1731                                 printf ("Methodref -> ");
1732                                 method_methodref_print((constant_FMIref *) e);
1733                                 break;
1734                         case CONSTANT_InterfaceMethodref:
1735                                 printf ("InterfaceMethod -> ");
1736                                 method_methodref_print((constant_FMIref *) e);
1737                                 break;
1738                         case CONSTANT_String:
1739                                 printf ("String -> ");
1740                                 utf_display_printable_ascii (e);
1741                                 break;
1742                         case CONSTANT_Integer:
1743                                 printf ("Integer -> %d", (int) ( ((constant_integer*)e) -> value) );
1744                                 break;
1745                         case CONSTANT_Float:
1746                                 printf ("Float -> %f", ((constant_float*)e) -> value);
1747                                 break;
1748                         case CONSTANT_Double:
1749                                 printf ("Double -> %f", ((constant_double*)e) -> value);
1750                                 break;
1751                         case CONSTANT_Long:
1752                                 {
1753                                         u8 v = ((constant_long*)e) -> value;
1754 #if U8_AVAILABLE
1755                                         printf ("Long -> %ld", (long int) v);
1756 #else
1757                                         printf ("Long -> HI: %ld, LO: %ld\n", 
1758                                                         (long int) v.high, (long int) v.low);
1759 #endif 
1760                                 }
1761                                 break;
1762                         case CONSTANT_NameAndType:
1763                                 {
1764                                         constant_nameandtype *cnt = e;
1765                                         printf ("NameAndType: ");
1766                                         utf_display_printable_ascii (cnt->name);
1767                                         printf (" ");
1768                                         utf_display_printable_ascii (cnt->descriptor);
1769                                 }
1770                                 break;
1771                         case CONSTANT_Utf8:
1772                                 printf ("Utf8 -> ");
1773                                 utf_display_printable_ascii (e);
1774                                 break;
1775                         default: 
1776                                 log_text("Invalid type of ConstantPool-Entry");
1777                                 assert(0);
1778                         }
1779                 }
1780
1781                 printf ("\n");
1782         }
1783 }
1784 #endif /* !defined(NDEBUG) */
1785
1786
1787 /* class_showmethods ***********************************************************
1788
1789    Dump info about the fields and methods of the given class to stdout.
1790
1791 *******************************************************************************/
1792
1793 #if !defined(NDEBUG)
1794 void class_showmethods (classinfo *c)
1795 {
1796         s4 i;
1797         
1798         printf("--------- Fields and Methods ----------------\n");
1799         printf("Flags: ");
1800         class_printflags(c);
1801         printf("\n");
1802
1803         printf("This: ");
1804         utf_display_printable_ascii(c->name);
1805         printf("\n");
1806
1807         if (c->super.cls) {
1808                 printf("Super: ");
1809                 utf_display_printable_ascii(c->super.cls->name);
1810                 printf ("\n");
1811         }
1812
1813         printf("Index: %d\n", c->index);
1814         
1815         printf("Interfaces:\n");        
1816         for (i = 0; i < c->interfacescount; i++) {
1817                 printf("   ");
1818                 utf_display_printable_ascii(c->interfaces[i].cls->name);
1819                 printf (" (%d)\n", c->interfaces[i].cls->index);
1820         }
1821
1822         printf("Fields:\n");
1823         for (i = 0; i < c->fieldscount; i++)
1824                 field_println(&(c->fields[i]));
1825
1826         printf("Methods:\n");
1827         for (i = 0; i < c->methodscount; i++) {
1828                 methodinfo *m = &(c->methods[i]);
1829
1830                 if (!(m->flags & ACC_STATIC))
1831                         printf("vftblindex: %d   ", m->vftblindex);
1832
1833                 method_println(m);
1834         }
1835
1836         printf ("Virtual function table:\n");
1837         for (i = 0; i < c->vftbl->vftbllength; i++)
1838                 printf ("entry: %d,  %ld\n", i, (long int) (c->vftbl->table[i]));
1839 }
1840 #endif /* !defined(NDEBUG) */
1841
1842
1843 /*
1844  * These are local overrides for various environment variables in Emacs.
1845  * Please do not remove this and leave it at the end of the file, where
1846  * Emacs will automagically detect them.
1847  * ---------------------------------------------------------------------
1848  * Local variables:
1849  * mode: c
1850  * indent-tabs-mode: t
1851  * c-basic-offset: 4
1852  * tab-width: 4
1853  * End:
1854  * vim:noexpandtab:sw=4:ts=4:
1855  */