1 /* src/vm/class.c - class related functions
3 Copyright (C) 1996-2005 R. Grafl, A. Krall, C. Kruegel, C. Oates,
4 R. Obermaisser, M. Platter, M. Probst, S. Ring, E. Steiner,
5 C. Thalinger, D. Thuernbeck, P. Tomsich, C. Ullrich, J. Wenninger,
6 Institut f. Computersprachen - TU Wien
8 This file is part of CACAO.
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.
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.
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., 59 Temple Place - Suite 330, Boston, MA
25 Contact: cacao@complang.tuwien.ac.at
27 Authors: Reinhard Grafl
33 $Id: class.c 3999 2005-12-22 14:04:47Z twisti $
45 #include "mm/memory.h"
47 #if defined(USE_THREADS)
48 # if defined(NATIVE_THREADS)
49 # include "threads/native/threads.h"
51 # include "threads/green/threads.h"
52 # include "threads/green/locks.h"
56 #include "toolbox/logging.h"
58 #include "vm/classcache.h"
59 #include "vm/exceptions.h"
60 #include "vm/global.h"
61 #include "vm/loader.h"
62 #include "vm/options.h"
63 #include "vm/resolve.h"
64 #include "vm/statistics.h"
65 #include "vm/stringlocal.h"
69 /******************************************************************************/
71 /******************************************************************************/
78 #define CLASS_ASSERT(cond) assert(cond)
80 #define CLASS_ASSERT(cond)
84 /* global variables ***********************************************************/
86 list unlinkedclasses; /* this is only used for eager class */
90 /* frequently used classes ****************************************************/
92 /* important system classes */
94 classinfo *class_java_lang_Object = NULL;
95 classinfo *class_java_lang_Class = NULL;
96 classinfo *class_java_lang_ClassLoader = NULL;
97 classinfo *class_java_lang_Cloneable = NULL;
98 classinfo *class_java_lang_SecurityManager = NULL;
99 classinfo *class_java_lang_String = NULL;
100 classinfo *class_java_lang_System = NULL;
101 classinfo *class_java_lang_Thread = NULL;
102 classinfo *class_java_lang_ThreadGroup = NULL;
103 classinfo *class_java_lang_VMThread = NULL;
104 classinfo *class_java_io_Serializable = NULL;
107 /* system exception classes required in cacao */
109 classinfo *class_java_lang_Throwable = NULL;
110 classinfo *class_java_lang_VMThrowable = NULL;
111 classinfo *class_java_lang_Error = NULL;
112 classinfo *class_java_lang_NoClassDefFoundError = NULL;
113 classinfo *class_java_lang_LinkageError = NULL;
114 classinfo *class_java_lang_NoSuchMethodError = NULL;
115 classinfo *class_java_lang_OutOfMemoryError = NULL;
117 classinfo *class_java_lang_Exception = NULL;
118 classinfo *class_java_lang_ClassNotFoundException = NULL;
119 classinfo *class_java_lang_IllegalArgumentException = NULL;
120 classinfo *class_java_lang_IllegalMonitorStateException = NULL;
122 classinfo *class_java_lang_Void = NULL;
123 classinfo *class_java_lang_Boolean = NULL;
124 classinfo *class_java_lang_Byte = NULL;
125 classinfo *class_java_lang_Character = NULL;
126 classinfo *class_java_lang_Short = NULL;
127 classinfo *class_java_lang_Integer = NULL;
128 classinfo *class_java_lang_Long = NULL;
129 classinfo *class_java_lang_Float = NULL;
130 classinfo *class_java_lang_Double = NULL;
133 /* some runtime exception */
135 classinfo *class_java_lang_NullPointerException = NULL;
138 /* some classes which may be used more often */
140 classinfo *class_java_lang_StackTraceElement = NULL;
141 classinfo *class_java_lang_reflect_Constructor = NULL;
142 classinfo *class_java_lang_reflect_Field = NULL;
143 classinfo *class_java_lang_reflect_Method = NULL;
144 classinfo *class_java_security_PrivilegedAction = NULL;
145 classinfo *class_java_util_Vector = NULL;
147 classinfo *arrayclass_java_lang_Object = NULL;
150 /* pseudo classes for the typechecker */
152 classinfo *pseudo_class_Arraystub = NULL;
153 classinfo *pseudo_class_Null = NULL;
154 classinfo *pseudo_class_New = NULL;
157 /* class_set_packagename *******************************************************
159 Derive the package name from the class name and store it in the struct.
161 *******************************************************************************/
163 void class_set_packagename(classinfo *c)
165 char *p = UTF_END(c->name) - 1;
166 char *start = c->name->text;
168 /* set the package name */
169 /* classes in the unnamed package keep packagename == NULL */
171 if (c->name->text[0] == '[') {
172 /* set packagename of arrays to the element's package */
174 for (; *start == '['; start++);
176 /* skip the 'L' in arrays of references */
180 for (; (p > start) && (*p != '/'); --p);
182 c->packagename = utf_new(start, p - start);
185 for (; (p > start) && (*p != '/'); --p);
187 c->packagename = utf_new(start, p - start);
192 /* class_create_classinfo ******************************************************
194 Create a new classinfo struct. The class name is set to the given utf *,
195 most other fields are initialized to zero.
197 Note: classname may be NULL. In this case a not-yet-named classinfo is
198 created. The name must be filled in later and class_set_packagename
199 must be called after that.
201 *******************************************************************************/
203 classinfo *class_create_classinfo(utf *classname)
207 #if defined(ENABLE_STATISTICS)
209 count_class_infos += sizeof(classinfo);
212 /* we use a safe name for temporarily unnamed classes */
214 classname = utf_not_named_yet;
218 log_message_utf("Creating class: ", classname);
221 /* GCNEW_UNCOLLECTABLE clears the allocated memory */
223 c = GCNEW_UNCOLLECTABLE(classinfo, 1);
224 /*c=NEW(classinfo);*/
227 /* set the header.vftbl of all loaded classes to the one of
228 java.lang.Class, so Java code can use a class as object */
230 if (class_java_lang_Class)
231 if (class_java_lang_Class->vftbl)
232 c->object.header.vftbl = class_java_lang_Class->vftbl;
234 if (classname != utf_not_named_yet)
235 class_set_packagename(c);
237 #if defined(USE_THREADS) && defined(NATIVE_THREADS)
238 initObjectLock(&c->object.header);
245 /* class_postset_header_vftbl **************************************************
247 Set the header.vftbl of all classes created before java.lang.Class
248 was linked. This is necessary that Java code can use a class as
251 *******************************************************************************/
253 void class_postset_header_vftbl(void)
257 classcache_name_entry *nmen;
258 classcache_class_entry *clsen;
260 assert(class_java_lang_Class);
262 for (slot = 0; slot < hashtable_classcache.size; slot++) {
263 nmen = (classcache_name_entry *) hashtable_classcache.ptr[slot];
265 for (; nmen; nmen = nmen->hashlink) {
266 /* iterate over all class entries */
268 for (clsen = nmen->classes; clsen; clsen = clsen->next) {
271 /* now set the the vftbl */
273 if (c->object.header.vftbl == NULL)
274 c->object.header.vftbl = class_java_lang_Class->vftbl;
281 /* class_freepool **************************************************************
283 Frees all resources used by this classes Constant Pool.
285 *******************************************************************************/
287 static void class_freecpool(classinfo *c)
293 if (c->cptags && c->cpinfos) {
294 for (idx = 0; idx < c->cpcount; idx++) {
295 tag = c->cptags[idx];
296 info = c->cpinfos[idx];
300 case CONSTANT_Fieldref:
301 case CONSTANT_Methodref:
302 case CONSTANT_InterfaceMethodref:
303 FREE(info, constant_FMIref);
305 case CONSTANT_Integer:
306 FREE(info, constant_integer);
309 FREE(info, constant_float);
312 FREE(info, constant_long);
314 case CONSTANT_Double:
315 FREE(info, constant_double);
317 case CONSTANT_NameAndType:
318 FREE(info, constant_nameandtype);
326 MFREE(c->cptags, u1, c->cpcount);
329 MFREE(c->cpinfos, voidptr, c->cpcount);
333 /* class_getconstant ***********************************************************
335 Retrieves the value at position 'pos' of the constantpool of a
336 class. If the type of the value is other than 'ctype', an error is
339 *******************************************************************************/
341 voidptr class_getconstant(classinfo *c, u4 pos, u4 ctype)
343 /* check index and type of constantpool entry */
344 /* (pos == 0 is caught by type comparison) */
346 if (pos >= c->cpcount || c->cptags[pos] != ctype) {
347 *exceptionptr = new_classformaterror(c, "Illegal constant pool index");
351 return c->cpinfos[pos];
355 /* innerclass_getconstant ******************************************************
357 Like class_getconstant, but if cptags is ZERO, null is returned.
359 *******************************************************************************/
361 voidptr innerclass_getconstant(classinfo *c, u4 pos, u4 ctype)
363 /* invalid position in constantpool */
364 if (pos >= c->cpcount) {
365 *exceptionptr = new_classformaterror(c, "Illegal constant pool index");
369 /* constantpool entry of type 0 */
373 /* check type of constantpool entry */
374 if (c->cptags[pos] != ctype) {
375 *exceptionptr = new_classformaterror(c, "Illegal constant pool index");
379 return c->cpinfos[pos];
383 /* class_free ******************************************************************
385 Frees all resources used by the class.
387 *******************************************************************************/
389 void class_free(classinfo *c)
397 MFREE(c->interfaces, classinfo*, c->interfacescount);
400 for (i = 0; i < c->fieldscount; i++)
401 field_free(&(c->fields[i]));
402 /* MFREE(c->fields, fieldinfo, c->fieldscount); */
406 for (i = 0; i < c->methodscount; i++)
407 method_free(&(c->methods[i]));
408 MFREE(c->methods, methodinfo, c->methodscount);
411 if ((v = c->vftbl) != NULL) {
413 mem_free(v->arraydesc,sizeof(arraydescriptor));
415 for (i = 0; i < v->interfacetablelength; i++) {
416 MFREE(v->interfacetable[-i], methodptr, v->interfacevftbllength[i]);
418 MFREE(v->interfacevftbllength, s4, v->interfacetablelength);
420 i = sizeof(vftbl_t) + sizeof(methodptr) * (v->vftbllength - 1) +
421 sizeof(methodptr*) * (v->interfacetablelength -
422 (v->interfacetablelength > 0));
423 v = (vftbl_t*) (((methodptr*) v) -
424 (v->interfacetablelength - 1) * (v->interfacetablelength > 1));
429 MFREE(c->innerclass, innerclassinfo, c->innerclasscount);
431 /* if (c->classvftbl)
432 mem_free(c->header.vftbl, sizeof(vftbl) + sizeof(methodptr)*(c->vftbl->vftbllength-1)); */
438 /* get_array_class *************************************************************
440 Returns the array class with the given name for the given
441 classloader, or NULL if an exception occurred.
443 Note: This function does eager loading.
445 *******************************************************************************/
447 static classinfo *get_array_class(utf *name,java_objectheader *initloader,
448 java_objectheader *defloader,bool link)
452 /* lookup this class in the classcache */
453 c = classcache_lookup(initloader,name);
455 c = classcache_lookup_defined(defloader,name);
458 /* we have to create it */
459 c = class_create_classinfo(name);
460 c = load_newly_created_array(c,initloader);
466 CLASS_ASSERT(c->state & CLASS_LOADED);
467 CLASS_ASSERT(c->classloader == defloader);
469 if (link && !(c->state & CLASS_LINKED))
473 CLASS_ASSERT(!link || (c->state & CLASS_LINKED));
479 /* class_array_of **************************************************************
481 Returns an array class with the given component class. The array
482 class is dynamically created if neccessary.
484 *******************************************************************************/
486 classinfo *class_array_of(classinfo *component, bool link)
491 /* Assemble the array class name */
492 namelen = component->name->blength;
494 if (component->name->text[0] == '[') {
495 /* the component is itself an array */
496 namebuf = DMNEW(char, namelen + 1);
498 MCOPY(namebuf + 1, component->name->text, char, namelen);
502 /* the component is a non-array class */
503 namebuf = DMNEW(char, namelen + 3);
506 MCOPY(namebuf + 2, component->name->text, char, namelen);
507 namebuf[2 + namelen] = ';';
511 return get_array_class(utf_new(namebuf, namelen),
512 component->classloader,
513 component->classloader,
518 /* class_multiarray_of *********************************************************
520 Returns an array class with the given dimension and element class.
521 The array class is dynamically created if neccessary.
523 *******************************************************************************/
525 classinfo *class_multiarray_of(s4 dim, classinfo *element, bool link)
531 log_text("Invalid array dimension requested");
535 /* Assemble the array class name */
536 namelen = element->name->blength;
538 if (element->name->text[0] == '[') {
539 /* the element is itself an array */
540 namebuf = DMNEW(char, namelen + dim);
541 memcpy(namebuf + dim, element->name->text, namelen);
545 /* the element is a non-array class */
546 namebuf = DMNEW(char, namelen + 2 + dim);
548 memcpy(namebuf + dim + 1, element->name->text, namelen);
549 namelen += (2 + dim);
550 namebuf[namelen - 1] = ';';
552 memset(namebuf, '[', dim);
554 return get_array_class(utf_new(namebuf, namelen),
555 element->classloader,
556 element->classloader,
561 /* class_lookup_classref *******************************************************
563 Looks up the constant_classref for a given classname in the classref
567 cls..............the class containing the reference
568 name.............the name of the class refered to
571 a pointer to a constant_classref, or
572 NULL if the reference was not found
574 *******************************************************************************/
576 constant_classref *class_lookup_classref(classinfo *cls, utf *name)
578 constant_classref *ref;
579 extra_classref *xref;
584 CLASS_ASSERT(!cls->classrefcount || cls->classrefs);
586 /* first search the main classref table */
587 count = cls->classrefcount;
588 ref = cls->classrefs;
589 for (; count; --count, ++ref)
590 if (ref->name == name)
593 /* next try the list of extra classrefs */
594 for (xref = cls->extclassrefs; xref; xref = xref->next) {
595 if (xref->classref.name == name)
596 return &(xref->classref);
604 /* class_get_classref **********************************************************
606 Returns the constant_classref for a given classname.
609 cls..............the class containing the reference
610 name.............the name of the class refered to
613 a pointer to a constant_classref (never NULL)
616 The given name is not checked for validity!
618 *******************************************************************************/
620 constant_classref *class_get_classref(classinfo *cls, utf *name)
622 constant_classref *ref;
623 extra_classref *xref;
628 ref = class_lookup_classref(cls,name);
632 xref = NEW(extra_classref);
633 CLASSREF_INIT(xref->classref,cls,name);
635 xref->next = cls->extclassrefs;
636 cls->extclassrefs = xref;
638 return &(xref->classref);
642 /* class_get_self_classref *****************************************************
644 Returns the constant_classref to the class itself.
647 cls..............the class containing the reference
650 a pointer to a constant_classref (never NULL)
652 *******************************************************************************/
654 constant_classref *class_get_self_classref(classinfo *cls)
656 /* XXX this should be done in a faster way. Maybe always make */
657 /* the classref of index 0 a self reference. */
658 return class_get_classref(cls,cls->name);
661 /* class_get_classref_multiarray_of ********************************************
663 Returns an array type reference with the given dimension and element class
667 dim..............the requested dimension
668 dim must be in [1;255]. This is NOT checked!
669 ref..............the component class reference
672 a pointer to the class reference for the array type
675 The referer of `ref` is used as the referer for the new classref.
677 *******************************************************************************/
679 constant_classref *class_get_classref_multiarray_of(s4 dim, constant_classref *ref)
685 CLASS_ASSERT(dim >= 1 && dim <= 255);
687 /* Assemble the array class name */
688 namelen = ref->name->blength;
690 if (ref->name->text[0] == '[') {
691 /* the element is itself an array */
692 namebuf = DMNEW(char, namelen + dim);
693 memcpy(namebuf + dim, ref->name->text, namelen);
697 /* the element is a non-array class */
698 namebuf = DMNEW(char, namelen + 2 + dim);
700 memcpy(namebuf + dim + 1, ref->name->text, namelen);
701 namelen += (2 + dim);
702 namebuf[namelen - 1] = ';';
704 memset(namebuf, '[', dim);
706 return class_get_classref(ref->referer,utf_new(namebuf, namelen));
710 /* class_get_classref_component_of *********************************************
712 Returns the component classref of a given array type reference
715 ref..............the array type reference
718 a reference to the component class, or
719 NULL if `ref` is not an object array type reference
722 The referer of `ref` is used as the referer for the new classref.
724 *******************************************************************************/
726 constant_classref *class_get_classref_component_of(constant_classref *ref)
733 name = ref->name->text;
737 namelen = ref->name->blength - 1;
742 else if (*name != '[') {
746 return class_get_classref(ref->referer, utf_new(name, namelen));
750 /* class_findmethod ************************************************************
752 Searches a 'classinfo' structure for a method having the given name
753 and descriptor. If descriptor is NULL, it is ignored.
755 *******************************************************************************/
757 methodinfo *class_findmethod(classinfo *c, utf *name, utf *desc)
762 for (i = 0; i < c->methodscount; i++) {
763 m = &(c->methods[i]);
765 if ((m->name == name) && ((desc == NULL) || (m->descriptor == desc)))
773 /************************* Function: class_findmethod_approx ******************
775 like class_findmethod but ignores the return value when comparing the
778 *******************************************************************************/
780 methodinfo *class_findmethod_approx(classinfo *c, utf *name, utf *desc)
784 for (i = 0; i < c->methodscount; i++) {
785 if (c->methods[i].name == name) {
786 utf *meth_descr = c->methods[i].descriptor;
790 return &(c->methods[i]);
792 if (desc->blength <= meth_descr->blength) {
793 /* current position in utf text */
794 char *desc_utf_ptr = desc->text;
795 char *meth_utf_ptr = meth_descr->text;
796 /* points behind utf strings */
797 char *desc_end = UTF_END(desc);
798 char *meth_end = UTF_END(meth_descr);
801 /* compare argument types */
802 while (desc_utf_ptr < desc_end && meth_utf_ptr < meth_end) {
804 if ((ch = *desc_utf_ptr++) != (*meth_utf_ptr++))
805 break; /* no match */
808 return &(c->methods[i]); /* all parameter types equal */
818 /* class_resolvemethod *********************************************************
820 Searches a class and it's super classes for a method.
822 Superinterfaces are *not* searched.
824 *******************************************************************************/
826 methodinfo *class_resolvemethod(classinfo *c, utf *name, utf *desc)
831 m = class_findmethod(c, name, desc);
836 /* JVM Specification bug:
838 It is important NOT to resolve special <init> and <clinit>
839 methods to super classes or interfaces; yet, this is not
840 explicited in the specification. Section 5.4.3.3 should be
841 updated appropriately. */
843 if (name == utf_init || name == utf_clinit)
853 /* class_resolveinterfacemethod_intern *****************************************
855 Internally used helper function. Do not use this directly.
857 *******************************************************************************/
859 static methodinfo *class_resolveinterfacemethod_intern(classinfo *c,
860 utf *name, utf *desc)
865 m = class_findmethod(c, name, desc);
870 /* try the superinterfaces */
872 for (i = 0; i < c->interfacescount; i++) {
873 m = class_resolveinterfacemethod_intern(c->interfaces[i].cls,
884 /* class_resolveclassmethod ****************************************************
886 Resolves a reference from REFERER to a method with NAME and DESC in
889 If the method cannot be resolved the return value is NULL. If
890 EXCEPT is true *exceptionptr is set, too.
892 *******************************************************************************/
894 methodinfo *class_resolveclassmethod(classinfo *c, utf *name, utf *desc,
895 classinfo *referer, bool except)
901 /* XXX resolve class c */
902 /* XXX check access from REFERER to C */
904 /* if (c->flags & ACC_INTERFACE) { */
906 /* *exceptionptr = */
907 /* new_exception(string_java_lang_IncompatibleClassChangeError); */
911 /* try class c and its superclasses */
915 m = class_resolvemethod(cls, name, desc);
920 /* try the superinterfaces */
922 for (i = 0; i < c->interfacescount; i++) {
923 m = class_resolveinterfacemethod_intern(c->interfaces[i].cls,
931 *exceptionptr = exceptions_new_nosuchmethoderror(c, name, desc);
936 if ((m->flags & ACC_ABSTRACT) && !(c->flags & ACC_ABSTRACT)) {
938 *exceptionptr = new_exception(string_java_lang_AbstractMethodError);
943 /* XXX check access rights */
949 /* class_resolveinterfacemethod ************************************************
951 Resolves a reference from REFERER to a method with NAME and DESC in
954 If the method cannot be resolved the return value is NULL. If
955 EXCEPT is true *exceptionptr is set, too.
957 *******************************************************************************/
959 methodinfo *class_resolveinterfacemethod(classinfo *c, utf *name, utf *desc,
960 classinfo *referer, bool except)
964 /* XXX resolve class c */
965 /* XXX check access from REFERER to C */
967 if (!(c->flags & ACC_INTERFACE)) {
970 new_exception(string_java_lang_IncompatibleClassChangeError);
975 mi = class_resolveinterfacemethod_intern(c, name, desc);
980 /* try class java.lang.Object */
982 mi = class_findmethod(class_java_lang_Object, name, desc);
989 exceptions_new_nosuchmethoderror(c, name, desc);
995 /* class_findfield *************************************************************
997 Searches for field with specified name and type in a classinfo
998 structure. If no such field is found NULL is returned.
1000 *******************************************************************************/
1002 fieldinfo *class_findfield(classinfo *c, utf *name, utf *desc)
1006 for (i = 0; i < c->fieldscount; i++)
1007 if ((c->fields[i].name == name) && (c->fields[i].descriptor == desc))
1008 return &(c->fields[i]);
1011 return class_findfield(c->super.cls, name, desc);
1017 /* class_findfield_approx ******************************************************
1019 Searches in 'classinfo'-structure for a field with the specified
1022 *******************************************************************************/
1024 fieldinfo *class_findfield_by_name(classinfo *c, utf *name)
1028 /* get field index */
1030 i = class_findfield_index_by_name(c, name);
1032 /* field was not found, return */
1037 /* return field address */
1039 return &(c->fields[i]);
1043 s4 class_findfield_index_by_name(classinfo *c, utf *name)
1047 for (i = 0; i < c->fieldscount; i++) {
1048 /* compare field names */
1050 if ((c->fields[i].name == name))
1054 /* field was not found, raise exception */
1056 *exceptionptr = new_exception(string_java_lang_NoSuchFieldException);
1062 /****************** Function: class_resolvefield_int ***************************
1064 This is an internally used helper function. Do not use this directly.
1066 Tries to resolve a field having the given name and type.
1067 If the field cannot be resolved, NULL is returned.
1069 *******************************************************************************/
1071 static fieldinfo *class_resolvefield_int(classinfo *c, utf *name, utf *desc)
1076 /* search for field in class c */
1078 for (i = 0; i < c->fieldscount; i++) {
1079 if ((c->fields[i].name == name) && (c->fields[i].descriptor == desc)) {
1080 return &(c->fields[i]);
1084 /* try superinterfaces recursively */
1086 for (i = 0; i < c->interfacescount; i++) {
1087 fi = class_resolvefield_int(c->interfaces[i].cls, name, desc);
1092 /* try superclass */
1095 return class_resolvefield_int(c->super.cls, name, desc);
1103 /********************* Function: class_resolvefield ***************************
1105 Resolves a reference from REFERER to a field with NAME and DESC in class C.
1107 If the field cannot be resolved the return value is NULL. If EXCEPT is
1108 true *exceptionptr is set, too.
1110 *******************************************************************************/
1112 fieldinfo *class_resolvefield(classinfo *c, utf *name, utf *desc,
1113 classinfo *referer, bool except)
1117 /* XXX resolve class c */
1118 /* XXX check access from REFERER to C */
1120 fi = class_resolvefield_int(c, name, desc);
1125 new_exception_utfmessage(string_java_lang_NoSuchFieldError,
1131 /* XXX check access rights */
1137 /* class_issubclass ************************************************************
1139 Checks if sub is a descendant of super.
1141 *******************************************************************************/
1143 bool class_issubclass(classinfo *sub, classinfo *super)
1152 sub = sub->super.cls;
1157 #if !defined(NDEBUG)
1158 void class_showconstanti(classinfo *c, int ii)
1164 printf ("#%d: ", (int) i);
1166 switch (c->cptags [i]) {
1167 case CONSTANT_Class:
1168 printf("Classreference -> ");
1169 utf_display(((constant_classref*)e)->name);
1172 case CONSTANT_Fieldref:
1173 printf("Fieldref -> "); goto displayFMIi;
1174 case CONSTANT_Methodref:
1175 printf("Methodref -> "); goto displayFMIi;
1176 case CONSTANT_InterfaceMethodref:
1177 printf("InterfaceMethod -> "); goto displayFMIi;
1180 constant_FMIref *fmi = e;
1181 utf_display(fmi->classref->name);
1183 utf_display(fmi->name);
1185 utf_display(fmi->descriptor);
1189 case CONSTANT_String:
1190 printf("String -> ");
1193 case CONSTANT_Integer:
1194 printf("Integer -> %d", (int) (((constant_integer*)e)->value));
1196 case CONSTANT_Float:
1197 printf("Float -> %f", ((constant_float*)e)->value);
1199 case CONSTANT_Double:
1200 printf("Double -> %f", ((constant_double*)e)->value);
1204 u8 v = ((constant_long*)e)->value;
1206 printf("Long -> %ld", (long int) v);
1208 printf("Long -> HI: %ld, LO: %ld\n",
1209 (long int) v.high, (long int) v.low);
1213 case CONSTANT_NameAndType:
1215 constant_nameandtype *cnt = e;
1216 printf("NameAndType: ");
1217 utf_display(cnt->name);
1219 utf_display(cnt->descriptor);
1227 log_text("Invalid type of ConstantPool-Entry");
1235 void class_showconstantpool (classinfo *c)
1240 printf ("---- dump of constant pool ----\n");
1242 for (i=0; i<c->cpcount; i++) {
1243 printf ("#%d: ", (int) i);
1245 e = c -> cpinfos [i];
1248 switch (c -> cptags [i]) {
1249 case CONSTANT_Class:
1250 printf ("Classreference -> ");
1251 utf_display ( ((constant_classref*)e) -> name );
1254 case CONSTANT_Fieldref:
1255 printf ("Fieldref -> "); goto displayFMI;
1256 case CONSTANT_Methodref:
1257 printf ("Methodref -> "); goto displayFMI;
1258 case CONSTANT_InterfaceMethodref:
1259 printf ("InterfaceMethod -> "); goto displayFMI;
1262 constant_FMIref *fmi = e;
1263 utf_display ( fmi->classref->name );
1265 utf_display ( fmi->name);
1267 utf_display ( fmi->descriptor );
1271 case CONSTANT_String:
1272 printf ("String -> ");
1275 case CONSTANT_Integer:
1276 printf ("Integer -> %d", (int) ( ((constant_integer*)e) -> value) );
1278 case CONSTANT_Float:
1279 printf ("Float -> %f", ((constant_float*)e) -> value);
1281 case CONSTANT_Double:
1282 printf ("Double -> %f", ((constant_double*)e) -> value);
1286 u8 v = ((constant_long*)e) -> value;
1288 printf ("Long -> %ld", (long int) v);
1290 printf ("Long -> HI: %ld, LO: %ld\n",
1291 (long int) v.high, (long int) v.low);
1295 case CONSTANT_NameAndType:
1297 constant_nameandtype *cnt = e;
1298 printf ("NameAndType: ");
1299 utf_display (cnt->name);
1301 utf_display (cnt->descriptor);
1305 printf ("Utf8 -> ");
1309 log_text("Invalid type of ConstantPool-Entry");
1320 /********** Function: class_showmethods (debugging only) *************/
1322 void class_showmethods (classinfo *c)
1326 printf ("--------- Fields and Methods ----------------\n");
1327 printf ("Flags: "); printflags (c->flags); printf ("\n");
1329 printf ("This: "); utf_display (c->name); printf ("\n");
1331 printf ("Super: "); utf_display (c->super.cls->name); printf ("\n");
1333 printf ("Index: %d\n", c->index);
1335 printf ("interfaces:\n");
1336 for (i=0; i < c-> interfacescount; i++) {
1338 utf_display (c -> interfaces[i].cls -> name);
1339 printf (" (%d)\n", c->interfaces[i].cls -> index);
1342 printf ("fields:\n");
1343 for (i=0; i < c -> fieldscount; i++) {
1344 field_display (&(c -> fields[i]));
1347 printf ("methods:\n");
1348 for (i=0; i < c -> methodscount; i++) {
1349 methodinfo *m = &(c->methods[i]);
1350 if ( !(m->flags & ACC_STATIC))
1351 printf ("vftblindex: %d ", m->vftblindex);
1353 method_display ( m );
1357 printf ("Virtual function table:\n");
1358 for (i=0; i<c->vftbl->vftbllength; i++) {
1359 printf ("entry: %d, %ld\n", i, (long int) (c->vftbl->table[i]) );
1363 #endif /* !defined(NDEBUG) */
1367 * These are local overrides for various environment variables in Emacs.
1368 * Please do not remove this and leave it at the end of the file, where
1369 * Emacs will automagically detect them.
1370 * ---------------------------------------------------------------------
1373 * indent-tabs-mode: t