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 7387 2007-02-21 23:26:24Z twisti $
39 #include "mm/memory.h"
41 #if defined(ENABLE_THREADS)
42 # include "threads/native/lock.h"
45 #include "toolbox/logging.h"
47 #include "vm/exceptions.h"
48 #include "vm/global.h"
50 #include "vmcore/class.h"
51 #include "vmcore/classcache.h"
52 #include "vmcore/loader.h"
53 #include "vmcore/options.h"
54 #include "vmcore/resolve.h"
56 #if defined(ENABLE_STATISTICS)
57 # include "vmcore/statistics.h"
60 #include "vmcore/suck.h"
61 #include "vmcore/utf8.h"
64 /* global variables ***********************************************************/
66 list unlinkedclasses; /* this is only used for eager class */
70 /* frequently used classes ****************************************************/
72 /* important system classes */
74 classinfo *class_java_lang_Object;
75 classinfo *class_java_lang_Class;
76 classinfo *class_java_lang_ClassLoader;
77 classinfo *class_java_lang_Cloneable;
78 classinfo *class_java_lang_SecurityManager;
79 classinfo *class_java_lang_String;
80 classinfo *class_java_lang_System;
81 classinfo *class_java_lang_Thread;
82 classinfo *class_java_lang_ThreadGroup;
83 classinfo *class_java_lang_VMSystem;
84 classinfo *class_java_lang_VMThread;
85 classinfo *class_java_io_Serializable;
88 /* system exception classes required in cacao */
90 classinfo *class_java_lang_Throwable;
91 classinfo *class_java_lang_Error;
92 classinfo *class_java_lang_LinkageError;
93 classinfo *class_java_lang_NoClassDefFoundError;
94 classinfo *class_java_lang_OutOfMemoryError;
95 classinfo *class_java_lang_VirtualMachineError;
97 #if defined(WITH_CLASSPATH_GNU)
98 classinfo *class_java_lang_VMThrowable;
101 classinfo *class_java_lang_Exception;
102 classinfo *class_java_lang_ClassCastException;
103 classinfo *class_java_lang_ClassNotFoundException;
105 #if defined(ENABLE_JAVASE)
106 classinfo *class_java_lang_Void;
108 classinfo *class_java_lang_Boolean;
109 classinfo *class_java_lang_Byte;
110 classinfo *class_java_lang_Character;
111 classinfo *class_java_lang_Short;
112 classinfo *class_java_lang_Integer;
113 classinfo *class_java_lang_Long;
114 classinfo *class_java_lang_Float;
115 classinfo *class_java_lang_Double;
118 /* some runtime exception */
120 classinfo *class_java_lang_NullPointerException;
123 /* some classes which may be used more often */
125 #if defined(ENABLE_JAVASE)
126 classinfo *class_java_lang_StackTraceElement;
127 classinfo *class_java_lang_reflect_Constructor;
128 classinfo *class_java_lang_reflect_Field;
129 classinfo *class_java_lang_reflect_Method;
130 classinfo *class_java_security_PrivilegedAction;
131 classinfo *class_java_util_Vector;
133 classinfo *arrayclass_java_lang_Object;
137 /* pseudo classes for the typechecker */
139 classinfo *pseudo_class_Arraystub;
140 classinfo *pseudo_class_Null;
141 classinfo *pseudo_class_New;
144 /* class_set_packagename *******************************************************
146 Derive the package name from the class name and store it in the struct.
148 *******************************************************************************/
150 void class_set_packagename(classinfo *c)
152 char *p = UTF_END(c->name) - 1;
153 char *start = c->name->text;
155 /* set the package name */
156 /* classes in the unnamed package keep packagename == NULL */
158 if (c->name->text[0] == '[') {
159 /* set packagename of arrays to the element's package */
161 for (; *start == '['; start++);
163 /* skip the 'L' in arrays of references */
167 for (; (p > start) && (*p != '/'); --p);
169 c->packagename = utf_new(start, p - start);
172 for (; (p > start) && (*p != '/'); --p);
174 c->packagename = utf_new(start, p - start);
179 /* class_create_classinfo ******************************************************
181 Create a new classinfo struct. The class name is set to the given utf *,
182 most other fields are initialized to zero.
184 Note: classname may be NULL. In this case a not-yet-named classinfo is
185 created. The name must be filled in later and class_set_packagename
186 must be called after that.
188 *******************************************************************************/
190 classinfo *class_create_classinfo(utf *classname)
194 #if defined(ENABLE_STATISTICS)
196 size_classinfo += sizeof(classinfo);
199 /* we use a safe name for temporarily unnamed classes */
201 if (classname == NULL)
202 classname = utf_not_named_yet;
206 log_message_utf("Creating class: ", classname);
209 /* GCNEW_UNCOLLECTABLE clears the allocated memory */
211 c = GCNEW_UNCOLLECTABLE(classinfo, 1);
212 /*c=NEW(classinfo);*/
215 /* Set the header.vftbl of all loaded classes to the one of
216 java.lang.Class, so Java code can use a class as object. */
218 if (class_java_lang_Class != NULL)
219 if (class_java_lang_Class->vftbl != NULL)
220 c->object.header.vftbl = class_java_lang_Class->vftbl;
222 #if defined(ENABLE_JAVASE)
223 /* check if the class is a reference class and flag it */
225 if (classname == utf_java_lang_ref_SoftReference) {
226 c->flags |= ACC_CLASS_SOFT_REFERENCE;
228 else if (classname == utf_java_lang_ref_WeakReference) {
229 c->flags |= ACC_CLASS_WEAK_REFERENCE;
231 else if (classname == utf_java_lang_ref_PhantomReference) {
232 c->flags |= ACC_CLASS_PHANTOM_REFERENCE;
236 if (classname != utf_not_named_yet)
237 class_set_packagename(c);
239 #if defined(ENABLE_THREADS)
240 lock_init_object_lock(&c->object.header);
247 /* class_postset_header_vftbl **************************************************
249 Set the header.vftbl of all classes created before java.lang.Class
250 was linked. This is necessary that Java code can use a class as
253 *******************************************************************************/
255 void class_postset_header_vftbl(void)
259 classcache_name_entry *nmen;
260 classcache_class_entry *clsen;
262 assert(class_java_lang_Class);
264 for (slot = 0; slot < hashtable_classcache.size; slot++) {
265 nmen = (classcache_name_entry *) hashtable_classcache.ptr[slot];
267 for (; nmen; nmen = nmen->hashlink) {
268 /* iterate over all class entries */
270 for (clsen = nmen->classes; clsen; clsen = clsen->next) {
273 /* now set the the vftbl */
275 if (c->object.header.vftbl == NULL)
276 c->object.header.vftbl = class_java_lang_Class->vftbl;
283 /* class_load_attribute_sourcefile *********************************************
285 SourceFile_attribute {
286 u2 attribute_name_index;
291 *******************************************************************************/
293 static bool class_load_attribute_sourcefile(classbuffer *cb)
304 /* check buffer size */
306 if (!suck_check_classbuffer_size(cb, 4 + 2))
309 /* check attribute length */
311 attribute_length = suck_u4(cb);
313 if (attribute_length != 2) {
314 exceptions_throw_classformaterror(c, "Wrong size for VALUE attribute");
318 /* there can be no more than one SourceFile attribute */
320 if (c->sourcefile != NULL) {
321 exceptions_throw_classformaterror(c, "Multiple SourceFile attributes");
327 sourcefile_index = suck_u2(cb);
328 sourcefile = class_getconstant(c, sourcefile_index, CONSTANT_Utf8);
330 if (sourcefile == NULL)
333 /* store sourcefile */
335 c->sourcefile = sourcefile;
341 /* class_load_attribute_enclosingmethod ****************************************
343 EnclosingMethod_attribute {
344 u2 attribute_name_index;
350 *******************************************************************************/
352 #if defined(ENABLE_JAVASE)
353 static bool class_load_attribute_enclosingmethod(classbuffer *cb)
359 classref_or_classinfo cr;
360 constant_nameandtype *cn;
366 /* check buffer size */
368 if (!suck_check_classbuffer_size(cb, 4 + 2 + 2))
371 /* check attribute length */
373 attribute_length = suck_u4(cb);
375 if (attribute_length != 4) {
376 exceptions_throw_classformaterror(c, "Wrong size for VALUE attribute");
380 /* there can be no more than one EnclosingMethod attribute */
382 if (c->enclosingmethod != NULL) {
383 exceptions_throw_classformaterror(c, "Multiple EnclosingMethod attributes");
387 /* get class index */
389 class_index = suck_u2(cb);
390 cr.ref = innerclass_getconstant(c, class_index, CONSTANT_Class);
392 /* get method index */
394 method_index = suck_u2(cb);
395 cn = innerclass_getconstant(c, method_index, CONSTANT_NameAndType);
397 /* store info in classinfo */
399 c->enclosingclass.any = cr.any;
400 c->enclosingmethod = cn;
404 #endif /* defined(ENABLE_JAVASE) */
407 /* class_load_attributes *******************************************************
409 Read attributes from ClassFile.
412 u2 attribute_name_index;
414 u1 info[attribute_length];
417 InnerClasses_attribute {
418 u2 attribute_name_index;
422 *******************************************************************************/
424 bool class_load_attributes(classbuffer *cb)
429 u2 attribute_name_index;
434 /* get attributes count */
436 if (!suck_check_classbuffer_size(cb, 2))
439 attributes_count = suck_u2(cb);
441 for (i = 0; i < attributes_count; i++) {
442 /* get attribute name */
444 if (!suck_check_classbuffer_size(cb, 2))
447 attribute_name_index = suck_u2(cb);
449 class_getconstant(c, attribute_name_index, CONSTANT_Utf8);
451 if (attribute_name == NULL)
454 if (attribute_name == utf_InnerClasses) {
457 if (c->innerclass != NULL) {
458 exceptions_throw_classformaterror(c, "Multiple InnerClasses attributes");
462 if (!suck_check_classbuffer_size(cb, 4 + 2))
465 /* skip attribute length */
468 /* number of records */
469 c->innerclasscount = suck_u2(cb);
471 if (!suck_check_classbuffer_size(cb, (2 + 2 + 2 + 2) * c->innerclasscount))
474 /* allocate memory for innerclass structure */
475 c->innerclass = MNEW(innerclassinfo, c->innerclasscount);
477 for (j = 0; j < c->innerclasscount; j++) {
478 /* The innerclass structure contains a class with an encoded
479 name, its defining scope, its simple name and a bitmask of
480 the access flags. If an inner class is not a member, its
481 outer_class is NULL, if a class is anonymous, its name is
484 innerclassinfo *info = c->innerclass + j;
486 info->inner_class.ref =
487 innerclass_getconstant(c, suck_u2(cb), CONSTANT_Class);
488 info->outer_class.ref =
489 innerclass_getconstant(c, suck_u2(cb), CONSTANT_Class);
491 innerclass_getconstant(c, suck_u2(cb), CONSTANT_Utf8);
492 info->flags = suck_u2(cb);
495 else if (attribute_name == utf_SourceFile) {
498 if (!class_load_attribute_sourcefile(cb))
501 #if defined(ENABLE_JAVASE)
502 else if (attribute_name == utf_EnclosingMethod) {
503 /* EnclosingMethod */
505 if (!class_load_attribute_enclosingmethod(cb))
508 else if (attribute_name == utf_Signature) {
511 if (!loader_load_attribute_signature(cb, &(c->signature)))
514 else if (attribute_name == utf_RuntimeVisibleAnnotations) {
515 /* RuntimeVisibleAnnotations */
517 if (!annotation_load_attribute_runtimevisibleannotations(cb))
522 /* unknown attribute */
524 if (!loader_skip_attribute_body(cb))
533 /* class_freepool **************************************************************
535 Frees all resources used by this classes Constant Pool.
537 *******************************************************************************/
539 static void class_freecpool(classinfo *c)
545 if (c->cptags && c->cpinfos) {
546 for (idx = 0; idx < c->cpcount; idx++) {
547 tag = c->cptags[idx];
548 info = c->cpinfos[idx];
552 case CONSTANT_Fieldref:
553 case CONSTANT_Methodref:
554 case CONSTANT_InterfaceMethodref:
555 FREE(info, constant_FMIref);
557 case CONSTANT_Integer:
558 FREE(info, constant_integer);
561 FREE(info, constant_float);
564 FREE(info, constant_long);
566 case CONSTANT_Double:
567 FREE(info, constant_double);
569 case CONSTANT_NameAndType:
570 FREE(info, constant_nameandtype);
578 MFREE(c->cptags, u1, c->cpcount);
581 MFREE(c->cpinfos, voidptr, c->cpcount);
585 /* class_getconstant ***********************************************************
587 Retrieves the value at position 'pos' of the constantpool of a
588 class. If the type of the value is other than 'ctype', an error is
591 *******************************************************************************/
593 voidptr class_getconstant(classinfo *c, u4 pos, u4 ctype)
595 /* check index and type of constantpool entry */
596 /* (pos == 0 is caught by type comparison) */
598 if ((pos >= c->cpcount) || (c->cptags[pos] != ctype)) {
599 exceptions_throw_classformaterror(c, "Illegal constant pool index");
603 return c->cpinfos[pos];
607 /* innerclass_getconstant ******************************************************
609 Like class_getconstant, but if cptags is ZERO, null is returned.
611 *******************************************************************************/
613 voidptr innerclass_getconstant(classinfo *c, u4 pos, u4 ctype)
615 /* invalid position in constantpool */
617 if (pos >= c->cpcount) {
618 exceptions_throw_classformaterror(c, "Illegal constant pool index");
622 /* constantpool entry of type 0 */
624 if (c->cptags[pos] == 0)
627 /* check type of constantpool entry */
629 if (c->cptags[pos] != ctype) {
630 exceptions_throw_classformaterror(c, "Illegal constant pool index");
634 return c->cpinfos[pos];
638 /* class_free ******************************************************************
640 Frees all resources used by the class.
642 *******************************************************************************/
644 void class_free(classinfo *c)
652 MFREE(c->interfaces, classinfo*, c->interfacescount);
655 for (i = 0; i < c->fieldscount; i++)
656 field_free(&(c->fields[i]));
657 #if defined(ENABLE_CACAO_GC)
658 MFREE(c->fields, fieldinfo, c->fieldscount);
663 for (i = 0; i < c->methodscount; i++)
664 method_free(&(c->methods[i]));
665 MFREE(c->methods, methodinfo, c->methodscount);
668 if ((v = c->vftbl) != NULL) {
670 mem_free(v->arraydesc,sizeof(arraydescriptor));
672 for (i = 0; i < v->interfacetablelength; i++) {
673 MFREE(v->interfacetable[-i], methodptr, v->interfacevftbllength[i]);
675 MFREE(v->interfacevftbllength, s4, v->interfacetablelength);
677 i = sizeof(vftbl_t) + sizeof(methodptr) * (v->vftbllength - 1) +
678 sizeof(methodptr*) * (v->interfacetablelength -
679 (v->interfacetablelength > 0));
680 v = (vftbl_t*) (((methodptr*) v) -
681 (v->interfacetablelength - 1) * (v->interfacetablelength > 1));
686 MFREE(c->innerclass, innerclassinfo, c->innerclasscount);
688 /* if (c->classvftbl)
689 mem_free(c->header.vftbl, sizeof(vftbl) + sizeof(methodptr)*(c->vftbl->vftbllength-1)); */
695 /* get_array_class *************************************************************
697 Returns the array class with the given name for the given
698 classloader, or NULL if an exception occurred.
700 Note: This function does eager loading.
702 *******************************************************************************/
704 static classinfo *get_array_class(utf *name,java_objectheader *initloader,
705 java_objectheader *defloader,bool link)
709 /* lookup this class in the classcache */
710 c = classcache_lookup(initloader,name);
712 c = classcache_lookup_defined(defloader,name);
715 /* we have to create it */
716 c = class_create_classinfo(name);
717 c = load_newly_created_array(c,initloader);
723 assert(c->state & CLASS_LOADED);
724 assert(c->classloader == defloader);
726 if (link && !(c->state & CLASS_LINKED))
730 assert(!link || (c->state & CLASS_LINKED));
736 /* class_array_of **************************************************************
738 Returns an array class with the given component class. The array
739 class is dynamically created if neccessary.
741 *******************************************************************************/
743 classinfo *class_array_of(classinfo *component, bool link)
750 dumpsize = dump_size();
752 /* Assemble the array class name */
753 namelen = component->name->blength;
755 if (component->name->text[0] == '[') {
756 /* the component is itself an array */
757 namebuf = DMNEW(char, namelen + 1);
759 MCOPY(namebuf + 1, component->name->text, char, namelen);
763 /* the component is a non-array class */
764 namebuf = DMNEW(char, namelen + 3);
767 MCOPY(namebuf + 2, component->name->text, char, namelen);
768 namebuf[2 + namelen] = ';';
772 c = get_array_class(utf_new(namebuf, namelen),
773 component->classloader,
774 component->classloader,
777 dump_release(dumpsize);
783 /* class_multiarray_of *********************************************************
785 Returns an array class with the given dimension and element class.
786 The array class is dynamically created if neccessary.
788 *******************************************************************************/
790 classinfo *class_multiarray_of(s4 dim, classinfo *element, bool link)
797 dumpsize = dump_size();
800 log_text("Invalid array dimension requested");
804 /* Assemble the array class name */
805 namelen = element->name->blength;
807 if (element->name->text[0] == '[') {
808 /* the element is itself an array */
809 namebuf = DMNEW(char, namelen + dim);
810 memcpy(namebuf + dim, element->name->text, namelen);
814 /* the element is a non-array class */
815 namebuf = DMNEW(char, namelen + 2 + dim);
817 memcpy(namebuf + dim + 1, element->name->text, namelen);
818 namelen += (2 + dim);
819 namebuf[namelen - 1] = ';';
821 memset(namebuf, '[', dim);
823 c = get_array_class(utf_new(namebuf, namelen),
824 element->classloader,
825 element->classloader,
828 dump_release(dumpsize);
834 /* class_lookup_classref *******************************************************
836 Looks up the constant_classref for a given classname in the classref
840 cls..............the class containing the reference
841 name.............the name of the class refered to
844 a pointer to a constant_classref, or
845 NULL if the reference was not found
847 *******************************************************************************/
849 constant_classref *class_lookup_classref(classinfo *cls, utf *name)
851 constant_classref *ref;
852 extra_classref *xref;
857 assert(!cls->classrefcount || cls->classrefs);
859 /* first search the main classref table */
860 count = cls->classrefcount;
861 ref = cls->classrefs;
862 for (; count; --count, ++ref)
863 if (ref->name == name)
866 /* next try the list of extra classrefs */
867 for (xref = cls->extclassrefs; xref; xref = xref->next) {
868 if (xref->classref.name == name)
869 return &(xref->classref);
877 /* class_get_classref **********************************************************
879 Returns the constant_classref for a given classname.
882 cls..............the class containing the reference
883 name.............the name of the class refered to
886 a pointer to a constant_classref (never NULL)
889 The given name is not checked for validity!
891 *******************************************************************************/
893 constant_classref *class_get_classref(classinfo *cls, utf *name)
895 constant_classref *ref;
896 extra_classref *xref;
901 ref = class_lookup_classref(cls,name);
905 xref = NEW(extra_classref);
906 CLASSREF_INIT(xref->classref,cls,name);
908 xref->next = cls->extclassrefs;
909 cls->extclassrefs = xref;
911 return &(xref->classref);
915 /* class_get_self_classref *****************************************************
917 Returns the constant_classref to the class itself.
920 cls..............the class containing the reference
923 a pointer to a constant_classref (never NULL)
925 *******************************************************************************/
927 constant_classref *class_get_self_classref(classinfo *cls)
929 /* XXX this should be done in a faster way. Maybe always make */
930 /* the classref of index 0 a self reference. */
931 return class_get_classref(cls,cls->name);
934 /* class_get_classref_multiarray_of ********************************************
936 Returns an array type reference with the given dimension and element class
940 dim..............the requested dimension
941 dim must be in [1;255]. This is NOT checked!
942 ref..............the component class reference
945 a pointer to the class reference for the array type
948 The referer of `ref` is used as the referer for the new classref.
950 *******************************************************************************/
952 constant_classref *class_get_classref_multiarray_of(s4 dim, constant_classref *ref)
957 constant_classref *cr;
960 assert(dim >= 1 && dim <= 255);
962 dumpsize = dump_size();
964 /* Assemble the array class name */
965 namelen = ref->name->blength;
967 if (ref->name->text[0] == '[') {
968 /* the element is itself an array */
969 namebuf = DMNEW(char, namelen + dim);
970 memcpy(namebuf + dim, ref->name->text, namelen);
974 /* the element is a non-array class */
975 namebuf = DMNEW(char, namelen + 2 + dim);
977 memcpy(namebuf + dim + 1, ref->name->text, namelen);
978 namelen += (2 + dim);
979 namebuf[namelen - 1] = ';';
981 memset(namebuf, '[', dim);
983 cr = class_get_classref(ref->referer,utf_new(namebuf, namelen));
985 dump_release(dumpsize);
991 /* class_get_classref_component_of *********************************************
993 Returns the component classref of a given array type reference
996 ref..............the array type reference
999 a reference to the component class, or
1000 NULL if `ref` is not an object array type reference
1003 The referer of `ref` is used as the referer for the new classref.
1005 *******************************************************************************/
1007 constant_classref *class_get_classref_component_of(constant_classref *ref)
1014 name = ref->name->text;
1018 namelen = ref->name->blength - 1;
1023 else if (*name != '[') {
1027 return class_get_classref(ref->referer, utf_new(name, namelen));
1031 /* class_findmethod ************************************************************
1033 Searches a 'classinfo' structure for a method having the given name
1034 and descriptor. If descriptor is NULL, it is ignored.
1036 *******************************************************************************/
1038 methodinfo *class_findmethod(classinfo *c, utf *name, utf *desc)
1043 for (i = 0; i < c->methodscount; i++) {
1044 m = &(c->methods[i]);
1046 if ((m->name == name) && ((desc == NULL) || (m->descriptor == desc)))
1054 /* class_resolvemethod *********************************************************
1056 Searches a class and it's super classes for a method.
1058 Superinterfaces are *not* searched.
1060 *******************************************************************************/
1062 methodinfo *class_resolvemethod(classinfo *c, utf *name, utf *desc)
1067 m = class_findmethod(c, name, desc);
1072 /* JVM Specification bug:
1074 It is important NOT to resolve special <init> and <clinit>
1075 methods to super classes or interfaces; yet, this is not
1076 explicited in the specification. Section 5.4.3.3 should be
1077 updated appropriately. */
1079 if (name == utf_init || name == utf_clinit)
1089 /* class_resolveinterfacemethod_intern *****************************************
1091 Internally used helper function. Do not use this directly.
1093 *******************************************************************************/
1095 static methodinfo *class_resolveinterfacemethod_intern(classinfo *c,
1096 utf *name, utf *desc)
1101 /* try to find the method in the class */
1103 m = class_findmethod(c, name, desc);
1108 /* no method found? try the superinterfaces */
1110 for (i = 0; i < c->interfacescount; i++) {
1111 m = class_resolveinterfacemethod_intern(c->interfaces[i].cls,
1118 /* no method found */
1124 /* class_resolveclassmethod ****************************************************
1126 Resolves a reference from REFERER to a method with NAME and DESC in
1129 If the method cannot be resolved the return value is NULL. If
1130 EXCEPT is true *exceptionptr is set, too.
1132 *******************************************************************************/
1134 methodinfo *class_resolveclassmethod(classinfo *c, utf *name, utf *desc,
1135 classinfo *referer, bool throwexception)
1141 /* if (c->flags & ACC_INTERFACE) { */
1142 /* if (throwexception) */
1143 /* *exceptionptr = */
1144 /* new_exception(string_java_lang_IncompatibleClassChangeError); */
1148 /* try class c and its superclasses */
1152 m = class_resolvemethod(cls, name, desc);
1157 /* try the superinterfaces */
1159 for (i = 0; i < c->interfacescount; i++) {
1160 m = class_resolveinterfacemethod_intern(c->interfaces[i].cls,
1168 exceptions_throw_nosuchmethoderror(c, name, desc);
1173 if ((m->flags & ACC_ABSTRACT) && !(c->flags & ACC_ABSTRACT)) {
1175 exceptions_throw_abstractmethoderror();
1180 /* XXX check access rights */
1186 /* class_resolveinterfacemethod ************************************************
1188 Resolves a reference from REFERER to a method with NAME and DESC in
1191 If the method cannot be resolved the return value is NULL. If
1192 EXCEPT is true *exceptionptr is set, too.
1194 *******************************************************************************/
1196 methodinfo *class_resolveinterfacemethod(classinfo *c, utf *name, utf *desc,
1197 classinfo *referer, bool throwexception)
1201 if (!(c->flags & ACC_INTERFACE)) {
1203 exceptions_throw_incompatibleclasschangeerror(c, "Not an interface");
1208 mi = class_resolveinterfacemethod_intern(c, name, desc);
1213 /* try class java.lang.Object */
1215 mi = class_findmethod(class_java_lang_Object, name, desc);
1221 exceptions_throw_nosuchmethoderror(c, name, desc);
1227 /* class_findfield *************************************************************
1229 Searches for field with specified name and type in a classinfo
1230 structure. If no such field is found NULL is returned.
1232 *******************************************************************************/
1234 fieldinfo *class_findfield(classinfo *c, utf *name, utf *desc)
1238 for (i = 0; i < c->fieldscount; i++)
1239 if ((c->fields[i].name == name) && (c->fields[i].descriptor == desc))
1240 return &(c->fields[i]);
1243 return class_findfield(c->super.cls, name, desc);
1249 /* class_findfield_approx ******************************************************
1251 Searches in 'classinfo'-structure for a field with the specified
1254 *******************************************************************************/
1256 fieldinfo *class_findfield_by_name(classinfo *c, utf *name)
1260 /* get field index */
1262 i = class_findfield_index_by_name(c, name);
1264 /* field was not found, return */
1269 /* return field address */
1271 return &(c->fields[i]);
1275 s4 class_findfield_index_by_name(classinfo *c, utf *name)
1279 for (i = 0; i < c->fieldscount; i++) {
1280 /* compare field names */
1282 if ((c->fields[i].name == name))
1286 /* field was not found, raise exception */
1288 exceptions_throw_nosuchfielderror(c, name);
1294 /****************** Function: class_resolvefield_int ***************************
1296 This is an internally used helper function. Do not use this directly.
1298 Tries to resolve a field having the given name and type.
1299 If the field cannot be resolved, NULL is returned.
1301 *******************************************************************************/
1303 static fieldinfo *class_resolvefield_int(classinfo *c, utf *name, utf *desc)
1308 /* search for field in class c */
1310 for (i = 0; i < c->fieldscount; i++) {
1311 if ((c->fields[i].name == name) && (c->fields[i].descriptor == desc)) {
1312 return &(c->fields[i]);
1316 /* try superinterfaces recursively */
1318 for (i = 0; i < c->interfacescount; i++) {
1319 fi = class_resolvefield_int(c->interfaces[i].cls, name, desc);
1324 /* try superclass */
1327 return class_resolvefield_int(c->super.cls, name, desc);
1335 /********************* Function: class_resolvefield ***************************
1337 Resolves a reference from REFERER to a field with NAME and DESC in class C.
1339 If the field cannot be resolved the return value is NULL. If EXCEPT is
1340 true *exceptionptr is set, too.
1342 *******************************************************************************/
1344 fieldinfo *class_resolvefield(classinfo *c, utf *name, utf *desc,
1345 classinfo *referer, bool throwexception)
1349 fi = class_resolvefield_int(c, name, desc);
1353 exceptions_throw_nosuchfielderror(c, name);
1358 /* XXX check access rights */
1364 /* class_issubclass ************************************************************
1366 Checks if sub is a descendant of super.
1368 *******************************************************************************/
1370 bool class_issubclass(classinfo *sub, classinfo *super)
1379 sub = sub->super.cls;
1384 /* class_printflags ************************************************************
1386 Prints flags of a class.
1388 *******************************************************************************/
1390 #if !defined(NDEBUG)
1391 void class_printflags(classinfo *c)
1398 if (c->flags & ACC_PUBLIC) printf(" PUBLIC");
1399 if (c->flags & ACC_PRIVATE) printf(" PRIVATE");
1400 if (c->flags & ACC_PROTECTED) printf(" PROTECTED");
1401 if (c->flags & ACC_STATIC) printf(" STATIC");
1402 if (c->flags & ACC_FINAL) printf(" FINAL");
1403 if (c->flags & ACC_SYNCHRONIZED) printf(" SYNCHRONIZED");
1404 if (c->flags & ACC_VOLATILE) printf(" VOLATILE");
1405 if (c->flags & ACC_TRANSIENT) printf(" TRANSIENT");
1406 if (c->flags & ACC_NATIVE) printf(" NATIVE");
1407 if (c->flags & ACC_INTERFACE) printf(" INTERFACE");
1408 if (c->flags & ACC_ABSTRACT) printf(" ABSTRACT");
1413 /* class_print *****************************************************************
1415 Prints classname plus flags.
1417 *******************************************************************************/
1419 #if !defined(NDEBUG)
1420 void class_print(classinfo *c)
1427 utf_display_printable_ascii(c->name);
1428 class_printflags(c);
1433 /* class_classref_print ********************************************************
1435 Prints classname plus referer class.
1437 *******************************************************************************/
1439 #if !defined(NDEBUG)
1440 void class_classref_print(constant_classref *cr)
1447 utf_display_printable_ascii(cr->name);
1450 class_print(cr->referer);
1458 /* class_println ***************************************************************
1460 Prints classname plus flags and new line.
1462 *******************************************************************************/
1464 #if !defined(NDEBUG)
1465 void class_println(classinfo *c)
1473 /* class_classref_println ******************************************************
1475 Prints classname plus referer class and new line.
1477 *******************************************************************************/
1479 #if !defined(NDEBUG)
1480 void class_classref_println(constant_classref *cr)
1482 class_classref_print(cr);
1488 /* class_classref_or_classinfo_print *******************************************
1490 Prints classname plus referer class.
1492 *******************************************************************************/
1494 #if !defined(NDEBUG)
1495 void class_classref_or_classinfo_print(classref_or_classinfo c)
1497 if (c.any == NULL) {
1498 printf("(classref_or_classinfo) NULL");
1502 class_classref_print(c.ref);
1509 /* class_classref_or_classinfo_println *****************************************
1511 Prints classname plus referer class and a newline.
1513 *******************************************************************************/
1515 void class_classref_or_classinfo_println(classref_or_classinfo c)
1517 class_classref_or_classinfo_println(c);
1522 /* class_showconstantpool ******************************************************
1524 Dump the constant pool of the given class to stdout.
1526 *******************************************************************************/
1528 #if !defined(NDEBUG)
1529 void class_showconstantpool (classinfo *c)
1534 printf ("---- dump of constant pool ----\n");
1536 for (i=0; i<c->cpcount; i++) {
1537 printf ("#%d: ", (int) i);
1539 e = c -> cpinfos [i];
1542 switch (c -> cptags [i]) {
1543 case CONSTANT_Class:
1544 printf ("Classreference -> ");
1545 utf_display_printable_ascii ( ((constant_classref*)e) -> name );
1547 case CONSTANT_Fieldref:
1548 printf ("Fieldref -> ");
1549 field_fieldref_print((constant_FMIref *) e);
1551 case CONSTANT_Methodref:
1552 printf ("Methodref -> ");
1553 method_methodref_print((constant_FMIref *) e);
1555 case CONSTANT_InterfaceMethodref:
1556 printf ("InterfaceMethod -> ");
1557 method_methodref_print((constant_FMIref *) e);
1559 case CONSTANT_String:
1560 printf ("String -> ");
1561 utf_display_printable_ascii (e);
1563 case CONSTANT_Integer:
1564 printf ("Integer -> %d", (int) ( ((constant_integer*)e) -> value) );
1566 case CONSTANT_Float:
1567 printf ("Float -> %f", ((constant_float*)e) -> value);
1569 case CONSTANT_Double:
1570 printf ("Double -> %f", ((constant_double*)e) -> value);
1574 u8 v = ((constant_long*)e) -> value;
1576 printf ("Long -> %ld", (long int) v);
1578 printf ("Long -> HI: %ld, LO: %ld\n",
1579 (long int) v.high, (long int) v.low);
1583 case CONSTANT_NameAndType:
1585 constant_nameandtype *cnt = e;
1586 printf ("NameAndType: ");
1587 utf_display_printable_ascii (cnt->name);
1589 utf_display_printable_ascii (cnt->descriptor);
1593 printf ("Utf8 -> ");
1594 utf_display_printable_ascii (e);
1597 log_text("Invalid type of ConstantPool-Entry");
1605 #endif /* !defined(NDEBUG) */
1608 /* class_showmethods ***********************************************************
1610 Dump info about the fields and methods of the given class to stdout.
1612 *******************************************************************************/
1614 #if !defined(NDEBUG)
1615 void class_showmethods (classinfo *c)
1619 printf("--------- Fields and Methods ----------------\n");
1621 class_printflags(c);
1625 utf_display_printable_ascii(c->name);
1630 utf_display_printable_ascii(c->super.cls->name);
1634 printf("Index: %d\n", c->index);
1636 printf("Interfaces:\n");
1637 for (i = 0; i < c->interfacescount; i++) {
1639 utf_display_printable_ascii(c->interfaces[i].cls->name);
1640 printf (" (%d)\n", c->interfaces[i].cls->index);
1643 printf("Fields:\n");
1644 for (i = 0; i < c->fieldscount; i++)
1645 field_println(&(c->fields[i]));
1647 printf("Methods:\n");
1648 for (i = 0; i < c->methodscount; i++) {
1649 methodinfo *m = &(c->methods[i]);
1651 if (!(m->flags & ACC_STATIC))
1652 printf("vftblindex: %d ", m->vftblindex);
1657 printf ("Virtual function table:\n");
1658 for (i = 0; i < c->vftbl->vftbllength; i++)
1659 printf ("entry: %d, %ld\n", i, (long int) (c->vftbl->table[i]));
1661 #endif /* !defined(NDEBUG) */
1665 * These are local overrides for various environment variables in Emacs.
1666 * Please do not remove this and leave it at the end of the file, where
1667 * Emacs will automagically detect them.
1668 * ---------------------------------------------------------------------
1671 * indent-tabs-mode: t
1675 * vim:noexpandtab:sw=4:ts=4: