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