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