Merged revisions 8034-8055 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 8056 2007-06-10 14:49:57Z 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_SOFT_REFERENCE;
232         }
233         else if (classname == utf_java_lang_ref_WeakReference) {
234                 c->flags |= ACC_CLASS_WEAK_REFERENCE;
235         }
236         else if (classname == utf_java_lang_ref_PhantomReference) {
237                 c->flags |= ACC_CLASS_PHANTOM_REFERENCE;
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, java_objectheader *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     s4 namelen;
841     char *namebuf;
842         s4 dumpsize;
843         classinfo *c;
844
845         dumpsize = dump_size();
846
847     /* Assemble the array class name */
848     namelen = component->name->blength;
849     
850     if (component->name->text[0] == '[') {
851         /* the component is itself an array */
852         namebuf = DMNEW(char, namelen + 1);
853         namebuf[0] = '[';
854         MCOPY(namebuf + 1, component->name->text, char, namelen);
855         namelen++;
856
857     } else {
858         /* the component is a non-array class */
859         namebuf = DMNEW(char, namelen + 3);
860         namebuf[0] = '[';
861         namebuf[1] = 'L';
862         MCOPY(namebuf + 2, component->name->text, char, namelen);
863         namebuf[2 + namelen] = ';';
864         namelen += 3;
865     }
866
867         c = get_array_class(utf_new(namebuf, namelen),
868                                                 component->classloader,
869                                                 component->classloader,
870                                                 link);
871
872         dump_release(dumpsize);
873
874         return c;
875 }
876
877
878 /* class_multiarray_of *********************************************************
879
880    Returns an array class with the given dimension and element class.
881    The array class is dynamically created if neccessary.
882
883 *******************************************************************************/
884
885 classinfo *class_multiarray_of(s4 dim, classinfo *element, bool link)
886 {
887     s4 namelen;
888     char *namebuf;
889         s4 dumpsize;
890         classinfo *c;
891
892         dumpsize = dump_size();
893
894         if (dim < 1) {
895                 log_text("Invalid array dimension requested");
896                 assert(0);
897         }
898
899     /* Assemble the array class name */
900     namelen = element->name->blength;
901     
902     if (element->name->text[0] == '[') {
903         /* the element is itself an array */
904         namebuf = DMNEW(char, namelen + dim);
905         memcpy(namebuf + dim, element->name->text, namelen);
906         namelen += dim;
907     }
908     else {
909         /* the element is a non-array class */
910         namebuf = DMNEW(char, namelen + 2 + dim);
911         namebuf[dim] = 'L';
912         memcpy(namebuf + dim + 1, element->name->text, namelen);
913         namelen += (2 + dim);
914         namebuf[namelen - 1] = ';';
915     }
916         memset(namebuf, '[', dim);
917
918         c = get_array_class(utf_new(namebuf, namelen),
919                                                 element->classloader,
920                                                 element->classloader,
921                                                 link);
922
923         dump_release(dumpsize);
924
925         return c;
926 }
927
928
929 /* class_lookup_classref *******************************************************
930
931    Looks up the constant_classref for a given classname in the classref
932    tables of a class.
933
934    IN:
935        cls..............the class containing the reference
936            name.............the name of the class refered to
937
938     RETURN VALUE:
939            a pointer to a constant_classref, or 
940            NULL if the reference was not found
941    
942 *******************************************************************************/
943
944 constant_classref *class_lookup_classref(classinfo *cls, utf *name)
945 {
946         constant_classref *ref;
947         extra_classref *xref;
948         int count;
949
950         assert(cls);
951         assert(name);
952         assert(!cls->classrefcount || cls->classrefs);
953         
954         /* first search the main classref table */
955         count = cls->classrefcount;
956         ref = cls->classrefs;
957         for (; count; --count, ++ref)
958                 if (ref->name == name)
959                         return ref;
960
961         /* next try the list of extra classrefs */
962         for (xref = cls->extclassrefs; xref; xref = xref->next) {
963                 if (xref->classref.name == name)
964                         return &(xref->classref);
965         }
966
967         /* not found */
968         return NULL;
969 }
970
971
972 /* class_get_classref **********************************************************
973
974    Returns the constant_classref for a given classname.
975
976    IN:
977        cls..............the class containing the reference
978            name.............the name of the class refered to
979
980    RETURN VALUE:
981        a pointer to a constant_classref (never NULL)
982
983    NOTE:
984        The given name is not checked for validity!
985    
986 *******************************************************************************/
987
988 constant_classref *class_get_classref(classinfo *cls, utf *name)
989 {
990         constant_classref *ref;
991         extra_classref *xref;
992
993         assert(cls);
994         assert(name);
995
996         ref = class_lookup_classref(cls,name);
997         if (ref)
998                 return ref;
999
1000         xref = NEW(extra_classref);
1001         CLASSREF_INIT(xref->classref,cls,name);
1002
1003         xref->next = cls->extclassrefs;
1004         cls->extclassrefs = xref;
1005
1006         return &(xref->classref);
1007 }
1008
1009
1010 /* class_get_self_classref *****************************************************
1011
1012    Returns the constant_classref to the class itself.
1013
1014    IN:
1015        cls..............the class containing the reference
1016
1017    RETURN VALUE:
1018        a pointer to a constant_classref (never NULL)
1019
1020 *******************************************************************************/
1021
1022 constant_classref *class_get_self_classref(classinfo *cls)
1023 {
1024         /* XXX this should be done in a faster way. Maybe always make */
1025         /* the classref of index 0 a self reference.                  */
1026         return class_get_classref(cls,cls->name);
1027 }
1028
1029 /* class_get_classref_multiarray_of ********************************************
1030
1031    Returns an array type reference with the given dimension and element class
1032    reference.
1033
1034    IN:
1035        dim..............the requested dimension
1036                             dim must be in [1;255]. This is NOT checked!
1037            ref..............the component class reference
1038
1039    RETURN VALUE:
1040        a pointer to the class reference for the array type
1041
1042    NOTE:
1043        The referer of `ref` is used as the referer for the new classref.
1044
1045 *******************************************************************************/
1046
1047 constant_classref *class_get_classref_multiarray_of(s4 dim, constant_classref *ref)
1048 {
1049     s4 namelen;
1050     char *namebuf;
1051         s4 dumpsize;
1052         constant_classref *cr;
1053
1054         assert(ref);
1055         assert(dim >= 1 && dim <= 255);
1056
1057         dumpsize = dump_size();
1058
1059     /* Assemble the array class name */
1060     namelen = ref->name->blength;
1061     
1062     if (ref->name->text[0] == '[') {
1063         /* the element is itself an array */
1064         namebuf = DMNEW(char, namelen + dim);
1065         memcpy(namebuf + dim, ref->name->text, namelen);
1066         namelen += dim;
1067     }
1068     else {
1069         /* the element is a non-array class */
1070         namebuf = DMNEW(char, namelen + 2 + dim);
1071         namebuf[dim] = 'L';
1072         memcpy(namebuf + dim + 1, ref->name->text, namelen);
1073         namelen += (2 + dim);
1074         namebuf[namelen - 1] = ';';
1075     }
1076         memset(namebuf, '[', dim);
1077
1078     cr = class_get_classref(ref->referer,utf_new(namebuf, namelen));
1079
1080         dump_release(dumpsize);
1081
1082         return cr;
1083 }
1084
1085
1086 /* class_get_classref_component_of *********************************************
1087
1088    Returns the component classref of a given array type reference
1089
1090    IN:
1091        ref..............the array type reference
1092
1093    RETURN VALUE:
1094        a reference to the component class, or
1095            NULL if `ref` is not an object array type reference
1096
1097    NOTE:
1098        The referer of `ref` is used as the referer for the new classref.
1099
1100 *******************************************************************************/
1101
1102 constant_classref *class_get_classref_component_of(constant_classref *ref)
1103 {
1104         s4 namelen;
1105         char *name;
1106         
1107         assert(ref);
1108
1109         name = ref->name->text;
1110         if (*name++ != '[')
1111                 return NULL;
1112         
1113         namelen = ref->name->blength - 1;
1114         if (*name == 'L') {
1115                 name++;
1116                 namelen -= 2;
1117         }
1118         else if (*name != '[') {
1119                 return NULL;
1120         }
1121
1122     return class_get_classref(ref->referer, utf_new(name, namelen));
1123 }
1124
1125
1126 /* class_findmethod ************************************************************
1127         
1128    Searches a 'classinfo' structure for a method having the given name
1129    and descriptor. If descriptor is NULL, it is ignored.
1130
1131 *******************************************************************************/
1132
1133 methodinfo *class_findmethod(classinfo *c, utf *name, utf *desc)
1134 {
1135         methodinfo *m;
1136         s4          i;
1137
1138         for (i = 0; i < c->methodscount; i++) {
1139                 m = &(c->methods[i]);
1140
1141                 if ((m->name == name) && ((desc == NULL) || (m->descriptor == desc)))
1142                         return m;
1143         }
1144
1145         return NULL;
1146 }
1147
1148
1149 /* class_resolvemethod *********************************************************
1150         
1151    Searches a class and it's super classes for a method.
1152
1153    Superinterfaces are *not* searched.
1154
1155 *******************************************************************************/
1156
1157 methodinfo *class_resolvemethod(classinfo *c, utf *name, utf *desc)
1158 {
1159         methodinfo *m;
1160
1161         while (c) {
1162                 m = class_findmethod(c, name, desc);
1163
1164                 if (m)
1165                         return m;
1166
1167                 /* JVM Specification bug: 
1168
1169                    It is important NOT to resolve special <init> and <clinit>
1170                    methods to super classes or interfaces; yet, this is not
1171                    explicited in the specification.  Section 5.4.3.3 should be
1172                    updated appropriately.  */
1173
1174                 if (name == utf_init || name == utf_clinit)
1175                         return NULL;
1176
1177                 c = c->super.cls;
1178         }
1179
1180         return NULL;
1181 }
1182
1183
1184 /* class_resolveinterfacemethod_intern *****************************************
1185
1186    Internally used helper function. Do not use this directly.
1187
1188 *******************************************************************************/
1189
1190 static methodinfo *class_resolveinterfacemethod_intern(classinfo *c,
1191                                                                                                            utf *name, utf *desc)
1192 {
1193         methodinfo *m;
1194         s4          i;
1195
1196         /* try to find the method in the class */
1197
1198         m = class_findmethod(c, name, desc);
1199
1200         if (m != NULL)
1201                 return m;
1202
1203         /* no method found? try the superinterfaces */
1204
1205         for (i = 0; i < c->interfacescount; i++) {
1206                 m = class_resolveinterfacemethod_intern(c->interfaces[i].cls,
1207                                                                                                         name, desc);
1208
1209                 if (m != NULL)
1210                         return m;
1211         }
1212
1213         /* no method found */
1214
1215         return NULL;
1216 }
1217
1218
1219 /* class_resolveclassmethod ****************************************************
1220         
1221    Resolves a reference from REFERER to a method with NAME and DESC in
1222    class C.
1223
1224    If the method cannot be resolved the return value is NULL. If
1225    EXCEPT is true *exceptionptr is set, too.
1226
1227 *******************************************************************************/
1228
1229 methodinfo *class_resolveclassmethod(classinfo *c, utf *name, utf *desc,
1230                                                                          classinfo *referer, bool throwexception)
1231 {
1232         classinfo  *cls;
1233         methodinfo *m;
1234         s4          i;
1235
1236 /*      if (c->flags & ACC_INTERFACE) { */
1237 /*              if (throwexception) */
1238 /*                      *exceptionptr = */
1239 /*                              new_exception(string_java_lang_IncompatibleClassChangeError); */
1240 /*              return NULL; */
1241 /*      } */
1242
1243         /* try class c and its superclasses */
1244
1245         cls = c;
1246
1247         m = class_resolvemethod(cls, name, desc);
1248
1249         if (m != NULL)
1250                 goto found;
1251
1252         /* try the superinterfaces */
1253
1254         for (i = 0; i < c->interfacescount; i++) {
1255                 m = class_resolveinterfacemethod_intern(c->interfaces[i].cls,
1256                                                                                                 name, desc);
1257
1258                 if (m != NULL)
1259                         goto found;
1260         }
1261         
1262         if (throwexception)
1263                 exceptions_throw_nosuchmethoderror(c, name, desc);
1264
1265         return NULL;
1266
1267  found:
1268         if ((m->flags & ACC_ABSTRACT) && !(c->flags & ACC_ABSTRACT)) {
1269                 if (throwexception)
1270                         exceptions_throw_abstractmethoderror();
1271
1272                 return NULL;
1273         }
1274
1275         /* XXX check access rights */
1276
1277         return m;
1278 }
1279
1280
1281 /* class_resolveinterfacemethod ************************************************
1282
1283    Resolves a reference from REFERER to a method with NAME and DESC in
1284    interface C.
1285
1286    If the method cannot be resolved the return value is NULL. If
1287    EXCEPT is true *exceptionptr is set, too.
1288
1289 *******************************************************************************/
1290
1291 methodinfo *class_resolveinterfacemethod(classinfo *c, utf *name, utf *desc,
1292                                                                                  classinfo *referer, bool throwexception)
1293 {
1294         methodinfo *mi;
1295
1296         if (!(c->flags & ACC_INTERFACE)) {
1297                 if (throwexception)
1298                         exceptions_throw_incompatibleclasschangeerror(c, "Not an interface");
1299
1300                 return NULL;
1301         }
1302
1303         mi = class_resolveinterfacemethod_intern(c, name, desc);
1304
1305         if (mi != NULL)
1306                 return mi;
1307
1308         /* try class java.lang.Object */
1309
1310         mi = class_findmethod(class_java_lang_Object, name, desc);
1311
1312         if (mi != NULL)
1313                 return mi;
1314
1315         if (throwexception)
1316                 exceptions_throw_nosuchmethoderror(c, name, desc);
1317
1318         return NULL;
1319 }
1320
1321
1322 /* class_findfield *************************************************************
1323         
1324    Searches for field with specified name and type in a classinfo
1325    structure. If no such field is found NULL is returned.
1326
1327 *******************************************************************************/
1328
1329 fieldinfo *class_findfield(classinfo *c, utf *name, utf *desc)
1330 {
1331         s4 i;
1332
1333         for (i = 0; i < c->fieldscount; i++)
1334                 if ((c->fields[i].name == name) && (c->fields[i].descriptor == desc))
1335                         return &(c->fields[i]);
1336
1337         if (c->super.cls)
1338                 return class_findfield(c->super.cls, name, desc);
1339
1340         return NULL;
1341 }
1342
1343
1344 /* class_findfield_approx ******************************************************
1345         
1346    Searches in 'classinfo'-structure for a field with the specified
1347    name.
1348
1349 *******************************************************************************/
1350  
1351 fieldinfo *class_findfield_by_name(classinfo *c, utf *name)
1352 {
1353         s4 i;
1354
1355         /* get field index */
1356
1357         i = class_findfield_index_by_name(c, name);
1358
1359         /* field was not found, return */
1360
1361         if (i == -1)
1362                 return NULL;
1363
1364         /* return field address */
1365
1366         return &(c->fields[i]);
1367 }
1368
1369
1370 s4 class_findfield_index_by_name(classinfo *c, utf *name)
1371 {
1372         s4 i;
1373
1374         for (i = 0; i < c->fieldscount; i++) {
1375                 /* compare field names */
1376
1377                 if ((c->fields[i].name == name))
1378                         return i;
1379         }
1380
1381         /* field was not found, raise exception */      
1382
1383         exceptions_throw_nosuchfielderror(c, name);
1384
1385         return -1;
1386 }
1387
1388
1389 /****************** Function: class_resolvefield_int ***************************
1390
1391     This is an internally used helper function. Do not use this directly.
1392
1393         Tries to resolve a field having the given name and type.
1394     If the field cannot be resolved, NULL is returned.
1395
1396 *******************************************************************************/
1397
1398 static fieldinfo *class_resolvefield_int(classinfo *c, utf *name, utf *desc)
1399 {
1400         fieldinfo *fi;
1401         s4         i;
1402
1403         /* search for field in class c */
1404
1405         for (i = 0; i < c->fieldscount; i++) { 
1406                 if ((c->fields[i].name == name) && (c->fields[i].descriptor == desc)) {
1407                         return &(c->fields[i]);
1408                 }
1409     }
1410
1411         /* try superinterfaces recursively */
1412
1413         for (i = 0; i < c->interfacescount; i++) {
1414                 fi = class_resolvefield_int(c->interfaces[i].cls, name, desc);
1415                 if (fi)
1416                         return fi;
1417         }
1418
1419         /* try superclass */
1420
1421         if (c->super.cls)
1422                 return class_resolvefield_int(c->super.cls, name, desc);
1423
1424         /* not found */
1425
1426         return NULL;
1427 }
1428
1429
1430 /********************* Function: class_resolvefield ***************************
1431         
1432         Resolves a reference from REFERER to a field with NAME and DESC in class C.
1433
1434     If the field cannot be resolved the return value is NULL. If EXCEPT is
1435     true *exceptionptr is set, too.
1436
1437 *******************************************************************************/
1438
1439 fieldinfo *class_resolvefield(classinfo *c, utf *name, utf *desc,
1440                                                           classinfo *referer, bool throwexception)
1441 {
1442         fieldinfo *fi;
1443
1444         fi = class_resolvefield_int(c, name, desc);
1445
1446         if (!fi) {
1447                 if (throwexception)
1448                         exceptions_throw_nosuchfielderror(c, name);
1449
1450                 return NULL;
1451         }
1452
1453         /* XXX check access rights */
1454
1455         return fi;
1456 }
1457
1458
1459 /* class_is_primitive **********************************************************
1460
1461    Check if the given class is a primitive class.
1462
1463 *******************************************************************************/
1464
1465 bool class_is_primitive(classinfo *c)
1466 {
1467         s4 i;
1468
1469         /* search table of primitive classes */
1470
1471         for (i = 0; i < PRIMITIVETYPE_COUNT; i++)
1472                 if (primitivetype_table[i].class_primitive == c)
1473                         return true;
1474
1475         return false;
1476 }
1477
1478
1479 /* class_primitive_get *********************************************************
1480
1481    Returns the primitive class of the given class name.
1482
1483 *******************************************************************************/
1484
1485 classinfo *class_primitive_get(utf *name)
1486 {
1487         s4 i;
1488
1489         /* search table of primitive classes */
1490
1491         for (i = 0; i < PRIMITIVETYPE_COUNT; i++)
1492                 if (primitivetype_table[i].name == name)
1493                         return primitivetype_table[i].class_primitive;
1494
1495         vm_abort("class_primitive_get: unknown primitive type");
1496
1497         /* keep compiler happy */
1498
1499         return NULL;
1500 }
1501
1502
1503 /* class_issubclass ************************************************************
1504
1505    Checks if sub is a descendant of super.
1506         
1507 *******************************************************************************/
1508
1509 bool class_issubclass(classinfo *sub, classinfo *super)
1510 {
1511         for (;;) {
1512                 if (!sub)
1513                         return false;
1514
1515                 if (sub == super)
1516                         return true;
1517
1518                 sub = sub->super.cls;
1519         }
1520 }
1521
1522
1523 /* class_isanysubclass *********************************************************
1524
1525    Checks a subclass relation between two classes. Implemented
1526    interfaces are interpreted as super classes.
1527
1528    Return value: 1 ... sub is subclass of super
1529                  0 ... otherwise
1530
1531 *******************************************************************************/
1532
1533 bool class_isanysubclass(classinfo *sub, classinfo *super)
1534 {
1535         castinfo classvalues;
1536         u4       diffval;
1537         bool     result;
1538
1539         /* This is the trivial case. */
1540
1541         if (sub == super)
1542                 return true;
1543
1544         /* Primitive classes are only subclasses of themselves. */
1545
1546         if ((sub->flags & ACC_CLASS_PRIMITIVE) ||
1547                 (super->flags & ACC_CLASS_PRIMITIVE))
1548                 return false;
1549
1550         /* Check for interfaces. */
1551
1552         if (super->flags & ACC_INTERFACE) {
1553                 result = (sub->vftbl->interfacetablelength > super->index) &&
1554                         (sub->vftbl->interfacetable[-super->index] != NULL);
1555         }
1556         else {
1557                 /* java.lang.Object is the only super class of any
1558                    interface. */
1559
1560                 if (sub->flags & ACC_INTERFACE)
1561                         return (super == class_java_lang_Object);
1562
1563                 ASM_GETCLASSVALUES_ATOMIC(super->vftbl, sub->vftbl, &classvalues);
1564
1565                 diffval = classvalues.sub_baseval - classvalues.super_baseval;
1566                 result  = diffval <= (u4) classvalues.super_diffval;
1567         }
1568
1569         return result;
1570 }
1571
1572
1573 /* class_printflags ************************************************************
1574
1575    Prints flags of a class.
1576
1577 *******************************************************************************/
1578
1579 #if !defined(NDEBUG)
1580 void class_printflags(classinfo *c)
1581 {
1582         if (c == NULL) {
1583                 printf("NULL");
1584                 return;
1585         }
1586
1587         if (c->flags & ACC_PUBLIC)       printf(" PUBLIC");
1588         if (c->flags & ACC_PRIVATE)      printf(" PRIVATE");
1589         if (c->flags & ACC_PROTECTED)    printf(" PROTECTED");
1590         if (c->flags & ACC_STATIC)       printf(" STATIC");
1591         if (c->flags & ACC_FINAL)        printf(" FINAL");
1592         if (c->flags & ACC_SYNCHRONIZED) printf(" SYNCHRONIZED");
1593         if (c->flags & ACC_VOLATILE)     printf(" VOLATILE");
1594         if (c->flags & ACC_TRANSIENT)    printf(" TRANSIENT");
1595         if (c->flags & ACC_NATIVE)       printf(" NATIVE");
1596         if (c->flags & ACC_INTERFACE)    printf(" INTERFACE");
1597         if (c->flags & ACC_ABSTRACT)     printf(" ABSTRACT");
1598 }
1599 #endif
1600
1601
1602 /* class_print *****************************************************************
1603
1604    Prints classname plus flags.
1605
1606 *******************************************************************************/
1607
1608 #if !defined(NDEBUG)
1609 void class_print(classinfo *c)
1610 {
1611         if (c == NULL) {
1612                 printf("NULL");
1613                 return;
1614         }
1615
1616         utf_display_printable_ascii(c->name);
1617         class_printflags(c);
1618 }
1619 #endif
1620
1621
1622 /* class_classref_print ********************************************************
1623
1624    Prints classname plus referer class.
1625
1626 *******************************************************************************/
1627
1628 #if !defined(NDEBUG)
1629 void class_classref_print(constant_classref *cr)
1630 {
1631         if (cr == NULL) {
1632                 printf("NULL");
1633                 return;
1634         }
1635
1636         utf_display_printable_ascii(cr->name);
1637         printf("(ref.by ");
1638         if (cr->referer)
1639                 class_print(cr->referer);
1640         else
1641                 printf("NULL");
1642         printf(")");
1643 }
1644 #endif
1645
1646
1647 /* class_println ***************************************************************
1648
1649    Prints classname plus flags and new line.
1650
1651 *******************************************************************************/
1652
1653 #if !defined(NDEBUG)
1654 void class_println(classinfo *c)
1655 {
1656         class_print(c);
1657         printf("\n");
1658 }
1659 #endif
1660
1661
1662 /* class_classref_println ******************************************************
1663
1664    Prints classname plus referer class and new line.
1665
1666 *******************************************************************************/
1667
1668 #if !defined(NDEBUG)
1669 void class_classref_println(constant_classref *cr)
1670 {
1671         class_classref_print(cr);
1672         printf("\n");
1673 }
1674 #endif
1675
1676
1677 /* class_classref_or_classinfo_print *******************************************
1678
1679    Prints classname plus referer class.
1680
1681 *******************************************************************************/
1682
1683 #if !defined(NDEBUG)
1684 void class_classref_or_classinfo_print(classref_or_classinfo c)
1685 {
1686         if (c.any == NULL) {
1687                 printf("(classref_or_classinfo) NULL");
1688                 return;
1689         }
1690         if (IS_CLASSREF(c))
1691                 class_classref_print(c.ref);
1692         else
1693                 class_print(c.cls);
1694 }
1695 #endif
1696
1697
1698 /* class_classref_or_classinfo_println *****************************************
1699
1700    Prints classname plus referer class and a newline.
1701
1702 *******************************************************************************/
1703
1704 void class_classref_or_classinfo_println(classref_or_classinfo c)
1705 {
1706         class_classref_or_classinfo_println(c);
1707         printf("\n");
1708 }
1709
1710
1711 /* class_showconstantpool ******************************************************
1712
1713    Dump the constant pool of the given class to stdout.
1714
1715 *******************************************************************************/
1716
1717 #if !defined(NDEBUG)
1718 void class_showconstantpool (classinfo *c) 
1719 {
1720         u4 i;
1721         voidptr e;
1722
1723         printf ("---- dump of constant pool ----\n");
1724
1725         for (i=0; i<c->cpcount; i++) {
1726                 printf ("#%d:  ", (int) i);
1727                 
1728                 e = c -> cpinfos [i];
1729                 if (e) {
1730                         
1731                         switch (c -> cptags [i]) {
1732                         case CONSTANT_Class:
1733                                 printf ("Classreference -> ");
1734                                 utf_display_printable_ascii ( ((constant_classref*)e) -> name );
1735                                 break;
1736                         case CONSTANT_Fieldref:
1737                                 printf ("Fieldref -> ");
1738                                 field_fieldref_print((constant_FMIref *) e);
1739                                 break;
1740                         case CONSTANT_Methodref:
1741                                 printf ("Methodref -> ");
1742                                 method_methodref_print((constant_FMIref *) e);
1743                                 break;
1744                         case CONSTANT_InterfaceMethodref:
1745                                 printf ("InterfaceMethod -> ");
1746                                 method_methodref_print((constant_FMIref *) e);
1747                                 break;
1748                         case CONSTANT_String:
1749                                 printf ("String -> ");
1750                                 utf_display_printable_ascii (e);
1751                                 break;
1752                         case CONSTANT_Integer:
1753                                 printf ("Integer -> %d", (int) ( ((constant_integer*)e) -> value) );
1754                                 break;
1755                         case CONSTANT_Float:
1756                                 printf ("Float -> %f", ((constant_float*)e) -> value);
1757                                 break;
1758                         case CONSTANT_Double:
1759                                 printf ("Double -> %f", ((constant_double*)e) -> value);
1760                                 break;
1761                         case CONSTANT_Long:
1762                                 {
1763                                         u8 v = ((constant_long*)e) -> value;
1764 #if U8_AVAILABLE
1765                                         printf ("Long -> %ld", (long int) v);
1766 #else
1767                                         printf ("Long -> HI: %ld, LO: %ld\n", 
1768                                                         (long int) v.high, (long int) v.low);
1769 #endif 
1770                                 }
1771                                 break;
1772                         case CONSTANT_NameAndType:
1773                                 {
1774                                         constant_nameandtype *cnt = e;
1775                                         printf ("NameAndType: ");
1776                                         utf_display_printable_ascii (cnt->name);
1777                                         printf (" ");
1778                                         utf_display_printable_ascii (cnt->descriptor);
1779                                 }
1780                                 break;
1781                         case CONSTANT_Utf8:
1782                                 printf ("Utf8 -> ");
1783                                 utf_display_printable_ascii (e);
1784                                 break;
1785                         default: 
1786                                 log_text("Invalid type of ConstantPool-Entry");
1787                                 assert(0);
1788                         }
1789                 }
1790
1791                 printf ("\n");
1792         }
1793 }
1794 #endif /* !defined(NDEBUG) */
1795
1796
1797 /* class_showmethods ***********************************************************
1798
1799    Dump info about the fields and methods of the given class to stdout.
1800
1801 *******************************************************************************/
1802
1803 #if !defined(NDEBUG)
1804 void class_showmethods (classinfo *c)
1805 {
1806         s4 i;
1807         
1808         printf("--------- Fields and Methods ----------------\n");
1809         printf("Flags: ");
1810         class_printflags(c);
1811         printf("\n");
1812
1813         printf("This: ");
1814         utf_display_printable_ascii(c->name);
1815         printf("\n");
1816
1817         if (c->super.cls) {
1818                 printf("Super: ");
1819                 utf_display_printable_ascii(c->super.cls->name);
1820                 printf ("\n");
1821         }
1822
1823         printf("Index: %d\n", c->index);
1824         
1825         printf("Interfaces:\n");        
1826         for (i = 0; i < c->interfacescount; i++) {
1827                 printf("   ");
1828                 utf_display_printable_ascii(c->interfaces[i].cls->name);
1829                 printf (" (%d)\n", c->interfaces[i].cls->index);
1830         }
1831
1832         printf("Fields:\n");
1833         for (i = 0; i < c->fieldscount; i++)
1834                 field_println(&(c->fields[i]));
1835
1836         printf("Methods:\n");
1837         for (i = 0; i < c->methodscount; i++) {
1838                 methodinfo *m = &(c->methods[i]);
1839
1840                 if (!(m->flags & ACC_STATIC))
1841                         printf("vftblindex: %d   ", m->vftblindex);
1842
1843                 method_println(m);
1844         }
1845
1846         printf ("Virtual function table:\n");
1847         for (i = 0; i < c->vftbl->vftbllength; i++)
1848                 printf ("entry: %d,  %ld\n", i, (long int) (c->vftbl->table[i]));
1849 }
1850 #endif /* !defined(NDEBUG) */
1851
1852
1853 /*
1854  * These are local overrides for various environment variables in Emacs.
1855  * Please do not remove this and leave it at the end of the file, where
1856  * Emacs will automagically detect them.
1857  * ---------------------------------------------------------------------
1858  * Local variables:
1859  * mode: c
1860  * indent-tabs-mode: t
1861  * c-basic-offset: 4
1862  * tab-width: 4
1863  * End:
1864  * vim:noexpandtab:sw=4:ts=4:
1865  */