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 3542 2005-11-03 20:34:14Z twisti $
43 #include "mm/memory.h"
45 #if defined(USE_THREADS)
46 # if defined(NATIVE_THREADS)
47 # include "threads/native/threads.h"
49 # include "threads/green/threads.h"
50 # include "threads/green/locks.h"
54 #include "toolbox/logging.h"
56 #include "vm/classcache.h"
57 #include "vm/exceptions.h"
58 #include "vm/global.h"
59 #include "vm/loader.h"
60 #include "vm/options.h"
61 #include "vm/resolve.h"
62 #include "vm/statistics.h"
63 #include "vm/stringlocal.h"
64 #include "vm/tables.h"
68 /******************************************************************************/
70 /******************************************************************************/
77 #define CLASS_ASSERT(cond) assert(cond)
79 #define CLASS_ASSERT(cond)
83 /* global variables ***********************************************************/
85 list unlinkedclasses; /* this is only used for eager class */
89 /* frequently used classes ****************************************************/
91 /* important system classes */
93 classinfo *class_java_lang_Object = NULL;
94 classinfo *class_java_lang_Class = NULL;
95 classinfo *class_java_lang_ClassLoader = NULL;
96 classinfo *class_java_lang_Cloneable = NULL;
97 classinfo *class_java_lang_SecurityManager = NULL;
98 classinfo *class_java_lang_String = NULL;
99 classinfo *class_java_lang_System = NULL;
100 classinfo *class_java_lang_Thread = NULL;
101 classinfo *class_java_lang_ThreadGroup = NULL;
102 classinfo *class_java_lang_VMThread = NULL;
103 classinfo *class_java_io_Serializable = NULL;
106 /* system exception classes required in cacao */
108 classinfo *class_java_lang_Throwable = NULL;
109 classinfo *class_java_lang_VMThrowable = NULL;
110 classinfo *class_java_lang_Error = NULL;
111 classinfo *class_java_lang_NoClassDefFoundError = NULL;
112 classinfo *class_java_lang_OutOfMemoryError = NULL;
114 classinfo *class_java_lang_Exception = NULL;
115 classinfo *class_java_lang_ClassNotFoundException = NULL;
116 classinfo *class_java_lang_IllegalArgumentException = NULL;
117 classinfo *class_java_lang_IllegalMonitorStateException = NULL;
119 classinfo *class_java_lang_Void = NULL;
120 classinfo *class_java_lang_Boolean = NULL;
121 classinfo *class_java_lang_Byte = NULL;
122 classinfo *class_java_lang_Character = NULL;
123 classinfo *class_java_lang_Short = NULL;
124 classinfo *class_java_lang_Integer = NULL;
125 classinfo *class_java_lang_Long = NULL;
126 classinfo *class_java_lang_Float = NULL;
127 classinfo *class_java_lang_Double = NULL;
130 /* some runtime exception */
132 classinfo *class_java_lang_NullPointerException = NULL;
135 /* some classes which may be used more often */
137 classinfo *class_java_lang_StackTraceElement = NULL;
138 classinfo *class_java_lang_reflect_Constructor = NULL;
139 classinfo *class_java_lang_reflect_Field = NULL;
140 classinfo *class_java_lang_reflect_Method = NULL;
141 classinfo *class_java_security_PrivilegedAction = NULL;
142 classinfo *class_java_util_Vector = NULL;
144 classinfo *arrayclass_java_lang_Object = NULL;
147 /* pseudo classes for the typechecker */
149 classinfo *pseudo_class_Arraystub = NULL;
150 classinfo *pseudo_class_Null = NULL;
151 classinfo *pseudo_class_New = NULL;
154 /* class_set_packagename *******************************************************
156 Derive the package name from the class name and store it in the struct.
158 *******************************************************************************/
160 void class_set_packagename(classinfo *c)
162 char *p = UTF_END(c->name) - 1;
163 char *start = c->name->text;
165 /* set the package name */
166 /* classes in the unnamed package keep packagename == NULL */
168 if (c->name->text[0] == '[') {
169 /* set packagename of arrays to the element's package */
171 for (; *start == '['; start++);
173 /* skip the 'L' in arrays of references */
177 for (; (p > start) && (*p != '/'); --p);
179 c->packagename = utf_new(start, p - start);
182 for (; (p > start) && (*p != '/'); --p);
184 c->packagename = utf_new(start, p - start);
189 /* class_create_classinfo ******************************************************
191 Create a new classinfo struct. The class name is set to the given utf *,
192 most other fields are initialized to zero.
194 Note: classname may be NULL. In this case a not-yet-named classinfo is
195 created. The name must be filled in later and class_set_packagename
196 must be called after that.
198 *******************************************************************************/
200 classinfo *class_create_classinfo(utf *classname)
204 #if defined(STATISTICS)
206 count_class_infos += sizeof(classinfo);
209 /* we use a safe name for temporarily unnamed classes */
211 classname = utf_not_named_yet;
214 log_message_utf("Creating class: ", classname);
216 /* GCNEW_UNCOLLECTABLE clears the allocated memory */
218 c = GCNEW_UNCOLLECTABLE(classinfo, 1);
219 /*c=NEW(classinfo);*/
222 if (classname != utf_not_named_yet) {
223 class_set_packagename(c);
226 #if defined(USE_THREADS) && defined(NATIVE_THREADS)
227 initObjectLock(&c->header);
233 /* class_freepool **************************************************************
235 Frees all resources used by this classes Constant Pool.
237 *******************************************************************************/
239 static void class_freecpool(classinfo *c)
245 if (c->cptags && c->cpinfos) {
246 for (idx = 0; idx < c->cpcount; idx++) {
247 tag = c->cptags[idx];
248 info = c->cpinfos[idx];
252 case CONSTANT_Fieldref:
253 case CONSTANT_Methodref:
254 case CONSTANT_InterfaceMethodref:
255 FREE(info, constant_FMIref);
257 case CONSTANT_Integer:
258 FREE(info, constant_integer);
261 FREE(info, constant_float);
264 FREE(info, constant_long);
266 case CONSTANT_Double:
267 FREE(info, constant_double);
269 case CONSTANT_NameAndType:
270 FREE(info, constant_nameandtype);
278 MFREE(c->cptags, u1, c->cpcount);
281 MFREE(c->cpinfos, voidptr, c->cpcount);
285 /* class_getconstant ***********************************************************
287 Retrieves the value at position 'pos' of the constantpool of a
288 class. If the type of the value is other than 'ctype', an error is
291 *******************************************************************************/
293 voidptr class_getconstant(classinfo *c, u4 pos, u4 ctype)
295 /* check index and type of constantpool entry */
296 /* (pos == 0 is caught by type comparison) */
298 if (pos >= c->cpcount || c->cptags[pos] != ctype) {
299 *exceptionptr = new_classformaterror(c, "Illegal constant pool index");
303 return c->cpinfos[pos];
307 /* innerclass_getconstant ******************************************************
309 Like class_getconstant, but if cptags is ZERO, null is returned.
311 *******************************************************************************/
313 voidptr innerclass_getconstant(classinfo *c, u4 pos, u4 ctype)
315 /* invalid position in constantpool */
316 if (pos >= c->cpcount) {
317 *exceptionptr = new_classformaterror(c, "Illegal constant pool index");
321 /* constantpool entry of type 0 */
325 /* check type of constantpool entry */
326 if (c->cptags[pos] != ctype) {
327 *exceptionptr = new_classformaterror(c, "Illegal constant pool index");
331 return c->cpinfos[pos];
335 /* class_free ******************************************************************
337 Frees all resources used by the class.
339 *******************************************************************************/
341 void class_free(classinfo *c)
349 MFREE(c->interfaces, classinfo*, c->interfacescount);
352 for (i = 0; i < c->fieldscount; i++)
353 field_free(&(c->fields[i]));
354 /* MFREE(c->fields, fieldinfo, c->fieldscount); */
358 for (i = 0; i < c->methodscount; i++)
359 method_free(&(c->methods[i]));
360 MFREE(c->methods, methodinfo, c->methodscount);
363 if ((v = c->vftbl) != NULL) {
365 mem_free(v->arraydesc,sizeof(arraydescriptor));
367 for (i = 0; i < v->interfacetablelength; i++) {
368 MFREE(v->interfacetable[-i], methodptr, v->interfacevftbllength[i]);
370 MFREE(v->interfacevftbllength, s4, v->interfacetablelength);
372 i = sizeof(vftbl_t) + sizeof(methodptr) * (v->vftbllength - 1) +
373 sizeof(methodptr*) * (v->interfacetablelength -
374 (v->interfacetablelength > 0));
375 v = (vftbl_t*) (((methodptr*) v) -
376 (v->interfacetablelength - 1) * (v->interfacetablelength > 1));
381 MFREE(c->innerclass, innerclassinfo, c->innerclasscount);
383 /* if (c->classvftbl)
384 mem_free(c->header.vftbl, sizeof(vftbl) + sizeof(methodptr)*(c->vftbl->vftbllength-1)); */
390 /* get_array_class *************************************************************
392 Returns the array class with the given name for the given
393 classloader, or NULL if an exception occurred.
395 Note: This function does eager loading.
397 *******************************************************************************/
399 static classinfo *get_array_class(utf *name,java_objectheader *initloader,
400 java_objectheader *defloader,bool link)
404 /* lookup this class in the classcache */
405 c = classcache_lookup(initloader,name);
407 c = classcache_lookup_defined(defloader,name);
410 /* we have to create it */
411 c = class_create_classinfo(name);
412 c = load_newly_created_array(c,initloader);
418 CLASS_ASSERT(c->loaded);
419 CLASS_ASSERT(c->classloader == defloader);
421 if (link && !c->linked)
425 CLASS_ASSERT(!link || c->linked);
431 /* class_array_of **************************************************************
433 Returns an array class with the given component class. The array
434 class is dynamically created if neccessary.
436 *******************************************************************************/
438 classinfo *class_array_of(classinfo *component, bool link)
443 /* Assemble the array class name */
444 namelen = component->name->blength;
446 if (component->name->text[0] == '[') {
447 /* the component is itself an array */
448 namebuf = DMNEW(char, namelen + 1);
450 MCOPY(namebuf + 1, component->name->text, char, namelen);
454 /* the component is a non-array class */
455 namebuf = DMNEW(char, namelen + 3);
458 MCOPY(namebuf + 2, component->name->text, char, namelen);
459 namebuf[2 + namelen] = ';';
463 return get_array_class(utf_new(namebuf, namelen),
464 component->classloader,
465 component->classloader,
470 /* class_multiarray_of *********************************************************
472 Returns an array class with the given dimension and element class.
473 The array class is dynamically created if neccessary.
475 *******************************************************************************/
477 classinfo *class_multiarray_of(s4 dim, classinfo *element, bool link)
483 log_text("Invalid array dimension requested");
487 /* Assemble the array class name */
488 namelen = element->name->blength;
490 if (element->name->text[0] == '[') {
491 /* the element is itself an array */
492 namebuf = DMNEW(char, namelen + dim);
493 memcpy(namebuf + dim, element->name->text, namelen);
497 /* the element is a non-array class */
498 namebuf = DMNEW(char, namelen + 2 + dim);
500 memcpy(namebuf + dim + 1, element->name->text, namelen);
501 namelen += (2 + dim);
502 namebuf[namelen - 1] = ';';
504 memset(namebuf, '[', dim);
506 return get_array_class(utf_new(namebuf, namelen),
507 element->classloader,
508 element->classloader,
513 /* class_lookup_classref *******************************************************
515 Looks up the constant_classref for a given classname in the classref
519 cls..............the class containing the reference
520 name.............the name of the class refered to
523 a pointer to a constant_classref, or
524 NULL if the reference was not found
526 *******************************************************************************/
528 constant_classref *class_lookup_classref(classinfo *cls, utf *name)
530 constant_classref *ref;
531 extra_classref *xref;
536 CLASS_ASSERT(!cls->classrefcount || cls->classrefs);
538 /* first search the main classref table */
539 count = cls->classrefcount;
540 ref = cls->classrefs;
541 for (; count; --count, ++ref)
542 if (ref->name == name)
545 /* next try the list of extra classrefs */
546 for (xref = cls->extclassrefs; xref; xref = xref->next) {
547 if (xref->classref.name == name)
548 return &(xref->classref);
556 /* class_get_classref **********************************************************
558 Returns the constant_classref for a given classname.
561 cls..............the class containing the reference
562 name.............the name of the class refered to
565 a pointer to a constant_classref (never NULL)
568 The given name is not checked for validity!
570 *******************************************************************************/
572 constant_classref *class_get_classref(classinfo *cls, utf *name)
574 constant_classref *ref;
575 extra_classref *xref;
580 ref = class_lookup_classref(cls,name);
584 xref = NEW(extra_classref);
585 CLASSREF_INIT(xref->classref,cls,name);
587 xref->next = cls->extclassrefs;
588 cls->extclassrefs = xref;
590 return &(xref->classref);
594 /* class_get_self_classref *****************************************************
596 Returns the constant_classref to the class itself.
599 cls..............the class containing the reference
602 a pointer to a constant_classref (never NULL)
604 *******************************************************************************/
606 constant_classref *class_get_self_classref(classinfo *cls)
608 /* XXX this should be done in a faster way. Maybe always make */
609 /* the classref of index 0 a self reference. */
610 return class_get_classref(cls,cls->name);
613 /* class_get_classref_multiarray_of ********************************************
615 Returns an array type reference with the given dimension and element class
619 dim..............the requested dimension
620 dim must be in [1;255]. This is NOT checked!
621 ref..............the component class reference
624 a pointer to the class reference for the array type
627 The referer of `ref` is used as the referer for the new classref.
629 *******************************************************************************/
631 constant_classref *class_get_classref_multiarray_of(s4 dim, constant_classref *ref)
637 CLASS_ASSERT(dim >= 1 && dim <= 255);
639 /* Assemble the array class name */
640 namelen = ref->name->blength;
642 if (ref->name->text[0] == '[') {
643 /* the element is itself an array */
644 namebuf = DMNEW(char, namelen + dim);
645 memcpy(namebuf + dim, ref->name->text, namelen);
649 /* the element is a non-array class */
650 namebuf = DMNEW(char, namelen + 2 + dim);
652 memcpy(namebuf + dim + 1, ref->name->text, namelen);
653 namelen += (2 + dim);
654 namebuf[namelen - 1] = ';';
656 memset(namebuf, '[', dim);
658 return class_get_classref(ref->referer,utf_new(namebuf, namelen));
662 /* class_get_classref_component_of *********************************************
664 Returns the component classref of a given array type reference
667 ref..............the array type reference
670 a reference to the component class, or
671 NULL if `ref` is not an object array type reference
674 The referer of `ref` is used as the referer for the new classref.
676 *******************************************************************************/
678 constant_classref *class_get_classref_component_of(constant_classref *ref)
685 name = ref->name->text;
689 namelen = ref->name->blength - 1;
694 else if (*name != '[') {
698 return class_get_classref(ref->referer, utf_new(name, namelen));
702 /* class_findmethod ************************************************************
704 Searches a 'classinfo' structure for a method having the given name
705 and descriptor. If descriptor is NULL, it is ignored.
707 *******************************************************************************/
709 methodinfo *class_findmethod(classinfo *c, utf *name, utf *desc)
714 for (i = 0; i < c->methodscount; i++) {
715 m = &(c->methods[i]);
717 if ((m->name == name) && ((desc == NULL) || (m->descriptor == desc)))
725 /************************* Function: class_findmethod_approx ******************
727 like class_findmethod but ignores the return value when comparing the
730 *******************************************************************************/
732 methodinfo *class_findmethod_approx(classinfo *c, utf *name, utf *desc)
736 for (i = 0; i < c->methodscount; i++) {
737 if (c->methods[i].name == name) {
738 utf *meth_descr = c->methods[i].descriptor;
742 return &(c->methods[i]);
744 if (desc->blength <= meth_descr->blength) {
745 /* current position in utf text */
746 char *desc_utf_ptr = desc->text;
747 char *meth_utf_ptr = meth_descr->text;
748 /* points behind utf strings */
749 char *desc_end = UTF_END(desc);
750 char *meth_end = UTF_END(meth_descr);
753 /* compare argument types */
754 while (desc_utf_ptr < desc_end && meth_utf_ptr < meth_end) {
756 if ((ch = *desc_utf_ptr++) != (*meth_utf_ptr++))
757 break; /* no match */
760 return &(c->methods[i]); /* all parameter types equal */
770 /* class_resolvemethod *********************************************************
772 Searches a class and it's super classes for a method.
774 Superinterfaces are *not* searched.
776 *******************************************************************************/
778 methodinfo *class_resolvemethod(classinfo *c, utf *name, utf *desc)
783 m = class_findmethod(c, name, desc);
788 /* JVM Specification bug:
790 It is important NOT to resolve special <init> and <clinit>
791 methods to super classes or interfaces; yet, this is not
792 explicited in the specification. Section 5.4.3.3 should be
793 updated appropriately. */
795 if (name == utf_init || name == utf_clinit)
805 /* class_resolveinterfacemethod_intern *****************************************
807 Internally used helper function. Do not use this directly.
809 *******************************************************************************/
811 static methodinfo *class_resolveinterfacemethod_intern(classinfo *c,
812 utf *name, utf *desc)
817 m = class_findmethod(c, name, desc);
822 /* try the superinterfaces */
824 for (i = 0; i < c->interfacescount; i++) {
825 m = class_resolveinterfacemethod_intern(c->interfaces[i].cls,
836 /* class_resolveclassmethod ****************************************************
838 Resolves a reference from REFERER to a method with NAME and DESC in
841 If the method cannot be resolved the return value is NULL. If
842 EXCEPT is true *exceptionptr is set, too.
844 *******************************************************************************/
846 methodinfo *class_resolveclassmethod(classinfo *c, utf *name, utf *desc,
847 classinfo *referer, bool except)
855 /* XXX resolve class c */
856 /* XXX check access from REFERER to C */
858 /* if (c->flags & ACC_INTERFACE) { */
860 /* *exceptionptr = */
861 /* new_exception(string_java_lang_IncompatibleClassChangeError); */
865 /* try class c and its superclasses */
869 m = class_resolvemethod(cls, name, desc);
874 /* try the superinterfaces */
876 for (i = 0; i < c->interfacescount; i++) {
877 m = class_resolveinterfacemethod_intern(c->interfaces[i].cls,
885 msglen = utf_strlen(c->name) + strlen(".") + utf_strlen(name) +
886 utf_strlen(desc) + strlen("0");
888 msg = MNEW(char, msglen);
890 utf_sprint(msg, c->name);
892 utf_sprint(msg + strlen(msg), name);
893 utf_sprint(msg + strlen(msg), desc);
896 new_exception_message(string_java_lang_NoSuchMethodError, msg);
898 MFREE(msg, char, msglen);
904 if ((m->flags & ACC_ABSTRACT) && !(c->flags & ACC_ABSTRACT)) {
906 *exceptionptr = new_exception(string_java_lang_AbstractMethodError);
911 /* XXX check access rights */
917 /* class_resolveinterfacemethod ************************************************
919 Resolves a reference from REFERER to a method with NAME and DESC in
922 If the method cannot be resolved the return value is NULL. If
923 EXCEPT is true *exceptionptr is set, too.
925 *******************************************************************************/
927 methodinfo *class_resolveinterfacemethod(classinfo *c, utf *name, utf *desc,
928 classinfo *referer, bool except)
932 /* XXX resolve class c */
933 /* XXX check access from REFERER to C */
935 if (!(c->flags & ACC_INTERFACE)) {
938 new_exception(string_java_lang_IncompatibleClassChangeError);
943 mi = class_resolveinterfacemethod_intern(c, name, desc);
948 /* try class java.lang.Object */
950 mi = class_findmethod(class_java_lang_Object, name, desc);
957 new_exception_utfmessage(string_java_lang_NoSuchMethodError, name);
963 /* class_findfield *************************************************************
965 Searches for field with specified name and type in a classinfo
966 structure. If no such field is found NULL is returned.
968 *******************************************************************************/
970 fieldinfo *class_findfield(classinfo *c, utf *name, utf *desc)
974 for (i = 0; i < c->fieldscount; i++)
975 if ((c->fields[i].name == name) && (c->fields[i].descriptor == desc))
976 return &(c->fields[i]);
979 return class_findfield(c->super.cls, name, desc);
985 /* class_findfield_approx ******************************************************
987 Searches in 'classinfo'-structure for a field with the specified
990 *******************************************************************************/
992 fieldinfo *class_findfield_by_name(classinfo *c, utf *name)
996 /* get field index */
998 i = class_findfield_index_by_name(c, name);
1000 /* field was not found, return */
1005 /* return field address */
1007 return &(c->fields[i]);
1011 s4 class_findfield_index_by_name(classinfo *c, utf *name)
1015 for (i = 0; i < c->fieldscount; i++) {
1016 /* compare field names */
1018 if ((c->fields[i].name == name))
1022 /* field was not found, raise exception */
1024 *exceptionptr = new_exception(string_java_lang_NoSuchFieldException);
1030 /****************** Function: class_resolvefield_int ***************************
1032 This is an internally used helper function. Do not use this directly.
1034 Tries to resolve a field having the given name and type.
1035 If the field cannot be resolved, NULL is returned.
1037 *******************************************************************************/
1039 static fieldinfo *class_resolvefield_int(classinfo *c, utf *name, utf *desc)
1044 /* search for field in class c */
1046 for (i = 0; i < c->fieldscount; i++) {
1047 if ((c->fields[i].name == name) && (c->fields[i].descriptor == desc)) {
1048 return &(c->fields[i]);
1052 /* try superinterfaces recursively */
1054 for (i = 0; i < c->interfacescount; i++) {
1055 fi = class_resolvefield_int(c->interfaces[i].cls, name, desc);
1060 /* try superclass */
1063 return class_resolvefield_int(c->super.cls, name, desc);
1071 /********************* Function: class_resolvefield ***************************
1073 Resolves a reference from REFERER to a field with NAME and DESC in class C.
1075 If the field cannot be resolved the return value is NULL. If EXCEPT is
1076 true *exceptionptr is set, too.
1078 *******************************************************************************/
1080 fieldinfo *class_resolvefield(classinfo *c, utf *name, utf *desc,
1081 classinfo *referer, bool except)
1085 /* XXX resolve class c */
1086 /* XXX check access from REFERER to C */
1088 fi = class_resolvefield_int(c, name, desc);
1093 new_exception_utfmessage(string_java_lang_NoSuchFieldError,
1099 /* XXX check access rights */
1105 /* class_issubclass ************************************************************
1107 Checks if sub is a descendant of super.
1109 *******************************************************************************/
1111 bool class_issubclass(classinfo *sub, classinfo *super)
1120 sub = sub->super.cls;
1125 void class_showconstanti(classinfo *c, int ii)
1131 printf ("#%d: ", (int) i);
1133 switch (c->cptags [i]) {
1134 case CONSTANT_Class:
1135 printf("Classreference -> ");
1136 utf_display(((constant_classref*)e)->name);
1139 case CONSTANT_Fieldref:
1140 printf("Fieldref -> "); goto displayFMIi;
1141 case CONSTANT_Methodref:
1142 printf("Methodref -> "); goto displayFMIi;
1143 case CONSTANT_InterfaceMethodref:
1144 printf("InterfaceMethod -> "); goto displayFMIi;
1147 constant_FMIref *fmi = e;
1148 utf_display(fmi->classref->name);
1150 utf_display(fmi->name);
1152 utf_display(fmi->descriptor);
1156 case CONSTANT_String:
1157 printf("String -> ");
1160 case CONSTANT_Integer:
1161 printf("Integer -> %d", (int) (((constant_integer*)e)->value));
1163 case CONSTANT_Float:
1164 printf("Float -> %f", ((constant_float*)e)->value);
1166 case CONSTANT_Double:
1167 printf("Double -> %f", ((constant_double*)e)->value);
1171 u8 v = ((constant_long*)e)->value;
1173 printf("Long -> %ld", (long int) v);
1175 printf("Long -> HI: %ld, LO: %ld\n",
1176 (long int) v.high, (long int) v.low);
1180 case CONSTANT_NameAndType:
1182 constant_nameandtype *cnt = e;
1183 printf("NameAndType: ");
1184 utf_display(cnt->name);
1186 utf_display(cnt->descriptor);
1194 log_text("Invalid type of ConstantPool-Entry");
1202 void class_showconstantpool (classinfo *c)
1207 printf ("---- dump of constant pool ----\n");
1209 for (i=0; i<c->cpcount; i++) {
1210 printf ("#%d: ", (int) i);
1212 e = c -> cpinfos [i];
1215 switch (c -> cptags [i]) {
1216 case CONSTANT_Class:
1217 printf ("Classreference -> ");
1218 utf_display ( ((constant_classref*)e) -> name );
1221 case CONSTANT_Fieldref:
1222 printf ("Fieldref -> "); goto displayFMI;
1223 case CONSTANT_Methodref:
1224 printf ("Methodref -> "); goto displayFMI;
1225 case CONSTANT_InterfaceMethodref:
1226 printf ("InterfaceMethod -> "); goto displayFMI;
1229 constant_FMIref *fmi = e;
1230 utf_display ( fmi->classref->name );
1232 utf_display ( fmi->name);
1234 utf_display ( fmi->descriptor );
1238 case CONSTANT_String:
1239 printf ("String -> ");
1242 case CONSTANT_Integer:
1243 printf ("Integer -> %d", (int) ( ((constant_integer*)e) -> value) );
1245 case CONSTANT_Float:
1246 printf ("Float -> %f", ((constant_float*)e) -> value);
1248 case CONSTANT_Double:
1249 printf ("Double -> %f", ((constant_double*)e) -> value);
1253 u8 v = ((constant_long*)e) -> value;
1255 printf ("Long -> %ld", (long int) v);
1257 printf ("Long -> HI: %ld, LO: %ld\n",
1258 (long int) v.high, (long int) v.low);
1262 case CONSTANT_NameAndType:
1264 constant_nameandtype *cnt = e;
1265 printf ("NameAndType: ");
1266 utf_display (cnt->name);
1268 utf_display (cnt->descriptor);
1272 printf ("Utf8 -> ");
1276 log_text("Invalid type of ConstantPool-Entry");
1287 /********** Function: class_showmethods (debugging only) *************/
1289 void class_showmethods (classinfo *c)
1293 printf ("--------- Fields and Methods ----------------\n");
1294 printf ("Flags: "); printflags (c->flags); printf ("\n");
1296 printf ("This: "); utf_display (c->name); printf ("\n");
1298 printf ("Super: "); utf_display (c->super.cls->name); printf ("\n");
1300 printf ("Index: %d\n", c->index);
1302 printf ("interfaces:\n");
1303 for (i=0; i < c-> interfacescount; i++) {
1305 utf_display (c -> interfaces[i].cls -> name);
1306 printf (" (%d)\n", c->interfaces[i].cls -> index);
1309 printf ("fields:\n");
1310 for (i=0; i < c -> fieldscount; i++) {
1311 field_display (&(c -> fields[i]));
1314 printf ("methods:\n");
1315 for (i=0; i < c -> methodscount; i++) {
1316 methodinfo *m = &(c->methods[i]);
1317 if ( !(m->flags & ACC_STATIC))
1318 printf ("vftblindex: %d ", m->vftblindex);
1320 method_display ( m );
1324 printf ("Virtual function table:\n");
1325 for (i=0; i<c->vftbl->vftbllength; i++) {
1326 printf ("entry: %d, %ld\n", i, (long int) (c->vftbl->table[i]) );
1333 * These are local overrides for various environment variables in Emacs.
1334 * Please do not remove this and leave it at the end of the file, where
1335 * Emacs will automagically detect them.
1336 * ---------------------------------------------------------------------
1339 * indent-tabs-mode: t