1 /* src/vmcore/class.c - class related functions
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
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., 51 Franklin Street, Fifth Floor, Boston, MA
25 $Id: class.c 7464 2007-03-06 00:26:31Z edwin $
41 #include "mm/memory.h"
43 #if defined(ENABLE_THREADS)
44 # include "threads/native/lock.h"
47 #include "toolbox/logging.h"
49 #include "vm/exceptions.h"
50 #include "vm/global.h"
52 #include "vmcore/class.h"
53 #include "vmcore/classcache.h"
54 #include "vmcore/loader.h"
55 #include "vmcore/options.h"
57 #if defined(ENABLE_STATISTICS)
58 # include "vmcore/statistics.h"
61 #include "vmcore/suck.h"
62 #include "vmcore/utf8.h"
65 /* global variables ***********************************************************/
67 list unlinkedclasses; /* this is only used for eager class */
71 /* frequently used classes ****************************************************/
73 /* important system classes */
75 classinfo *class_java_lang_Object;
76 classinfo *class_java_lang_Class;
77 classinfo *class_java_lang_ClassLoader;
78 classinfo *class_java_lang_Cloneable;
79 classinfo *class_java_lang_SecurityManager;
80 classinfo *class_java_lang_String;
81 classinfo *class_java_lang_System;
82 classinfo *class_java_lang_Thread;
83 classinfo *class_java_lang_ThreadGroup;
84 classinfo *class_java_lang_VMSystem;
85 classinfo *class_java_lang_VMThread;
86 classinfo *class_java_io_Serializable;
89 /* system exception classes required in cacao */
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;
98 #if defined(WITH_CLASSPATH_GNU)
99 classinfo *class_java_lang_VMThrowable;
102 classinfo *class_java_lang_Exception;
103 classinfo *class_java_lang_ClassCastException;
104 classinfo *class_java_lang_ClassNotFoundException;
106 #if defined(ENABLE_JAVASE)
107 classinfo *class_java_lang_Void;
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;
119 /* some runtime exception */
121 classinfo *class_java_lang_NullPointerException;
124 /* some classes which may be used more often */
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;
134 classinfo *arrayclass_java_lang_Object;
138 /* pseudo classes for the typechecker */
140 classinfo *pseudo_class_Arraystub;
141 classinfo *pseudo_class_Null;
142 classinfo *pseudo_class_New;
145 /* class_set_packagename *******************************************************
147 Derive the package name from the class name and store it in the struct.
149 *******************************************************************************/
151 void class_set_packagename(classinfo *c)
153 char *p = UTF_END(c->name) - 1;
154 char *start = c->name->text;
156 /* set the package name */
157 /* classes in the unnamed package keep packagename == NULL */
159 if (c->name->text[0] == '[') {
160 /* set packagename of arrays to the element's package */
162 for (; *start == '['; start++);
164 /* skip the 'L' in arrays of references */
168 for (; (p > start) && (*p != '/'); --p);
170 c->packagename = utf_new(start, p - start);
173 for (; (p > start) && (*p != '/'); --p);
175 c->packagename = utf_new(start, p - start);
180 /* class_create_classinfo ******************************************************
182 Create a new classinfo struct. The class name is set to the given utf *,
183 most other fields are initialized to zero.
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.
189 *******************************************************************************/
191 classinfo *class_create_classinfo(utf *classname)
195 #if defined(ENABLE_STATISTICS)
197 size_classinfo += sizeof(classinfo);
200 /* we use a safe name for temporarily unnamed classes */
202 if (classname == NULL)
203 classname = utf_not_named_yet;
207 log_message_utf("Creating class: ", classname);
210 /* GCNEW_UNCOLLECTABLE clears the allocated memory */
212 c = GCNEW_UNCOLLECTABLE(classinfo, 1);
213 /*c=NEW(classinfo);*/
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. */
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;
223 #if defined(ENABLE_JAVASE)
224 /* check if the class is a reference class and flag it */
226 if (classname == utf_java_lang_ref_SoftReference) {
227 c->flags |= ACC_CLASS_SOFT_REFERENCE;
229 else if (classname == utf_java_lang_ref_WeakReference) {
230 c->flags |= ACC_CLASS_WEAK_REFERENCE;
232 else if (classname == utf_java_lang_ref_PhantomReference) {
233 c->flags |= ACC_CLASS_PHANTOM_REFERENCE;
237 if (classname != utf_not_named_yet)
238 class_set_packagename(c);
240 #if defined(ENABLE_THREADS)
241 lock_init_object_lock(&c->object.header);
248 /* class_postset_header_vftbl **************************************************
250 Set the header.vftbl of all classes created before java.lang.Class
251 was linked. This is necessary that Java code can use a class as
254 *******************************************************************************/
256 void class_postset_header_vftbl(void)
260 classcache_name_entry *nmen;
261 classcache_class_entry *clsen;
263 assert(class_java_lang_Class);
265 for (slot = 0; slot < hashtable_classcache.size; slot++) {
266 nmen = (classcache_name_entry *) hashtable_classcache.ptr[slot];
268 for (; nmen; nmen = nmen->hashlink) {
269 /* iterate over all class entries */
271 for (clsen = nmen->classes; clsen; clsen = clsen->next) {
274 /* now set the the vftbl */
276 if (c->object.header.vftbl == NULL)
277 c->object.header.vftbl = class_java_lang_Class->vftbl;
284 /* class_load_attribute_sourcefile *********************************************
286 SourceFile_attribute {
287 u2 attribute_name_index;
292 *******************************************************************************/
294 static bool class_load_attribute_sourcefile(classbuffer *cb)
305 /* check buffer size */
307 if (!suck_check_classbuffer_size(cb, 4 + 2))
310 /* check attribute length */
312 attribute_length = suck_u4(cb);
314 if (attribute_length != 2) {
315 exceptions_throw_classformaterror(c, "Wrong size for VALUE attribute");
319 /* there can be no more than one SourceFile attribute */
321 if (c->sourcefile != NULL) {
322 exceptions_throw_classformaterror(c, "Multiple SourceFile attributes");
328 sourcefile_index = suck_u2(cb);
329 sourcefile = class_getconstant(c, sourcefile_index, CONSTANT_Utf8);
331 if (sourcefile == NULL)
334 /* store sourcefile */
336 c->sourcefile = sourcefile;
342 /* class_load_attribute_enclosingmethod ****************************************
344 EnclosingMethod_attribute {
345 u2 attribute_name_index;
351 *******************************************************************************/
353 #if defined(ENABLE_JAVASE)
354 static bool class_load_attribute_enclosingmethod(classbuffer *cb)
360 classref_or_classinfo cr;
361 constant_nameandtype *cn;
367 /* check buffer size */
369 if (!suck_check_classbuffer_size(cb, 4 + 2 + 2))
372 /* check attribute length */
374 attribute_length = suck_u4(cb);
376 if (attribute_length != 4) {
377 exceptions_throw_classformaterror(c, "Wrong size for VALUE attribute");
381 /* there can be no more than one EnclosingMethod attribute */
383 if (c->enclosingmethod != NULL) {
384 exceptions_throw_classformaterror(c, "Multiple EnclosingMethod attributes");
388 /* get class index */
390 class_index = suck_u2(cb);
391 cr.ref = innerclass_getconstant(c, class_index, CONSTANT_Class);
393 /* get method index */
395 method_index = suck_u2(cb);
396 cn = innerclass_getconstant(c, method_index, CONSTANT_NameAndType);
398 /* store info in classinfo */
400 c->enclosingclass.any = cr.any;
401 c->enclosingmethod = cn;
405 #endif /* defined(ENABLE_JAVASE) */
408 /* class_load_attributes *******************************************************
410 Read attributes from ClassFile.
413 u2 attribute_name_index;
415 u1 info[attribute_length];
418 InnerClasses_attribute {
419 u2 attribute_name_index;
423 *******************************************************************************/
425 bool class_load_attributes(classbuffer *cb)
430 u2 attribute_name_index;
435 /* get attributes count */
437 if (!suck_check_classbuffer_size(cb, 2))
440 attributes_count = suck_u2(cb);
442 for (i = 0; i < attributes_count; i++) {
443 /* get attribute name */
445 if (!suck_check_classbuffer_size(cb, 2))
448 attribute_name_index = suck_u2(cb);
450 class_getconstant(c, attribute_name_index, CONSTANT_Utf8);
452 if (attribute_name == NULL)
455 if (attribute_name == utf_InnerClasses) {
458 if (c->innerclass != NULL) {
459 exceptions_throw_classformaterror(c, "Multiple InnerClasses attributes");
463 if (!suck_check_classbuffer_size(cb, 4 + 2))
466 /* skip attribute length */
469 /* number of records */
470 c->innerclasscount = suck_u2(cb);
472 if (!suck_check_classbuffer_size(cb, (2 + 2 + 2 + 2) * c->innerclasscount))
475 /* allocate memory for innerclass structure */
476 c->innerclass = MNEW(innerclassinfo, c->innerclasscount);
478 for (j = 0; j < c->innerclasscount; j++) {
479 /* The innerclass structure contains a class with an encoded
480 name, its defining scope, its simple name and a bitmask of
481 the access flags. If an inner class is not a member, its
482 outer_class is NULL, if a class is anonymous, its name is
485 innerclassinfo *info = c->innerclass + j;
487 info->inner_class.ref =
488 innerclass_getconstant(c, suck_u2(cb), CONSTANT_Class);
489 info->outer_class.ref =
490 innerclass_getconstant(c, suck_u2(cb), CONSTANT_Class);
492 innerclass_getconstant(c, suck_u2(cb), CONSTANT_Utf8);
493 info->flags = suck_u2(cb);
496 else if (attribute_name == utf_SourceFile) {
499 if (!class_load_attribute_sourcefile(cb))
502 #if defined(ENABLE_JAVASE)
503 else if (attribute_name == utf_EnclosingMethod) {
504 /* EnclosingMethod */
506 if (!class_load_attribute_enclosingmethod(cb))
509 else if (attribute_name == utf_Signature) {
512 if (!loader_load_attribute_signature(cb, &(c->signature)))
515 else if (attribute_name == utf_RuntimeVisibleAnnotations) {
516 /* RuntimeVisibleAnnotations */
518 if (!annotation_load_attribute_runtimevisibleannotations(cb))
523 /* unknown attribute */
525 if (!loader_skip_attribute_body(cb))
534 /* class_freepool **************************************************************
536 Frees all resources used by this classes Constant Pool.
538 *******************************************************************************/
540 static void class_freecpool(classinfo *c)
546 if (c->cptags && c->cpinfos) {
547 for (idx = 0; idx < c->cpcount; idx++) {
548 tag = c->cptags[idx];
549 info = c->cpinfos[idx];
553 case CONSTANT_Fieldref:
554 case CONSTANT_Methodref:
555 case CONSTANT_InterfaceMethodref:
556 FREE(info, constant_FMIref);
558 case CONSTANT_Integer:
559 FREE(info, constant_integer);
562 FREE(info, constant_float);
565 FREE(info, constant_long);
567 case CONSTANT_Double:
568 FREE(info, constant_double);
570 case CONSTANT_NameAndType:
571 FREE(info, constant_nameandtype);
579 MFREE(c->cptags, u1, c->cpcount);
582 MFREE(c->cpinfos, voidptr, c->cpcount);
586 /* class_getconstant ***********************************************************
588 Retrieves the value at position 'pos' of the constantpool of a
589 class. If the type of the value is other than 'ctype', an error is
592 *******************************************************************************/
594 voidptr class_getconstant(classinfo *c, u4 pos, u4 ctype)
596 /* check index and type of constantpool entry */
597 /* (pos == 0 is caught by type comparison) */
599 if ((pos >= c->cpcount) || (c->cptags[pos] != ctype)) {
600 exceptions_throw_classformaterror(c, "Illegal constant pool index");
604 return c->cpinfos[pos];
608 /* innerclass_getconstant ******************************************************
610 Like class_getconstant, but if cptags is ZERO, null is returned.
612 *******************************************************************************/
614 voidptr innerclass_getconstant(classinfo *c, u4 pos, u4 ctype)
616 /* invalid position in constantpool */
618 if (pos >= c->cpcount) {
619 exceptions_throw_classformaterror(c, "Illegal constant pool index");
623 /* constantpool entry of type 0 */
625 if (c->cptags[pos] == 0)
628 /* check type of constantpool entry */
630 if (c->cptags[pos] != ctype) {
631 exceptions_throw_classformaterror(c, "Illegal constant pool index");
635 return c->cpinfos[pos];
639 /* class_free ******************************************************************
641 Frees all resources used by the class.
643 *******************************************************************************/
645 void class_free(classinfo *c)
653 MFREE(c->interfaces, classinfo*, c->interfacescount);
656 for (i = 0; i < c->fieldscount; i++)
657 field_free(&(c->fields[i]));
658 #if defined(ENABLE_CACAO_GC)
659 MFREE(c->fields, fieldinfo, c->fieldscount);
664 for (i = 0; i < c->methodscount; i++)
665 method_free(&(c->methods[i]));
666 MFREE(c->methods, methodinfo, c->methodscount);
669 if ((v = c->vftbl) != NULL) {
671 mem_free(v->arraydesc,sizeof(arraydescriptor));
673 for (i = 0; i < v->interfacetablelength; i++) {
674 MFREE(v->interfacetable[-i], methodptr, v->interfacevftbllength[i]);
676 MFREE(v->interfacevftbllength, s4, v->interfacetablelength);
678 i = sizeof(vftbl_t) + sizeof(methodptr) * (v->vftbllength - 1) +
679 sizeof(methodptr*) * (v->interfacetablelength -
680 (v->interfacetablelength > 0));
681 v = (vftbl_t*) (((methodptr*) v) -
682 (v->interfacetablelength - 1) * (v->interfacetablelength > 1));
687 MFREE(c->innerclass, innerclassinfo, c->innerclasscount);
689 /* if (c->classvftbl)
690 mem_free(c->header.vftbl, sizeof(vftbl) + sizeof(methodptr)*(c->vftbl->vftbllength-1)); */
696 /* get_array_class *************************************************************
698 Returns the array class with the given name for the given
699 classloader, or NULL if an exception occurred.
701 Note: This function does eager loading.
703 *******************************************************************************/
705 static classinfo *get_array_class(utf *name,java_objectheader *initloader,
706 java_objectheader *defloader,bool link)
710 /* lookup this class in the classcache */
711 c = classcache_lookup(initloader,name);
713 c = classcache_lookup_defined(defloader,name);
716 /* we have to create it */
717 c = class_create_classinfo(name);
718 c = load_newly_created_array(c,initloader);
724 assert(c->state & CLASS_LOADED);
725 assert(c->classloader == defloader);
727 if (link && !(c->state & CLASS_LINKED))
731 assert(!link || (c->state & CLASS_LINKED));
737 /* class_array_of **************************************************************
739 Returns an array class with the given component class. The array
740 class is dynamically created if neccessary.
742 *******************************************************************************/
744 classinfo *class_array_of(classinfo *component, bool link)
751 dumpsize = dump_size();
753 /* Assemble the array class name */
754 namelen = component->name->blength;
756 if (component->name->text[0] == '[') {
757 /* the component is itself an array */
758 namebuf = DMNEW(char, namelen + 1);
760 MCOPY(namebuf + 1, component->name->text, char, namelen);
764 /* the component is a non-array class */
765 namebuf = DMNEW(char, namelen + 3);
768 MCOPY(namebuf + 2, component->name->text, char, namelen);
769 namebuf[2 + namelen] = ';';
773 c = get_array_class(utf_new(namebuf, namelen),
774 component->classloader,
775 component->classloader,
778 dump_release(dumpsize);
784 /* class_multiarray_of *********************************************************
786 Returns an array class with the given dimension and element class.
787 The array class is dynamically created if neccessary.
789 *******************************************************************************/
791 classinfo *class_multiarray_of(s4 dim, classinfo *element, bool link)
798 dumpsize = dump_size();
801 log_text("Invalid array dimension requested");
805 /* Assemble the array class name */
806 namelen = element->name->blength;
808 if (element->name->text[0] == '[') {
809 /* the element is itself an array */
810 namebuf = DMNEW(char, namelen + dim);
811 memcpy(namebuf + dim, element->name->text, namelen);
815 /* the element is a non-array class */
816 namebuf = DMNEW(char, namelen + 2 + dim);
818 memcpy(namebuf + dim + 1, element->name->text, namelen);
819 namelen += (2 + dim);
820 namebuf[namelen - 1] = ';';
822 memset(namebuf, '[', dim);
824 c = get_array_class(utf_new(namebuf, namelen),
825 element->classloader,
826 element->classloader,
829 dump_release(dumpsize);
835 /* class_lookup_classref *******************************************************
837 Looks up the constant_classref for a given classname in the classref
841 cls..............the class containing the reference
842 name.............the name of the class refered to
845 a pointer to a constant_classref, or
846 NULL if the reference was not found
848 *******************************************************************************/
850 constant_classref *class_lookup_classref(classinfo *cls, utf *name)
852 constant_classref *ref;
853 extra_classref *xref;
858 assert(!cls->classrefcount || cls->classrefs);
860 /* first search the main classref table */
861 count = cls->classrefcount;
862 ref = cls->classrefs;
863 for (; count; --count, ++ref)
864 if (ref->name == name)
867 /* next try the list of extra classrefs */
868 for (xref = cls->extclassrefs; xref; xref = xref->next) {
869 if (xref->classref.name == name)
870 return &(xref->classref);
878 /* class_get_classref **********************************************************
880 Returns the constant_classref for a given classname.
883 cls..............the class containing the reference
884 name.............the name of the class refered to
887 a pointer to a constant_classref (never NULL)
890 The given name is not checked for validity!
892 *******************************************************************************/
894 constant_classref *class_get_classref(classinfo *cls, utf *name)
896 constant_classref *ref;
897 extra_classref *xref;
902 ref = class_lookup_classref(cls,name);
906 xref = NEW(extra_classref);
907 CLASSREF_INIT(xref->classref,cls,name);
909 xref->next = cls->extclassrefs;
910 cls->extclassrefs = xref;
912 return &(xref->classref);
916 /* class_get_self_classref *****************************************************
918 Returns the constant_classref to the class itself.
921 cls..............the class containing the reference
924 a pointer to a constant_classref (never NULL)
926 *******************************************************************************/
928 constant_classref *class_get_self_classref(classinfo *cls)
930 /* XXX this should be done in a faster way. Maybe always make */
931 /* the classref of index 0 a self reference. */
932 return class_get_classref(cls,cls->name);
935 /* class_get_classref_multiarray_of ********************************************
937 Returns an array type reference with the given dimension and element class
941 dim..............the requested dimension
942 dim must be in [1;255]. This is NOT checked!
943 ref..............the component class reference
946 a pointer to the class reference for the array type
949 The referer of `ref` is used as the referer for the new classref.
951 *******************************************************************************/
953 constant_classref *class_get_classref_multiarray_of(s4 dim, constant_classref *ref)
958 constant_classref *cr;
961 assert(dim >= 1 && dim <= 255);
963 dumpsize = dump_size();
965 /* Assemble the array class name */
966 namelen = ref->name->blength;
968 if (ref->name->text[0] == '[') {
969 /* the element is itself an array */
970 namebuf = DMNEW(char, namelen + dim);
971 memcpy(namebuf + dim, ref->name->text, namelen);
975 /* the element is a non-array class */
976 namebuf = DMNEW(char, namelen + 2 + dim);
978 memcpy(namebuf + dim + 1, ref->name->text, namelen);
979 namelen += (2 + dim);
980 namebuf[namelen - 1] = ';';
982 memset(namebuf, '[', dim);
984 cr = class_get_classref(ref->referer,utf_new(namebuf, namelen));
986 dump_release(dumpsize);
992 /* class_get_classref_component_of *********************************************
994 Returns the component classref of a given array type reference
997 ref..............the array type reference
1000 a reference to the component class, or
1001 NULL if `ref` is not an object array type reference
1004 The referer of `ref` is used as the referer for the new classref.
1006 *******************************************************************************/
1008 constant_classref *class_get_classref_component_of(constant_classref *ref)
1015 name = ref->name->text;
1019 namelen = ref->name->blength - 1;
1024 else if (*name != '[') {
1028 return class_get_classref(ref->referer, utf_new(name, namelen));
1032 /* class_findmethod ************************************************************
1034 Searches a 'classinfo' structure for a method having the given name
1035 and descriptor. If descriptor is NULL, it is ignored.
1037 *******************************************************************************/
1039 methodinfo *class_findmethod(classinfo *c, utf *name, utf *desc)
1044 for (i = 0; i < c->methodscount; i++) {
1045 m = &(c->methods[i]);
1047 if ((m->name == name) && ((desc == NULL) || (m->descriptor == desc)))
1055 /* class_resolvemethod *********************************************************
1057 Searches a class and it's super classes for a method.
1059 Superinterfaces are *not* searched.
1061 *******************************************************************************/
1063 methodinfo *class_resolvemethod(classinfo *c, utf *name, utf *desc)
1068 m = class_findmethod(c, name, desc);
1073 /* JVM Specification bug:
1075 It is important NOT to resolve special <init> and <clinit>
1076 methods to super classes or interfaces; yet, this is not
1077 explicited in the specification. Section 5.4.3.3 should be
1078 updated appropriately. */
1080 if (name == utf_init || name == utf_clinit)
1090 /* class_resolveinterfacemethod_intern *****************************************
1092 Internally used helper function. Do not use this directly.
1094 *******************************************************************************/
1096 static methodinfo *class_resolveinterfacemethod_intern(classinfo *c,
1097 utf *name, utf *desc)
1102 /* try to find the method in the class */
1104 m = class_findmethod(c, name, desc);
1109 /* no method found? try the superinterfaces */
1111 for (i = 0; i < c->interfacescount; i++) {
1112 m = class_resolveinterfacemethod_intern(c->interfaces[i].cls,
1119 /* no method found */
1125 /* class_resolveclassmethod ****************************************************
1127 Resolves a reference from REFERER to a method with NAME and DESC in
1130 If the method cannot be resolved the return value is NULL. If
1131 EXCEPT is true *exceptionptr is set, too.
1133 *******************************************************************************/
1135 methodinfo *class_resolveclassmethod(classinfo *c, utf *name, utf *desc,
1136 classinfo *referer, bool throwexception)
1142 /* if (c->flags & ACC_INTERFACE) { */
1143 /* if (throwexception) */
1144 /* *exceptionptr = */
1145 /* new_exception(string_java_lang_IncompatibleClassChangeError); */
1149 /* try class c and its superclasses */
1153 m = class_resolvemethod(cls, name, desc);
1158 /* try the superinterfaces */
1160 for (i = 0; i < c->interfacescount; i++) {
1161 m = class_resolveinterfacemethod_intern(c->interfaces[i].cls,
1169 exceptions_throw_nosuchmethoderror(c, name, desc);
1174 if ((m->flags & ACC_ABSTRACT) && !(c->flags & ACC_ABSTRACT)) {
1176 exceptions_throw_abstractmethoderror();
1181 /* XXX check access rights */
1187 /* class_resolveinterfacemethod ************************************************
1189 Resolves a reference from REFERER to a method with NAME and DESC in
1192 If the method cannot be resolved the return value is NULL. If
1193 EXCEPT is true *exceptionptr is set, too.
1195 *******************************************************************************/
1197 methodinfo *class_resolveinterfacemethod(classinfo *c, utf *name, utf *desc,
1198 classinfo *referer, bool throwexception)
1202 if (!(c->flags & ACC_INTERFACE)) {
1204 exceptions_throw_incompatibleclasschangeerror(c, "Not an interface");
1209 mi = class_resolveinterfacemethod_intern(c, name, desc);
1214 /* try class java.lang.Object */
1216 mi = class_findmethod(class_java_lang_Object, name, desc);
1222 exceptions_throw_nosuchmethoderror(c, name, desc);
1228 /* class_findfield *************************************************************
1230 Searches for field with specified name and type in a classinfo
1231 structure. If no such field is found NULL is returned.
1233 *******************************************************************************/
1235 fieldinfo *class_findfield(classinfo *c, utf *name, utf *desc)
1239 for (i = 0; i < c->fieldscount; i++)
1240 if ((c->fields[i].name == name) && (c->fields[i].descriptor == desc))
1241 return &(c->fields[i]);
1244 return class_findfield(c->super.cls, name, desc);
1250 /* class_findfield_approx ******************************************************
1252 Searches in 'classinfo'-structure for a field with the specified
1255 *******************************************************************************/
1257 fieldinfo *class_findfield_by_name(classinfo *c, utf *name)
1261 /* get field index */
1263 i = class_findfield_index_by_name(c, name);
1265 /* field was not found, return */
1270 /* return field address */
1272 return &(c->fields[i]);
1276 s4 class_findfield_index_by_name(classinfo *c, utf *name)
1280 for (i = 0; i < c->fieldscount; i++) {
1281 /* compare field names */
1283 if ((c->fields[i].name == name))
1287 /* field was not found, raise exception */
1289 exceptions_throw_nosuchfielderror(c, name);
1295 /****************** Function: class_resolvefield_int ***************************
1297 This is an internally used helper function. Do not use this directly.
1299 Tries to resolve a field having the given name and type.
1300 If the field cannot be resolved, NULL is returned.
1302 *******************************************************************************/
1304 static fieldinfo *class_resolvefield_int(classinfo *c, utf *name, utf *desc)
1309 /* search for field in class c */
1311 for (i = 0; i < c->fieldscount; i++) {
1312 if ((c->fields[i].name == name) && (c->fields[i].descriptor == desc)) {
1313 return &(c->fields[i]);
1317 /* try superinterfaces recursively */
1319 for (i = 0; i < c->interfacescount; i++) {
1320 fi = class_resolvefield_int(c->interfaces[i].cls, name, desc);
1325 /* try superclass */
1328 return class_resolvefield_int(c->super.cls, name, desc);
1336 /********************* Function: class_resolvefield ***************************
1338 Resolves a reference from REFERER to a field with NAME and DESC in class C.
1340 If the field cannot be resolved the return value is NULL. If EXCEPT is
1341 true *exceptionptr is set, too.
1343 *******************************************************************************/
1345 fieldinfo *class_resolvefield(classinfo *c, utf *name, utf *desc,
1346 classinfo *referer, bool throwexception)
1350 fi = class_resolvefield_int(c, name, desc);
1354 exceptions_throw_nosuchfielderror(c, name);
1359 /* XXX check access rights */
1365 /* class_issubclass ************************************************************
1367 Checks if sub is a descendant of super.
1369 *******************************************************************************/
1371 bool class_issubclass(classinfo *sub, classinfo *super)
1380 sub = sub->super.cls;
1385 /* class_printflags ************************************************************
1387 Prints flags of a class.
1389 *******************************************************************************/
1391 #if !defined(NDEBUG)
1392 void class_printflags(classinfo *c)
1399 if (c->flags & ACC_PUBLIC) printf(" PUBLIC");
1400 if (c->flags & ACC_PRIVATE) printf(" PRIVATE");
1401 if (c->flags & ACC_PROTECTED) printf(" PROTECTED");
1402 if (c->flags & ACC_STATIC) printf(" STATIC");
1403 if (c->flags & ACC_FINAL) printf(" FINAL");
1404 if (c->flags & ACC_SYNCHRONIZED) printf(" SYNCHRONIZED");
1405 if (c->flags & ACC_VOLATILE) printf(" VOLATILE");
1406 if (c->flags & ACC_TRANSIENT) printf(" TRANSIENT");
1407 if (c->flags & ACC_NATIVE) printf(" NATIVE");
1408 if (c->flags & ACC_INTERFACE) printf(" INTERFACE");
1409 if (c->flags & ACC_ABSTRACT) printf(" ABSTRACT");
1414 /* class_print *****************************************************************
1416 Prints classname plus flags.
1418 *******************************************************************************/
1420 #if !defined(NDEBUG)
1421 void class_print(classinfo *c)
1428 utf_display_printable_ascii(c->name);
1429 class_printflags(c);
1434 /* class_classref_print ********************************************************
1436 Prints classname plus referer class.
1438 *******************************************************************************/
1440 #if !defined(NDEBUG)
1441 void class_classref_print(constant_classref *cr)
1448 utf_display_printable_ascii(cr->name);
1451 class_print(cr->referer);
1459 /* class_println ***************************************************************
1461 Prints classname plus flags and new line.
1463 *******************************************************************************/
1465 #if !defined(NDEBUG)
1466 void class_println(classinfo *c)
1474 /* class_classref_println ******************************************************
1476 Prints classname plus referer class and new line.
1478 *******************************************************************************/
1480 #if !defined(NDEBUG)
1481 void class_classref_println(constant_classref *cr)
1483 class_classref_print(cr);
1489 /* class_classref_or_classinfo_print *******************************************
1491 Prints classname plus referer class.
1493 *******************************************************************************/
1495 #if !defined(NDEBUG)
1496 void class_classref_or_classinfo_print(classref_or_classinfo c)
1498 if (c.any == NULL) {
1499 printf("(classref_or_classinfo) NULL");
1503 class_classref_print(c.ref);
1510 /* class_classref_or_classinfo_println *****************************************
1512 Prints classname plus referer class and a newline.
1514 *******************************************************************************/
1516 void class_classref_or_classinfo_println(classref_or_classinfo c)
1518 class_classref_or_classinfo_println(c);
1523 /* class_showconstantpool ******************************************************
1525 Dump the constant pool of the given class to stdout.
1527 *******************************************************************************/
1529 #if !defined(NDEBUG)
1530 void class_showconstantpool (classinfo *c)
1535 printf ("---- dump of constant pool ----\n");
1537 for (i=0; i<c->cpcount; i++) {
1538 printf ("#%d: ", (int) i);
1540 e = c -> cpinfos [i];
1543 switch (c -> cptags [i]) {
1544 case CONSTANT_Class:
1545 printf ("Classreference -> ");
1546 utf_display_printable_ascii ( ((constant_classref*)e) -> name );
1548 case CONSTANT_Fieldref:
1549 printf ("Fieldref -> ");
1550 field_fieldref_print((constant_FMIref *) e);
1552 case CONSTANT_Methodref:
1553 printf ("Methodref -> ");
1554 method_methodref_print((constant_FMIref *) e);
1556 case CONSTANT_InterfaceMethodref:
1557 printf ("InterfaceMethod -> ");
1558 method_methodref_print((constant_FMIref *) e);
1560 case CONSTANT_String:
1561 printf ("String -> ");
1562 utf_display_printable_ascii (e);
1564 case CONSTANT_Integer:
1565 printf ("Integer -> %d", (int) ( ((constant_integer*)e) -> value) );
1567 case CONSTANT_Float:
1568 printf ("Float -> %f", ((constant_float*)e) -> value);
1570 case CONSTANT_Double:
1571 printf ("Double -> %f", ((constant_double*)e) -> value);
1575 u8 v = ((constant_long*)e) -> value;
1577 printf ("Long -> %ld", (long int) v);
1579 printf ("Long -> HI: %ld, LO: %ld\n",
1580 (long int) v.high, (long int) v.low);
1584 case CONSTANT_NameAndType:
1586 constant_nameandtype *cnt = e;
1587 printf ("NameAndType: ");
1588 utf_display_printable_ascii (cnt->name);
1590 utf_display_printable_ascii (cnt->descriptor);
1594 printf ("Utf8 -> ");
1595 utf_display_printable_ascii (e);
1598 log_text("Invalid type of ConstantPool-Entry");
1606 #endif /* !defined(NDEBUG) */
1609 /* class_showmethods ***********************************************************
1611 Dump info about the fields and methods of the given class to stdout.
1613 *******************************************************************************/
1615 #if !defined(NDEBUG)
1616 void class_showmethods (classinfo *c)
1620 printf("--------- Fields and Methods ----------------\n");
1622 class_printflags(c);
1626 utf_display_printable_ascii(c->name);
1631 utf_display_printable_ascii(c->super.cls->name);
1635 printf("Index: %d\n", c->index);
1637 printf("Interfaces:\n");
1638 for (i = 0; i < c->interfacescount; i++) {
1640 utf_display_printable_ascii(c->interfaces[i].cls->name);
1641 printf (" (%d)\n", c->interfaces[i].cls->index);
1644 printf("Fields:\n");
1645 for (i = 0; i < c->fieldscount; i++)
1646 field_println(&(c->fields[i]));
1648 printf("Methods:\n");
1649 for (i = 0; i < c->methodscount; i++) {
1650 methodinfo *m = &(c->methods[i]);
1652 if (!(m->flags & ACC_STATIC))
1653 printf("vftblindex: %d ", m->vftblindex);
1658 printf ("Virtual function table:\n");
1659 for (i = 0; i < c->vftbl->vftbllength; i++)
1660 printf ("entry: %d, %ld\n", i, (long int) (c->vftbl->table[i]));
1662 #endif /* !defined(NDEBUG) */
1666 * These are local overrides for various environment variables in Emacs.
1667 * Please do not remove this and leave it at the end of the file, where
1668 * Emacs will automagically detect them.
1669 * ---------------------------------------------------------------------
1672 * indent-tabs-mode: t
1676 * vim:noexpandtab:sw=4:ts=4: