* src/vm/string.c,
[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 8230 2007-07-25 08:23:10Z 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 #include "vm/resolve.h"
50
51 #include "vm/jit/asmpart.h"
52
53 #include "vmcore/class.h"
54 #include "vmcore/classcache.h"
55 #include "vmcore/loader.h"
56 #include "vmcore/options.h"
57
58 #if defined(ENABLE_STATISTICS)
59 # include "vmcore/statistics.h"
60 #endif
61
62 #include "vmcore/suck.h"
63 #include "vmcore/utf8.h"
64
65
66 /* global variables ***********************************************************/
67
68 /* frequently used classes ****************************************************/
69
70 /* important system classes */
71
72 classinfo *class_java_lang_Object;
73 classinfo *class_java_lang_Class;
74 classinfo *class_java_lang_ClassLoader;
75 classinfo *class_java_lang_Cloneable;
76 classinfo *class_java_lang_SecurityManager;
77 classinfo *class_java_lang_String;
78 classinfo *class_java_lang_System;
79 classinfo *class_java_lang_Thread;
80 classinfo *class_java_lang_ThreadGroup;
81 classinfo *class_java_lang_VMSystem;
82 classinfo *class_java_lang_VMThread;
83 classinfo *class_java_io_Serializable;
84
85
86 /* system exception classes required in cacao */
87
88 classinfo *class_java_lang_Throwable;
89 classinfo *class_java_lang_Error;
90 classinfo *class_java_lang_LinkageError;
91 classinfo *class_java_lang_NoClassDefFoundError;
92 classinfo *class_java_lang_OutOfMemoryError;
93 classinfo *class_java_lang_VirtualMachineError;
94
95 #if defined(WITH_CLASSPATH_GNU)
96 classinfo *class_java_lang_VMThrowable;
97 #endif
98
99 classinfo *class_java_lang_Exception;
100 classinfo *class_java_lang_ClassCastException;
101 classinfo *class_java_lang_ClassNotFoundException;
102
103 #if defined(ENABLE_JAVASE)
104 classinfo *class_java_lang_Void;
105 #endif
106 classinfo *class_java_lang_Boolean;
107 classinfo *class_java_lang_Byte;
108 classinfo *class_java_lang_Character;
109 classinfo *class_java_lang_Short;
110 classinfo *class_java_lang_Integer;
111 classinfo *class_java_lang_Long;
112 classinfo *class_java_lang_Float;
113 classinfo *class_java_lang_Double;
114
115
116 /* some runtime exception */
117
118 classinfo *class_java_lang_NullPointerException;
119
120
121 /* some classes which may be used more often */
122
123 #if defined(ENABLE_JAVASE)
124 classinfo *class_java_lang_StackTraceElement;
125 classinfo *class_java_lang_reflect_Constructor;
126 classinfo *class_java_lang_reflect_Field;
127 classinfo *class_java_lang_reflect_Method;
128 classinfo *class_java_security_PrivilegedAction;
129 classinfo *class_java_util_Vector;
130
131 classinfo *arrayclass_java_lang_Object;
132 #endif
133
134
135 /* pseudo classes for the typechecker */
136
137 classinfo *pseudo_class_Arraystub;
138 classinfo *pseudo_class_Null;
139 classinfo *pseudo_class_New;
140
141
142 /* class_set_packagename *******************************************************
143
144    Derive the package name from the class name and store it in the struct.
145
146 *******************************************************************************/
147
148 void class_set_packagename(classinfo *c)
149 {
150         char *p = UTF_END(c->name) - 1;
151         char *start = c->name->text;
152
153         /* set the package name */
154         /* classes in the unnamed package keep packagename == NULL */
155
156         if (c->name->text[0] == '[') {
157                 /* set packagename of arrays to the element's package */
158
159                 for (; *start == '['; start++);
160
161                 /* skip the 'L' in arrays of references */
162                 if (*start == 'L')
163                         start++;
164
165                 for (; (p > start) && (*p != '/'); --p);
166
167                 c->packagename = utf_new(start, p - start);
168
169         } else {
170                 for (; (p > start) && (*p != '/'); --p);
171
172                 c->packagename = utf_new(start, p - start);
173         }
174 }
175
176
177 /* class_create_classinfo ******************************************************
178
179    Create a new classinfo struct. The class name is set to the given utf *,
180    most other fields are initialized to zero.
181
182    Note: classname may be NULL. In this case a not-yet-named classinfo is
183          created. The name must be filled in later and class_set_packagename
184                  must be called after that.
185
186 *******************************************************************************/
187
188 classinfo *class_create_classinfo(utf *classname)
189 {
190         classinfo *c;
191
192 #if defined(ENABLE_STATISTICS)
193         if (opt_stat)
194                 size_classinfo += sizeof(classinfo);
195 #endif
196
197         /* we use a safe name for temporarily unnamed classes */
198
199         if (classname == NULL)
200                 classname = utf_not_named_yet;
201
202 #if !defined(NDEBUG)
203         if (initverbose)
204                 log_message_utf("Creating class: ", classname);
205 #endif
206
207         /* GCNEW_UNCOLLECTABLE clears the allocated memory */
208
209         c = GCNEW_UNCOLLECTABLE(classinfo, 1);
210         /*c=NEW(classinfo);*/
211         c->name = classname;
212
213         /* Set the header.vftbl of all loaded classes to the one of
214        java.lang.Class, so Java code can use a class as object. */
215
216         if (class_java_lang_Class != NULL)
217                 if (class_java_lang_Class->vftbl != NULL)
218                         c->object.header.vftbl = class_java_lang_Class->vftbl;
219
220 #if defined(ENABLE_JAVASE)
221         /* check if the class is a reference class and flag it */
222
223         if (classname == utf_java_lang_ref_SoftReference) {
224                 c->flags |= ACC_CLASS_REFERENCE_SOFT;
225         }
226         else if (classname == utf_java_lang_ref_WeakReference) {
227                 c->flags |= ACC_CLASS_REFERENCE_WEAK;
228         }
229         else if (classname == utf_java_lang_ref_PhantomReference) {
230                 c->flags |= ACC_CLASS_REFERENCE_PHANTOM;
231         }
232 #endif
233
234         if (classname != utf_not_named_yet)
235                 class_set_packagename(c);
236
237         LOCK_INIT_OBJECT_LOCK(&c->object.header);
238
239         return c;
240 }
241
242
243 /* class_postset_header_vftbl **************************************************
244
245    Set the header.vftbl of all classes created before java.lang.Class
246    was linked.  This is necessary that Java code can use a class as
247    object.
248
249 *******************************************************************************/
250
251 void class_postset_header_vftbl(void)
252 {
253         classinfo *c;
254         u4 slot;
255         classcache_name_entry *nmen;
256         classcache_class_entry *clsen;
257
258         assert(class_java_lang_Class);
259
260         for (slot = 0; slot < hashtable_classcache.size; slot++) {
261                 nmen = (classcache_name_entry *) hashtable_classcache.ptr[slot];
262
263                 for (; nmen; nmen = nmen->hashlink) {
264                         /* iterate over all class entries */
265
266                         for (clsen = nmen->classes; clsen; clsen = clsen->next) {
267                                 c = clsen->classobj;
268
269                                 /* now set the the vftbl */
270
271                                 if (c->object.header.vftbl == NULL)
272                                         c->object.header.vftbl = class_java_lang_Class->vftbl;
273                         }
274                 }
275         }
276 }
277
278 /* class_define ****************************************************************
279
280    Calls the loader and defines a class in the VM.
281
282 *******************************************************************************/
283
284 classinfo *class_define(utf *name, java_objectheader *cl, int32_t length, const uint8_t *data)
285 {
286         classinfo   *c;
287         classinfo   *r;
288         classbuffer *cb;
289
290         if (name != NULL) {
291                 /* check if this class has already been defined */
292
293                 c = classcache_lookup_defined_or_initiated(cl, name);
294
295                 if (c != NULL) {
296                         exceptions_throw_linkageerror("duplicate class definition: ", c);
297                         return NULL;
298                 }
299         } 
300
301         /* create a new classinfo struct */
302
303         c = class_create_classinfo(name);
304
305 #if defined(ENABLE_STATISTICS)
306         /* measure time */
307
308         if (opt_getloadingtime)
309                 loadingtime_start();
310 #endif
311
312         /* build a classbuffer with the given data */
313
314         cb = NEW(classbuffer);
315
316         cb->class = c;
317         cb->size  = length;
318         cb->data  = data;
319         cb->pos   = cb->data;
320
321         /* preset the defining classloader */
322
323         c->classloader = cl;
324
325         /* load the class from this buffer */
326
327         r = load_class_from_classbuffer(cb);
328
329         /* free memory */
330
331         FREE(cb, classbuffer);
332
333 #if defined(ENABLE_STATISTICS)
334         /* measure time */
335
336         if (opt_getloadingtime)
337                 loadingtime_stop();
338 #endif
339
340         if (r == NULL) {
341                 /* If return value is NULL, we had a problem and the class is
342                    not loaded.  Now free the allocated memory, otherwise we
343                    could run into a DOS. */
344
345                 class_free(c);
346
347                 return NULL;
348         }
349
350         /* Store the newly defined class in the class cache. This call
351            also checks whether a class of the same name has already been
352            defined by the same defining loader, and if so, replaces the
353            newly created class by the one defined earlier. */
354
355         /* Important: The classinfo given to classcache_store must be
356                       fully prepared because another thread may return
357                       this pointer after the lookup at to top of this
358                       function directly after the class cache lock has
359                       been released. */
360
361         c = classcache_store(cl, c, true);
362
363         return c;
364 }
365
366
367 /* class_load_attribute_sourcefile *********************************************
368
369    SourceFile_attribute {
370        u2 attribute_name_index;
371        u4 attribute_length;
372            u2 sourcefile_index;
373    }
374
375 *******************************************************************************/
376
377 static bool class_load_attribute_sourcefile(classbuffer *cb)
378 {
379         classinfo *c;
380         u4         attribute_length;
381         u2         sourcefile_index;
382         utf       *sourcefile;
383
384         /* get classinfo */
385
386         c = cb->class;
387
388         /* check buffer size */
389
390         if (!suck_check_classbuffer_size(cb, 4 + 2))
391                 return false;
392
393         /* check attribute length */
394
395         attribute_length = suck_u4(cb);
396
397         if (attribute_length != 2) {
398                 exceptions_throw_classformaterror(c, "Wrong size for VALUE attribute");
399                 return false;
400         }
401
402         /* there can be no more than one SourceFile attribute */
403
404         if (c->sourcefile != NULL) {
405                 exceptions_throw_classformaterror(c, "Multiple SourceFile attributes");
406                 return false;
407         }
408
409         /* get sourcefile */
410
411         sourcefile_index = suck_u2(cb);
412         sourcefile = class_getconstant(c, sourcefile_index, CONSTANT_Utf8);
413
414         if (sourcefile == NULL)
415                 return false;
416
417         /* store sourcefile */
418
419         c->sourcefile = sourcefile;
420
421         return true;
422 }
423
424
425 /* class_load_attribute_enclosingmethod ****************************************
426
427    EnclosingMethod_attribute {
428        u2 attribute_name_index;
429        u4 attribute_length;
430            u2 class_index;
431            u2 method_index;
432    }
433
434 *******************************************************************************/
435
436 #if defined(ENABLE_JAVASE)
437 static bool class_load_attribute_enclosingmethod(classbuffer *cb)
438 {
439         classinfo             *c;
440         u4                     attribute_length;
441         u2                     class_index;
442         u2                     method_index;
443         classref_or_classinfo  cr;
444         constant_nameandtype  *cn;
445
446         /* get classinfo */
447
448         c = cb->class;
449
450         /* check buffer size */
451
452         if (!suck_check_classbuffer_size(cb, 4 + 2 + 2))
453                 return false;
454
455         /* check attribute length */
456
457         attribute_length = suck_u4(cb);
458
459         if (attribute_length != 4) {
460                 exceptions_throw_classformaterror(c, "Wrong size for VALUE attribute");
461                 return false;
462         }
463
464         /* there can be no more than one EnclosingMethod attribute */
465
466         if (c->enclosingmethod != NULL) {
467                 exceptions_throw_classformaterror(c, "Multiple EnclosingMethod attributes");
468                 return false;
469         }
470
471         /* get class index */
472
473         class_index = suck_u2(cb);
474         cr.ref = innerclass_getconstant(c, class_index, CONSTANT_Class);
475
476         /* get method index */
477
478         method_index = suck_u2(cb);
479         cn = innerclass_getconstant(c, method_index, CONSTANT_NameAndType);
480
481         /* store info in classinfo */
482
483         c->enclosingclass.any = cr.any;
484         c->enclosingmethod    = cn;
485
486         return true;
487 }
488 #endif /* defined(ENABLE_JAVASE) */
489
490
491 /* class_load_attributes *******************************************************
492
493    Read attributes from ClassFile.
494
495    attribute_info {
496        u2 attribute_name_index;
497        u4 attribute_length;
498        u1 info[attribute_length];
499    }
500
501    InnerClasses_attribute {
502        u2 attribute_name_index;
503        u4 attribute_length;
504    }
505
506 *******************************************************************************/
507
508 bool class_load_attributes(classbuffer *cb)
509 {
510         classinfo *c;
511         u4         i, j;
512         u2         attributes_count;
513         u2         attribute_name_index;
514         utf       *attribute_name;
515
516         c = cb->class;
517
518         /* get attributes count */
519
520         if (!suck_check_classbuffer_size(cb, 2))
521                 return false;
522
523         attributes_count = suck_u2(cb);
524
525         for (i = 0; i < attributes_count; i++) {
526                 /* get attribute name */
527
528                 if (!suck_check_classbuffer_size(cb, 2))
529                         return false;
530
531                 attribute_name_index = suck_u2(cb);
532                 attribute_name =
533                         class_getconstant(c, attribute_name_index, CONSTANT_Utf8);
534
535                 if (attribute_name == NULL)
536                         return false;
537
538                 if (attribute_name == utf_InnerClasses) {
539                         /* InnerClasses */
540
541                         if (c->innerclass != NULL) {
542                                 exceptions_throw_classformaterror(c, "Multiple InnerClasses attributes");
543                                 return false;
544                         }
545                                 
546                         if (!suck_check_classbuffer_size(cb, 4 + 2))
547                                 return false;
548
549                         /* skip attribute length */
550                         suck_u4(cb);
551
552                         /* number of records */
553                         c->innerclasscount = suck_u2(cb);
554
555                         if (!suck_check_classbuffer_size(cb, (2 + 2 + 2 + 2) * c->innerclasscount))
556                                 return false;
557
558                         /* allocate memory for innerclass structure */
559                         c->innerclass = MNEW(innerclassinfo, c->innerclasscount);
560
561                         for (j = 0; j < c->innerclasscount; j++) {
562                                 /* The innerclass structure contains a class with an encoded
563                                    name, its defining scope, its simple name and a bitmask of
564                                    the access flags. If an inner class is not a member, its
565                                    outer_class is NULL, if a class is anonymous, its name is
566                                    NULL. */
567                                                                 
568                                 innerclassinfo *info = c->innerclass + j;
569
570                                 info->inner_class.ref =
571                                         innerclass_getconstant(c, suck_u2(cb), CONSTANT_Class);
572                                 info->outer_class.ref =
573                                         innerclass_getconstant(c, suck_u2(cb), CONSTANT_Class);
574                                 info->name =
575                                         innerclass_getconstant(c, suck_u2(cb), CONSTANT_Utf8);
576                                 info->flags = suck_u2(cb);
577                         }
578                 }
579                 else if (attribute_name == utf_SourceFile) {
580                         /* SourceFile */
581
582                         if (!class_load_attribute_sourcefile(cb))
583                                 return false;
584                 }
585 #if defined(ENABLE_JAVASE)
586                 else if (attribute_name == utf_EnclosingMethod) {
587                         /* EnclosingMethod */
588
589                         if (!class_load_attribute_enclosingmethod(cb))
590                                 return false;
591                 }
592                 else if (attribute_name == utf_Signature) {
593                         /* Signature */
594
595                         if (!loader_load_attribute_signature(cb, &(c->signature)))
596                                 return false;
597                 }
598 #if 0
599                 /* XXX We can't do a release with that enabled */
600
601                 else if (attribute_name == utf_RuntimeVisibleAnnotations) {
602                         /* RuntimeVisibleAnnotations */
603
604                         if (!annotation_load_attribute_runtimevisibleannotations(cb))
605                                 return false;
606                 }
607 #endif
608 #endif
609                 else {
610                         /* unknown attribute */
611
612                         if (!loader_skip_attribute_body(cb))
613                                 return false;
614                 }
615         }
616
617         return true;
618 }
619
620
621 /* class_freepool **************************************************************
622
623         Frees all resources used by this classes Constant Pool.
624
625 *******************************************************************************/
626
627 static void class_freecpool(classinfo *c)
628 {
629         u4 idx;
630         u4 tag;
631         voidptr info;
632         
633         if (c->cptags && c->cpinfos) {
634                 for (idx = 0; idx < c->cpcount; idx++) {
635                         tag = c->cptags[idx];
636                         info = c->cpinfos[idx];
637                 
638                         if (info != NULL) {
639                                 switch (tag) {
640                                 case CONSTANT_Fieldref:
641                                 case CONSTANT_Methodref:
642                                 case CONSTANT_InterfaceMethodref:
643                                         FREE(info, constant_FMIref);
644                                         break;
645                                 case CONSTANT_Integer:
646                                         FREE(info, constant_integer);
647                                         break;
648                                 case CONSTANT_Float:
649                                         FREE(info, constant_float);
650                                         break;
651                                 case CONSTANT_Long:
652                                         FREE(info, constant_long);
653                                         break;
654                                 case CONSTANT_Double:
655                                         FREE(info, constant_double);
656                                         break;
657                                 case CONSTANT_NameAndType:
658                                         FREE(info, constant_nameandtype);
659                                         break;
660                                 }
661                         }
662                 }
663         }
664
665         if (c->cptags)
666                 MFREE(c->cptags, u1, c->cpcount);
667
668         if (c->cpinfos)
669                 MFREE(c->cpinfos, voidptr, c->cpcount);
670 }
671
672
673 /* class_getconstant ***********************************************************
674
675    Retrieves the value at position 'pos' of the constantpool of a
676    class. If the type of the value is other than 'ctype', an error is
677    thrown.
678
679 *******************************************************************************/
680
681 voidptr class_getconstant(classinfo *c, u4 pos, u4 ctype)
682 {
683         /* check index and type of constantpool entry */
684         /* (pos == 0 is caught by type comparison) */
685
686         if ((pos >= c->cpcount) || (c->cptags[pos] != ctype)) {
687                 exceptions_throw_classformaterror(c, "Illegal constant pool index");
688                 return NULL;
689         }
690
691         return c->cpinfos[pos];
692 }
693
694
695 /* innerclass_getconstant ******************************************************
696
697    Like class_getconstant, but if cptags is ZERO, null is returned.
698         
699 *******************************************************************************/
700
701 voidptr innerclass_getconstant(classinfo *c, u4 pos, u4 ctype)
702 {
703         /* invalid position in constantpool */
704
705         if (pos >= c->cpcount) {
706                 exceptions_throw_classformaterror(c, "Illegal constant pool index");
707                 return NULL;
708         }
709
710         /* constantpool entry of type 0 */      
711
712         if (c->cptags[pos] == 0)
713                 return NULL;
714
715         /* check type of constantpool entry */
716
717         if (c->cptags[pos] != ctype) {
718                 exceptions_throw_classformaterror(c, "Illegal constant pool index");
719                 return NULL;
720         }
721                 
722         return c->cpinfos[pos];
723 }
724
725
726 /* class_free ******************************************************************
727
728    Frees all resources used by the class.
729
730 *******************************************************************************/
731
732 void class_free(classinfo *c)
733 {
734         s4 i;
735         vftbl_t *v;
736                 
737         class_freecpool(c);
738
739         if (c->interfaces)
740                 MFREE(c->interfaces, classinfo*, c->interfacescount);
741
742         if (c->fields) {
743                 for (i = 0; i < c->fieldscount; i++)
744                         field_free(&(c->fields[i]));
745 #if defined(ENABLE_CACAO_GC)
746                 MFREE(c->fields, fieldinfo, c->fieldscount);
747 #endif
748         }
749         
750         if (c->methods) {
751                 for (i = 0; i < c->methodscount; i++)
752                         method_free(&(c->methods[i]));
753                 MFREE(c->methods, methodinfo, c->methodscount);
754         }
755
756         if ((v = c->vftbl) != NULL) {
757                 if (v->arraydesc)
758                         mem_free(v->arraydesc,sizeof(arraydescriptor));
759                 
760                 for (i = 0; i < v->interfacetablelength; i++) {
761                         MFREE(v->interfacetable[-i], methodptr, v->interfacevftbllength[i]);
762                 }
763                 MFREE(v->interfacevftbllength, s4, v->interfacetablelength);
764
765                 i = sizeof(vftbl_t) + sizeof(methodptr) * (v->vftbllength - 1) +
766                     sizeof(methodptr*) * (v->interfacetablelength -
767                                          (v->interfacetablelength > 0));
768                 v = (vftbl_t*) (((methodptr*) v) -
769                                                 (v->interfacetablelength - 1) * (v->interfacetablelength > 1));
770                 mem_free(v, i);
771         }
772
773         if (c->innerclass)
774                 MFREE(c->innerclass, innerclassinfo, c->innerclasscount);
775
776         /*      if (c->classvftbl)
777                 mem_free(c->header.vftbl, sizeof(vftbl) + sizeof(methodptr)*(c->vftbl->vftbllength-1)); */
778         
779 /*      GCFREE(c); */
780 }
781
782
783 /* get_array_class *************************************************************
784
785    Returns the array class with the given name for the given
786    classloader, or NULL if an exception occurred.
787
788    Note: This function does eager loading. 
789
790 *******************************************************************************/
791
792 static classinfo *get_array_class(utf *name,java_objectheader *initloader,
793                                                                                         java_objectheader *defloader,bool link)
794 {
795         classinfo *c;
796         
797         /* lookup this class in the classcache */
798         c = classcache_lookup(initloader,name);
799         if (!c)
800                 c = classcache_lookup_defined(defloader,name);
801
802         if (!c) {
803                 /* we have to create it */
804                 c = class_create_classinfo(name);
805                 c = load_newly_created_array(c,initloader);
806                 if (c == NULL)
807                         return NULL;
808         }
809
810         assert(c);
811         assert(c->state & CLASS_LOADED);
812         assert(c->classloader == defloader);
813
814         if (link && !(c->state & CLASS_LINKED))
815                 if (!link_class(c))
816                         return NULL;
817
818         assert(!link || (c->state & CLASS_LINKED));
819
820         return c;
821 }
822
823
824 /* class_array_of **************************************************************
825
826    Returns an array class with the given component class. The array
827    class is dynamically created if neccessary.
828
829 *******************************************************************************/
830
831 classinfo *class_array_of(classinfo *component, bool link)
832 {
833         java_objectheader *cl;
834     s4                 namelen;
835     char              *namebuf;
836         utf               *u;
837         classinfo         *c;
838         s4                 dumpsize;
839
840         cl = component->classloader;
841
842         dumpsize = dump_size();
843
844     /* Assemble the array class name */
845     namelen = component->name->blength;
846     
847     if (component->name->text[0] == '[') {
848         /* the component is itself an array */
849         namebuf = DMNEW(char, namelen + 1);
850         namebuf[0] = '[';
851         MCOPY(namebuf + 1, component->name->text, char, namelen);
852         namelen++;
853     }
854         else {
855         /* the component is a non-array class */
856         namebuf = DMNEW(char, namelen + 3);
857         namebuf[0] = '[';
858         namebuf[1] = 'L';
859         MCOPY(namebuf + 2, component->name->text, char, namelen);
860         namebuf[2 + namelen] = ';';
861         namelen += 3;
862     }
863
864         u = utf_new(namebuf, namelen);
865
866         c = get_array_class(u, cl, cl, 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 (class_is_primitive(sub) || class_is_primitive(super))
1499                 return false;
1500
1501         /* Check for interfaces. */
1502
1503         if (super->flags & ACC_INTERFACE) {
1504                 result = (sub->vftbl->interfacetablelength > super->index) &&
1505                         (sub->vftbl->interfacetable[-super->index] != NULL);
1506         }
1507         else {
1508                 /* java.lang.Object is the only super class of any
1509                    interface. */
1510
1511                 if (sub->flags & ACC_INTERFACE)
1512                         return (super == class_java_lang_Object);
1513
1514                 ASM_GETCLASSVALUES_ATOMIC(super->vftbl, sub->vftbl, &classvalues);
1515
1516                 diffval = classvalues.sub_baseval - classvalues.super_baseval;
1517                 result  = diffval <= (u4) classvalues.super_diffval;
1518         }
1519
1520         return result;
1521 }
1522
1523
1524 /* class_is_primitive **********************************************************
1525
1526    Checks if the given class is a primitive class.
1527
1528 *******************************************************************************/
1529
1530 bool class_is_primitive(classinfo *c)
1531 {
1532         if (c->flags & ACC_CLASS_PRIMITIVE)
1533                 return true;
1534
1535         return false;
1536 }
1537
1538
1539 /* class_is_array **************************************************************
1540
1541    Checks if the given class is an array class.
1542
1543 *******************************************************************************/
1544
1545 bool class_is_array(classinfo *c)
1546 {
1547         if (!(c->state & CLASS_LINKED))
1548                 if (!link_class(c))
1549                         return false;
1550
1551         return (c->vftbl->arraydesc != NULL);
1552 }
1553
1554
1555 /* class_is_interface **********************************************************
1556
1557    Checks if the given class is an interface.
1558
1559 *******************************************************************************/
1560
1561 bool class_is_interface(classinfo *c)
1562 {
1563         if (c->flags & ACC_INTERFACE)
1564                 return true;
1565
1566         return false;
1567 }
1568
1569
1570 /* class_get_superclass ********************************************************
1571
1572    Return the super class of the given class.  If the super-field is a
1573    class-reference, resolve it and store it in the classinfo.
1574
1575 *******************************************************************************/
1576
1577 classinfo *class_get_superclass(classinfo *c)
1578 {
1579         classinfo *super;
1580
1581         /* For java.lang.Object, primitive and Void classes we return
1582            NULL. */
1583
1584         if (c->super.any == NULL)
1585                 return NULL;
1586
1587         /* For interfaces we also return NULL. */
1588
1589         if (c->flags & ACC_INTERFACE)
1590                 return NULL;
1591
1592         /* We may have to resolve the super class reference. */
1593
1594         if (IS_CLASSREF(c->super)) {
1595                 super = resolve_classref_or_classinfo_eager(c->super, true);
1596
1597                 if (super == NULL)
1598                         return NULL;
1599
1600                 /* Store the resolved super class in the class structure. */
1601
1602                 c->super.cls = super;
1603         }
1604
1605         return c->super.cls;
1606 }
1607
1608
1609 /* class_get_declaringclass ****************************************************
1610
1611    If the class or interface given is a member of another class,
1612    return the declaring class.  For array and primitive classes return
1613    NULL.
1614
1615 *******************************************************************************/
1616
1617 classinfo *class_get_declaringclass(classinfo *c)
1618 {
1619         classref_or_classinfo  innercr;
1620         utf                   *innername;
1621         classref_or_classinfo  outercr;
1622         classinfo             *outer;
1623         int16_t                i;
1624
1625         /* return NULL for arrayclasses and primitive classes */
1626
1627         if (class_is_primitive(c) || (c->name->text[0] == '['))
1628                 return NULL;
1629
1630         /* no innerclasses exist */
1631
1632         if (c->innerclasscount == 0)
1633                 return NULL;
1634
1635         for (i = 0; i < c->innerclasscount; i++) {
1636                 /* Check if inner_class is a classref or a real class and get
1637                    the class name from the structure. */
1638
1639                 innercr = c->innerclass[i].inner_class;
1640
1641                 innername = IS_CLASSREF(innercr) ?
1642                         innercr.ref->name : innercr.cls->name;
1643
1644                 /* Is the current innerclass this class? */
1645
1646                 if (innername == c->name) {
1647                         /* Maybe the outer class is not loaded yet. */
1648
1649                         outercr = c->innerclass[i].outer_class;
1650
1651                         outer = resolve_classref_or_classinfo_eager(outercr, false);
1652
1653                         if (outer == NULL)
1654                                 return NULL;
1655
1656                         if (!(outer->state & CLASS_LINKED))
1657                                 if (!link_class(outer))
1658                                         return NULL;
1659
1660                         return outer;
1661                 }
1662         }
1663
1664         return NULL;
1665 }
1666
1667
1668 /* class_get_signature *********************************************************
1669
1670    Return the signature of the given class.  For array and primitive
1671    classes return NULL.
1672
1673 *******************************************************************************/
1674
1675 utf *class_get_signature(classinfo *c)
1676 {
1677         /* For array and primitive classes return NULL. */
1678
1679         if (class_is_array(c) || class_is_primitive(c))
1680                 return NULL;
1681
1682         return c->signature;
1683 }
1684
1685
1686 /* class_printflags ************************************************************
1687
1688    Prints flags of a class.
1689
1690 *******************************************************************************/
1691
1692 #if !defined(NDEBUG)
1693 void class_printflags(classinfo *c)
1694 {
1695         if (c == NULL) {
1696                 printf("NULL");
1697                 return;
1698         }
1699
1700         if (c->flags & ACC_PUBLIC)       printf(" PUBLIC");
1701         if (c->flags & ACC_PRIVATE)      printf(" PRIVATE");
1702         if (c->flags & ACC_PROTECTED)    printf(" PROTECTED");
1703         if (c->flags & ACC_STATIC)       printf(" STATIC");
1704         if (c->flags & ACC_FINAL)        printf(" FINAL");
1705         if (c->flags & ACC_SYNCHRONIZED) printf(" SYNCHRONIZED");
1706         if (c->flags & ACC_VOLATILE)     printf(" VOLATILE");
1707         if (c->flags & ACC_TRANSIENT)    printf(" TRANSIENT");
1708         if (c->flags & ACC_NATIVE)       printf(" NATIVE");
1709         if (c->flags & ACC_INTERFACE)    printf(" INTERFACE");
1710         if (c->flags & ACC_ABSTRACT)     printf(" ABSTRACT");
1711 }
1712 #endif
1713
1714
1715 /* class_print *****************************************************************
1716
1717    Prints classname plus flags.
1718
1719 *******************************************************************************/
1720
1721 #if !defined(NDEBUG)
1722 void class_print(classinfo *c)
1723 {
1724         if (c == NULL) {
1725                 printf("NULL");
1726                 return;
1727         }
1728
1729         utf_display_printable_ascii(c->name);
1730         class_printflags(c);
1731 }
1732 #endif
1733
1734
1735 /* class_classref_print ********************************************************
1736
1737    Prints classname plus referer class.
1738
1739 *******************************************************************************/
1740
1741 #if !defined(NDEBUG)
1742 void class_classref_print(constant_classref *cr)
1743 {
1744         if (cr == NULL) {
1745                 printf("NULL");
1746                 return;
1747         }
1748
1749         utf_display_printable_ascii(cr->name);
1750         printf("(ref.by ");
1751         if (cr->referer)
1752                 class_print(cr->referer);
1753         else
1754                 printf("NULL");
1755         printf(")");
1756 }
1757 #endif
1758
1759
1760 /* class_println ***************************************************************
1761
1762    Prints classname plus flags and new line.
1763
1764 *******************************************************************************/
1765
1766 #if !defined(NDEBUG)
1767 void class_println(classinfo *c)
1768 {
1769         class_print(c);
1770         printf("\n");
1771 }
1772 #endif
1773
1774
1775 /* class_classref_println ******************************************************
1776
1777    Prints classname plus referer class and new line.
1778
1779 *******************************************************************************/
1780
1781 #if !defined(NDEBUG)
1782 void class_classref_println(constant_classref *cr)
1783 {
1784         class_classref_print(cr);
1785         printf("\n");
1786 }
1787 #endif
1788
1789
1790 /* class_classref_or_classinfo_print *******************************************
1791
1792    Prints classname plus referer class.
1793
1794 *******************************************************************************/
1795
1796 #if !defined(NDEBUG)
1797 void class_classref_or_classinfo_print(classref_or_classinfo c)
1798 {
1799         if (c.any == NULL) {
1800                 printf("(classref_or_classinfo) NULL");
1801                 return;
1802         }
1803         if (IS_CLASSREF(c))
1804                 class_classref_print(c.ref);
1805         else
1806                 class_print(c.cls);
1807 }
1808 #endif
1809
1810
1811 /* class_classref_or_classinfo_println *****************************************
1812
1813    Prints classname plus referer class and a newline.
1814
1815 *******************************************************************************/
1816
1817 void class_classref_or_classinfo_println(classref_or_classinfo c)
1818 {
1819         class_classref_or_classinfo_println(c);
1820         printf("\n");
1821 }
1822
1823
1824 /* class_showconstantpool ******************************************************
1825
1826    Dump the constant pool of the given class to stdout.
1827
1828 *******************************************************************************/
1829
1830 #if !defined(NDEBUG)
1831 void class_showconstantpool (classinfo *c) 
1832 {
1833         u4 i;
1834         voidptr e;
1835
1836         printf ("---- dump of constant pool ----\n");
1837
1838         for (i=0; i<c->cpcount; i++) {
1839                 printf ("#%d:  ", (int) i);
1840                 
1841                 e = c -> cpinfos [i];
1842                 if (e) {
1843                         
1844                         switch (c -> cptags [i]) {
1845                         case CONSTANT_Class:
1846                                 printf ("Classreference -> ");
1847                                 utf_display_printable_ascii ( ((constant_classref*)e) -> name );
1848                                 break;
1849                         case CONSTANT_Fieldref:
1850                                 printf ("Fieldref -> ");
1851                                 field_fieldref_print((constant_FMIref *) e);
1852                                 break;
1853                         case CONSTANT_Methodref:
1854                                 printf ("Methodref -> ");
1855                                 method_methodref_print((constant_FMIref *) e);
1856                                 break;
1857                         case CONSTANT_InterfaceMethodref:
1858                                 printf ("InterfaceMethod -> ");
1859                                 method_methodref_print((constant_FMIref *) e);
1860                                 break;
1861                         case CONSTANT_String:
1862                                 printf ("String -> ");
1863                                 utf_display_printable_ascii (e);
1864                                 break;
1865                         case CONSTANT_Integer:
1866                                 printf ("Integer -> %d", (int) ( ((constant_integer*)e) -> value) );
1867                                 break;
1868                         case CONSTANT_Float:
1869                                 printf ("Float -> %f", ((constant_float*)e) -> value);
1870                                 break;
1871                         case CONSTANT_Double:
1872                                 printf ("Double -> %f", ((constant_double*)e) -> value);
1873                                 break;
1874                         case CONSTANT_Long:
1875                                 {
1876                                         u8 v = ((constant_long*)e) -> value;
1877 #if U8_AVAILABLE
1878                                         printf ("Long -> %ld", (long int) v);
1879 #else
1880                                         printf ("Long -> HI: %ld, LO: %ld\n", 
1881                                                         (long int) v.high, (long int) v.low);
1882 #endif 
1883                                 }
1884                                 break;
1885                         case CONSTANT_NameAndType:
1886                                 {
1887                                         constant_nameandtype *cnt = e;
1888                                         printf ("NameAndType: ");
1889                                         utf_display_printable_ascii (cnt->name);
1890                                         printf (" ");
1891                                         utf_display_printable_ascii (cnt->descriptor);
1892                                 }
1893                                 break;
1894                         case CONSTANT_Utf8:
1895                                 printf ("Utf8 -> ");
1896                                 utf_display_printable_ascii (e);
1897                                 break;
1898                         default: 
1899                                 log_text("Invalid type of ConstantPool-Entry");
1900                                 assert(0);
1901                         }
1902                 }
1903
1904                 printf ("\n");
1905         }
1906 }
1907 #endif /* !defined(NDEBUG) */
1908
1909
1910 /* class_showmethods ***********************************************************
1911
1912    Dump info about the fields and methods of the given class to stdout.
1913
1914 *******************************************************************************/
1915
1916 #if !defined(NDEBUG)
1917 void class_showmethods (classinfo *c)
1918 {
1919         s4 i;
1920         
1921         printf("--------- Fields and Methods ----------------\n");
1922         printf("Flags: ");
1923         class_printflags(c);
1924         printf("\n");
1925
1926         printf("This: ");
1927         utf_display_printable_ascii(c->name);
1928         printf("\n");
1929
1930         if (c->super.cls) {
1931                 printf("Super: ");
1932                 utf_display_printable_ascii(c->super.cls->name);
1933                 printf ("\n");
1934         }
1935
1936         printf("Index: %d\n", c->index);
1937         
1938         printf("Interfaces:\n");        
1939         for (i = 0; i < c->interfacescount; i++) {
1940                 printf("   ");
1941                 utf_display_printable_ascii(c->interfaces[i].cls->name);
1942                 printf (" (%d)\n", c->interfaces[i].cls->index);
1943         }
1944
1945         printf("Fields:\n");
1946         for (i = 0; i < c->fieldscount; i++)
1947                 field_println(&(c->fields[i]));
1948
1949         printf("Methods:\n");
1950         for (i = 0; i < c->methodscount; i++) {
1951                 methodinfo *m = &(c->methods[i]);
1952
1953                 if (!(m->flags & ACC_STATIC))
1954                         printf("vftblindex: %d   ", m->vftblindex);
1955
1956                 method_println(m);
1957         }
1958
1959         printf ("Virtual function table:\n");
1960         for (i = 0; i < c->vftbl->vftbllength; i++)
1961                 printf ("entry: %d,  %ld\n", i, (long int) (c->vftbl->table[i]));
1962 }
1963 #endif /* !defined(NDEBUG) */
1964
1965
1966 /*
1967  * These are local overrides for various environment variables in Emacs.
1968  * Please do not remove this and leave it at the end of the file, where
1969  * Emacs will automagically detect them.
1970  * ---------------------------------------------------------------------
1971  * Local variables:
1972  * mode: c
1973  * indent-tabs-mode: t
1974  * c-basic-offset: 4
1975  * tab-width: 4
1976  * End:
1977  * vim:noexpandtab:sw=4:ts=4:
1978  */