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 7783 2007-04-20 13:28:27Z twisti $
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 "vm/jit/asmpart.h"
54 #include "vmcore/class.h"
55 #include "vmcore/classcache.h"
56 #include "vmcore/loader.h"
57 #include "vmcore/options.h"
59 #if defined(ENABLE_STATISTICS)
60 # include "vmcore/statistics.h"
63 #include "vmcore/suck.h"
64 #include "vmcore/utf8.h"
67 /* global variables ***********************************************************/
69 list_t unlinkedclasses; /* this is only used for eager class */
73 /* frequently used classes ****************************************************/
75 /* important system classes */
77 classinfo *class_java_lang_Object;
78 classinfo *class_java_lang_Class;
79 classinfo *class_java_lang_ClassLoader;
80 classinfo *class_java_lang_Cloneable;
81 classinfo *class_java_lang_SecurityManager;
82 classinfo *class_java_lang_String;
83 classinfo *class_java_lang_System;
84 classinfo *class_java_lang_Thread;
85 classinfo *class_java_lang_ThreadGroup;
86 classinfo *class_java_lang_VMSystem;
87 classinfo *class_java_lang_VMThread;
88 classinfo *class_java_io_Serializable;
91 /* system exception classes required in cacao */
93 classinfo *class_java_lang_Throwable;
94 classinfo *class_java_lang_Error;
95 classinfo *class_java_lang_LinkageError;
96 classinfo *class_java_lang_NoClassDefFoundError;
97 classinfo *class_java_lang_OutOfMemoryError;
98 classinfo *class_java_lang_VirtualMachineError;
100 #if defined(WITH_CLASSPATH_GNU)
101 classinfo *class_java_lang_VMThrowable;
104 classinfo *class_java_lang_Exception;
105 classinfo *class_java_lang_ClassCastException;
106 classinfo *class_java_lang_ClassNotFoundException;
108 #if defined(ENABLE_JAVASE)
109 classinfo *class_java_lang_Void;
111 classinfo *class_java_lang_Boolean;
112 classinfo *class_java_lang_Byte;
113 classinfo *class_java_lang_Character;
114 classinfo *class_java_lang_Short;
115 classinfo *class_java_lang_Integer;
116 classinfo *class_java_lang_Long;
117 classinfo *class_java_lang_Float;
118 classinfo *class_java_lang_Double;
121 /* some runtime exception */
123 classinfo *class_java_lang_NullPointerException;
126 /* some classes which may be used more often */
128 #if defined(ENABLE_JAVASE)
129 classinfo *class_java_lang_StackTraceElement;
130 classinfo *class_java_lang_reflect_Constructor;
131 classinfo *class_java_lang_reflect_Field;
132 classinfo *class_java_lang_reflect_Method;
133 classinfo *class_java_security_PrivilegedAction;
134 classinfo *class_java_util_Vector;
136 classinfo *arrayclass_java_lang_Object;
140 /* pseudo classes for the typechecker */
142 classinfo *pseudo_class_Arraystub;
143 classinfo *pseudo_class_Null;
144 classinfo *pseudo_class_New;
147 /* class_set_packagename *******************************************************
149 Derive the package name from the class name and store it in the struct.
151 *******************************************************************************/
153 void class_set_packagename(classinfo *c)
155 char *p = UTF_END(c->name) - 1;
156 char *start = c->name->text;
158 /* set the package name */
159 /* classes in the unnamed package keep packagename == NULL */
161 if (c->name->text[0] == '[') {
162 /* set packagename of arrays to the element's package */
164 for (; *start == '['; start++);
166 /* skip the 'L' in arrays of references */
170 for (; (p > start) && (*p != '/'); --p);
172 c->packagename = utf_new(start, p - start);
175 for (; (p > start) && (*p != '/'); --p);
177 c->packagename = utf_new(start, p - start);
182 /* class_create_classinfo ******************************************************
184 Create a new classinfo struct. The class name is set to the given utf *,
185 most other fields are initialized to zero.
187 Note: classname may be NULL. In this case a not-yet-named classinfo is
188 created. The name must be filled in later and class_set_packagename
189 must be called after that.
191 *******************************************************************************/
193 classinfo *class_create_classinfo(utf *classname)
197 #if defined(ENABLE_STATISTICS)
199 size_classinfo += sizeof(classinfo);
202 /* we use a safe name for temporarily unnamed classes */
204 if (classname == NULL)
205 classname = utf_not_named_yet;
209 log_message_utf("Creating class: ", classname);
212 /* GCNEW_UNCOLLECTABLE clears the allocated memory */
214 c = GCNEW_UNCOLLECTABLE(classinfo, 1);
215 /*c=NEW(classinfo);*/
218 /* Set the header.vftbl of all loaded classes to the one of
219 java.lang.Class, so Java code can use a class as object. */
221 if (class_java_lang_Class != NULL)
222 if (class_java_lang_Class->vftbl != NULL)
223 c->object.header.vftbl = class_java_lang_Class->vftbl;
225 #if defined(ENABLE_JAVASE)
226 /* check if the class is a reference class and flag it */
228 if (classname == utf_java_lang_ref_SoftReference) {
229 c->flags |= ACC_CLASS_SOFT_REFERENCE;
231 else if (classname == utf_java_lang_ref_WeakReference) {
232 c->flags |= ACC_CLASS_WEAK_REFERENCE;
234 else if (classname == utf_java_lang_ref_PhantomReference) {
235 c->flags |= ACC_CLASS_PHANTOM_REFERENCE;
239 if (classname != utf_not_named_yet)
240 class_set_packagename(c);
242 #if defined(ENABLE_THREADS)
243 lock_init_object_lock(&c->object.header);
250 /* class_postset_header_vftbl **************************************************
252 Set the header.vftbl of all classes created before java.lang.Class
253 was linked. This is necessary that Java code can use a class as
256 *******************************************************************************/
258 void class_postset_header_vftbl(void)
262 classcache_name_entry *nmen;
263 classcache_class_entry *clsen;
265 assert(class_java_lang_Class);
267 for (slot = 0; slot < hashtable_classcache.size; slot++) {
268 nmen = (classcache_name_entry *) hashtable_classcache.ptr[slot];
270 for (; nmen; nmen = nmen->hashlink) {
271 /* iterate over all class entries */
273 for (clsen = nmen->classes; clsen; clsen = clsen->next) {
276 /* now set the the vftbl */
278 if (c->object.header.vftbl == NULL)
279 c->object.header.vftbl = class_java_lang_Class->vftbl;
286 /* class_load_attribute_sourcefile *********************************************
288 SourceFile_attribute {
289 u2 attribute_name_index;
294 *******************************************************************************/
296 static bool class_load_attribute_sourcefile(classbuffer *cb)
307 /* check buffer size */
309 if (!suck_check_classbuffer_size(cb, 4 + 2))
312 /* check attribute length */
314 attribute_length = suck_u4(cb);
316 if (attribute_length != 2) {
317 exceptions_throw_classformaterror(c, "Wrong size for VALUE attribute");
321 /* there can be no more than one SourceFile attribute */
323 if (c->sourcefile != NULL) {
324 exceptions_throw_classformaterror(c, "Multiple SourceFile attributes");
330 sourcefile_index = suck_u2(cb);
331 sourcefile = class_getconstant(c, sourcefile_index, CONSTANT_Utf8);
333 if (sourcefile == NULL)
336 /* store sourcefile */
338 c->sourcefile = sourcefile;
344 /* class_load_attribute_enclosingmethod ****************************************
346 EnclosingMethod_attribute {
347 u2 attribute_name_index;
353 *******************************************************************************/
355 #if defined(ENABLE_JAVASE)
356 static bool class_load_attribute_enclosingmethod(classbuffer *cb)
362 classref_or_classinfo cr;
363 constant_nameandtype *cn;
369 /* check buffer size */
371 if (!suck_check_classbuffer_size(cb, 4 + 2 + 2))
374 /* check attribute length */
376 attribute_length = suck_u4(cb);
378 if (attribute_length != 4) {
379 exceptions_throw_classformaterror(c, "Wrong size for VALUE attribute");
383 /* there can be no more than one EnclosingMethod attribute */
385 if (c->enclosingmethod != NULL) {
386 exceptions_throw_classformaterror(c, "Multiple EnclosingMethod attributes");
390 /* get class index */
392 class_index = suck_u2(cb);
393 cr.ref = innerclass_getconstant(c, class_index, CONSTANT_Class);
395 /* get method index */
397 method_index = suck_u2(cb);
398 cn = innerclass_getconstant(c, method_index, CONSTANT_NameAndType);
400 /* store info in classinfo */
402 c->enclosingclass.any = cr.any;
403 c->enclosingmethod = cn;
407 #endif /* defined(ENABLE_JAVASE) */
410 /* class_load_attributes *******************************************************
412 Read attributes from ClassFile.
415 u2 attribute_name_index;
417 u1 info[attribute_length];
420 InnerClasses_attribute {
421 u2 attribute_name_index;
425 *******************************************************************************/
427 bool class_load_attributes(classbuffer *cb)
432 u2 attribute_name_index;
437 /* get attributes count */
439 if (!suck_check_classbuffer_size(cb, 2))
442 attributes_count = suck_u2(cb);
444 for (i = 0; i < attributes_count; i++) {
445 /* get attribute name */
447 if (!suck_check_classbuffer_size(cb, 2))
450 attribute_name_index = suck_u2(cb);
452 class_getconstant(c, attribute_name_index, CONSTANT_Utf8);
454 if (attribute_name == NULL)
457 if (attribute_name == utf_InnerClasses) {
460 if (c->innerclass != NULL) {
461 exceptions_throw_classformaterror(c, "Multiple InnerClasses attributes");
465 if (!suck_check_classbuffer_size(cb, 4 + 2))
468 /* skip attribute length */
471 /* number of records */
472 c->innerclasscount = suck_u2(cb);
474 if (!suck_check_classbuffer_size(cb, (2 + 2 + 2 + 2) * c->innerclasscount))
477 /* allocate memory for innerclass structure */
478 c->innerclass = MNEW(innerclassinfo, c->innerclasscount);
480 for (j = 0; j < c->innerclasscount; j++) {
481 /* The innerclass structure contains a class with an encoded
482 name, its defining scope, its simple name and a bitmask of
483 the access flags. If an inner class is not a member, its
484 outer_class is NULL, if a class is anonymous, its name is
487 innerclassinfo *info = c->innerclass + j;
489 info->inner_class.ref =
490 innerclass_getconstant(c, suck_u2(cb), CONSTANT_Class);
491 info->outer_class.ref =
492 innerclass_getconstant(c, suck_u2(cb), CONSTANT_Class);
494 innerclass_getconstant(c, suck_u2(cb), CONSTANT_Utf8);
495 info->flags = suck_u2(cb);
498 else if (attribute_name == utf_SourceFile) {
501 if (!class_load_attribute_sourcefile(cb))
504 #if defined(ENABLE_JAVASE)
505 else if (attribute_name == utf_EnclosingMethod) {
506 /* EnclosingMethod */
508 if (!class_load_attribute_enclosingmethod(cb))
511 else if (attribute_name == utf_Signature) {
514 if (!loader_load_attribute_signature(cb, &(c->signature)))
517 else if (attribute_name == utf_RuntimeVisibleAnnotations) {
518 /* RuntimeVisibleAnnotations */
520 if (!annotation_load_attribute_runtimevisibleannotations(cb))
525 /* unknown attribute */
527 if (!loader_skip_attribute_body(cb))
536 /* class_freepool **************************************************************
538 Frees all resources used by this classes Constant Pool.
540 *******************************************************************************/
542 static void class_freecpool(classinfo *c)
548 if (c->cptags && c->cpinfos) {
549 for (idx = 0; idx < c->cpcount; idx++) {
550 tag = c->cptags[idx];
551 info = c->cpinfos[idx];
555 case CONSTANT_Fieldref:
556 case CONSTANT_Methodref:
557 case CONSTANT_InterfaceMethodref:
558 FREE(info, constant_FMIref);
560 case CONSTANT_Integer:
561 FREE(info, constant_integer);
564 FREE(info, constant_float);
567 FREE(info, constant_long);
569 case CONSTANT_Double:
570 FREE(info, constant_double);
572 case CONSTANT_NameAndType:
573 FREE(info, constant_nameandtype);
581 MFREE(c->cptags, u1, c->cpcount);
584 MFREE(c->cpinfos, voidptr, c->cpcount);
588 /* class_getconstant ***********************************************************
590 Retrieves the value at position 'pos' of the constantpool of a
591 class. If the type of the value is other than 'ctype', an error is
594 *******************************************************************************/
596 voidptr class_getconstant(classinfo *c, u4 pos, u4 ctype)
598 /* check index and type of constantpool entry */
599 /* (pos == 0 is caught by type comparison) */
601 if ((pos >= c->cpcount) || (c->cptags[pos] != ctype)) {
602 exceptions_throw_classformaterror(c, "Illegal constant pool index");
606 return c->cpinfos[pos];
610 /* innerclass_getconstant ******************************************************
612 Like class_getconstant, but if cptags is ZERO, null is returned.
614 *******************************************************************************/
616 voidptr innerclass_getconstant(classinfo *c, u4 pos, u4 ctype)
618 /* invalid position in constantpool */
620 if (pos >= c->cpcount) {
621 exceptions_throw_classformaterror(c, "Illegal constant pool index");
625 /* constantpool entry of type 0 */
627 if (c->cptags[pos] == 0)
630 /* check type of constantpool entry */
632 if (c->cptags[pos] != ctype) {
633 exceptions_throw_classformaterror(c, "Illegal constant pool index");
637 return c->cpinfos[pos];
641 /* class_free ******************************************************************
643 Frees all resources used by the class.
645 *******************************************************************************/
647 void class_free(classinfo *c)
655 MFREE(c->interfaces, classinfo*, c->interfacescount);
658 for (i = 0; i < c->fieldscount; i++)
659 field_free(&(c->fields[i]));
660 #if defined(ENABLE_CACAO_GC)
661 MFREE(c->fields, fieldinfo, c->fieldscount);
666 for (i = 0; i < c->methodscount; i++)
667 method_free(&(c->methods[i]));
668 MFREE(c->methods, methodinfo, c->methodscount);
671 if ((v = c->vftbl) != NULL) {
673 mem_free(v->arraydesc,sizeof(arraydescriptor));
675 for (i = 0; i < v->interfacetablelength; i++) {
676 MFREE(v->interfacetable[-i], methodptr, v->interfacevftbllength[i]);
678 MFREE(v->interfacevftbllength, s4, v->interfacetablelength);
680 i = sizeof(vftbl_t) + sizeof(methodptr) * (v->vftbllength - 1) +
681 sizeof(methodptr*) * (v->interfacetablelength -
682 (v->interfacetablelength > 0));
683 v = (vftbl_t*) (((methodptr*) v) -
684 (v->interfacetablelength - 1) * (v->interfacetablelength > 1));
689 MFREE(c->innerclass, innerclassinfo, c->innerclasscount);
691 /* if (c->classvftbl)
692 mem_free(c->header.vftbl, sizeof(vftbl) + sizeof(methodptr)*(c->vftbl->vftbllength-1)); */
698 /* get_array_class *************************************************************
700 Returns the array class with the given name for the given
701 classloader, or NULL if an exception occurred.
703 Note: This function does eager loading.
705 *******************************************************************************/
707 static classinfo *get_array_class(utf *name,java_objectheader *initloader,
708 java_objectheader *defloader,bool link)
712 /* lookup this class in the classcache */
713 c = classcache_lookup(initloader,name);
715 c = classcache_lookup_defined(defloader,name);
718 /* we have to create it */
719 c = class_create_classinfo(name);
720 c = load_newly_created_array(c,initloader);
726 assert(c->state & CLASS_LOADED);
727 assert(c->classloader == defloader);
729 if (link && !(c->state & CLASS_LINKED))
733 assert(!link || (c->state & CLASS_LINKED));
739 /* class_array_of **************************************************************
741 Returns an array class with the given component class. The array
742 class is dynamically created if neccessary.
744 *******************************************************************************/
746 classinfo *class_array_of(classinfo *component, bool link)
753 dumpsize = dump_size();
755 /* Assemble the array class name */
756 namelen = component->name->blength;
758 if (component->name->text[0] == '[') {
759 /* the component is itself an array */
760 namebuf = DMNEW(char, namelen + 1);
762 MCOPY(namebuf + 1, component->name->text, char, namelen);
766 /* the component is a non-array class */
767 namebuf = DMNEW(char, namelen + 3);
770 MCOPY(namebuf + 2, component->name->text, char, namelen);
771 namebuf[2 + namelen] = ';';
775 c = get_array_class(utf_new(namebuf, namelen),
776 component->classloader,
777 component->classloader,
780 dump_release(dumpsize);
786 /* class_multiarray_of *********************************************************
788 Returns an array class with the given dimension and element class.
789 The array class is dynamically created if neccessary.
791 *******************************************************************************/
793 classinfo *class_multiarray_of(s4 dim, classinfo *element, bool link)
800 dumpsize = dump_size();
803 log_text("Invalid array dimension requested");
807 /* Assemble the array class name */
808 namelen = element->name->blength;
810 if (element->name->text[0] == '[') {
811 /* the element is itself an array */
812 namebuf = DMNEW(char, namelen + dim);
813 memcpy(namebuf + dim, element->name->text, namelen);
817 /* the element is a non-array class */
818 namebuf = DMNEW(char, namelen + 2 + dim);
820 memcpy(namebuf + dim + 1, element->name->text, namelen);
821 namelen += (2 + dim);
822 namebuf[namelen - 1] = ';';
824 memset(namebuf, '[', dim);
826 c = get_array_class(utf_new(namebuf, namelen),
827 element->classloader,
828 element->classloader,
831 dump_release(dumpsize);
837 /* class_lookup_classref *******************************************************
839 Looks up the constant_classref for a given classname in the classref
843 cls..............the class containing the reference
844 name.............the name of the class refered to
847 a pointer to a constant_classref, or
848 NULL if the reference was not found
850 *******************************************************************************/
852 constant_classref *class_lookup_classref(classinfo *cls, utf *name)
854 constant_classref *ref;
855 extra_classref *xref;
860 assert(!cls->classrefcount || cls->classrefs);
862 /* first search the main classref table */
863 count = cls->classrefcount;
864 ref = cls->classrefs;
865 for (; count; --count, ++ref)
866 if (ref->name == name)
869 /* next try the list of extra classrefs */
870 for (xref = cls->extclassrefs; xref; xref = xref->next) {
871 if (xref->classref.name == name)
872 return &(xref->classref);
880 /* class_get_classref **********************************************************
882 Returns the constant_classref for a given classname.
885 cls..............the class containing the reference
886 name.............the name of the class refered to
889 a pointer to a constant_classref (never NULL)
892 The given name is not checked for validity!
894 *******************************************************************************/
896 constant_classref *class_get_classref(classinfo *cls, utf *name)
898 constant_classref *ref;
899 extra_classref *xref;
904 ref = class_lookup_classref(cls,name);
908 xref = NEW(extra_classref);
909 CLASSREF_INIT(xref->classref,cls,name);
911 xref->next = cls->extclassrefs;
912 cls->extclassrefs = xref;
914 return &(xref->classref);
918 /* class_get_self_classref *****************************************************
920 Returns the constant_classref to the class itself.
923 cls..............the class containing the reference
926 a pointer to a constant_classref (never NULL)
928 *******************************************************************************/
930 constant_classref *class_get_self_classref(classinfo *cls)
932 /* XXX this should be done in a faster way. Maybe always make */
933 /* the classref of index 0 a self reference. */
934 return class_get_classref(cls,cls->name);
937 /* class_get_classref_multiarray_of ********************************************
939 Returns an array type reference with the given dimension and element class
943 dim..............the requested dimension
944 dim must be in [1;255]. This is NOT checked!
945 ref..............the component class reference
948 a pointer to the class reference for the array type
951 The referer of `ref` is used as the referer for the new classref.
953 *******************************************************************************/
955 constant_classref *class_get_classref_multiarray_of(s4 dim, constant_classref *ref)
960 constant_classref *cr;
963 assert(dim >= 1 && dim <= 255);
965 dumpsize = dump_size();
967 /* Assemble the array class name */
968 namelen = ref->name->blength;
970 if (ref->name->text[0] == '[') {
971 /* the element is itself an array */
972 namebuf = DMNEW(char, namelen + dim);
973 memcpy(namebuf + dim, ref->name->text, namelen);
977 /* the element is a non-array class */
978 namebuf = DMNEW(char, namelen + 2 + dim);
980 memcpy(namebuf + dim + 1, ref->name->text, namelen);
981 namelen += (2 + dim);
982 namebuf[namelen - 1] = ';';
984 memset(namebuf, '[', dim);
986 cr = class_get_classref(ref->referer,utf_new(namebuf, namelen));
988 dump_release(dumpsize);
994 /* class_get_classref_component_of *********************************************
996 Returns the component classref of a given array type reference
999 ref..............the array type reference
1002 a reference to the component class, or
1003 NULL if `ref` is not an object array type reference
1006 The referer of `ref` is used as the referer for the new classref.
1008 *******************************************************************************/
1010 constant_classref *class_get_classref_component_of(constant_classref *ref)
1017 name = ref->name->text;
1021 namelen = ref->name->blength - 1;
1026 else if (*name != '[') {
1030 return class_get_classref(ref->referer, utf_new(name, namelen));
1034 /* class_findmethod ************************************************************
1036 Searches a 'classinfo' structure for a method having the given name
1037 and descriptor. If descriptor is NULL, it is ignored.
1039 *******************************************************************************/
1041 methodinfo *class_findmethod(classinfo *c, utf *name, utf *desc)
1046 for (i = 0; i < c->methodscount; i++) {
1047 m = &(c->methods[i]);
1049 if ((m->name == name) && ((desc == NULL) || (m->descriptor == desc)))
1057 /* class_resolvemethod *********************************************************
1059 Searches a class and it's super classes for a method.
1061 Superinterfaces are *not* searched.
1063 *******************************************************************************/
1065 methodinfo *class_resolvemethod(classinfo *c, utf *name, utf *desc)
1070 m = class_findmethod(c, name, desc);
1075 /* JVM Specification bug:
1077 It is important NOT to resolve special <init> and <clinit>
1078 methods to super classes or interfaces; yet, this is not
1079 explicited in the specification. Section 5.4.3.3 should be
1080 updated appropriately. */
1082 if (name == utf_init || name == utf_clinit)
1092 /* class_resolveinterfacemethod_intern *****************************************
1094 Internally used helper function. Do not use this directly.
1096 *******************************************************************************/
1098 static methodinfo *class_resolveinterfacemethod_intern(classinfo *c,
1099 utf *name, utf *desc)
1104 /* try to find the method in the class */
1106 m = class_findmethod(c, name, desc);
1111 /* no method found? try the superinterfaces */
1113 for (i = 0; i < c->interfacescount; i++) {
1114 m = class_resolveinterfacemethod_intern(c->interfaces[i].cls,
1121 /* no method found */
1127 /* class_resolveclassmethod ****************************************************
1129 Resolves a reference from REFERER to a method with NAME and DESC in
1132 If the method cannot be resolved the return value is NULL. If
1133 EXCEPT is true *exceptionptr is set, too.
1135 *******************************************************************************/
1137 methodinfo *class_resolveclassmethod(classinfo *c, utf *name, utf *desc,
1138 classinfo *referer, bool throwexception)
1144 /* if (c->flags & ACC_INTERFACE) { */
1145 /* if (throwexception) */
1146 /* *exceptionptr = */
1147 /* new_exception(string_java_lang_IncompatibleClassChangeError); */
1151 /* try class c and its superclasses */
1155 m = class_resolvemethod(cls, name, desc);
1160 /* try the superinterfaces */
1162 for (i = 0; i < c->interfacescount; i++) {
1163 m = class_resolveinterfacemethod_intern(c->interfaces[i].cls,
1171 exceptions_throw_nosuchmethoderror(c, name, desc);
1176 if ((m->flags & ACC_ABSTRACT) && !(c->flags & ACC_ABSTRACT)) {
1178 exceptions_throw_abstractmethoderror();
1183 /* XXX check access rights */
1189 /* class_resolveinterfacemethod ************************************************
1191 Resolves a reference from REFERER to a method with NAME and DESC in
1194 If the method cannot be resolved the return value is NULL. If
1195 EXCEPT is true *exceptionptr is set, too.
1197 *******************************************************************************/
1199 methodinfo *class_resolveinterfacemethod(classinfo *c, utf *name, utf *desc,
1200 classinfo *referer, bool throwexception)
1204 if (!(c->flags & ACC_INTERFACE)) {
1206 exceptions_throw_incompatibleclasschangeerror(c, "Not an interface");
1211 mi = class_resolveinterfacemethod_intern(c, name, desc);
1216 /* try class java.lang.Object */
1218 mi = class_findmethod(class_java_lang_Object, name, desc);
1224 exceptions_throw_nosuchmethoderror(c, name, desc);
1230 /* class_findfield *************************************************************
1232 Searches for field with specified name and type in a classinfo
1233 structure. If no such field is found NULL is returned.
1235 *******************************************************************************/
1237 fieldinfo *class_findfield(classinfo *c, utf *name, utf *desc)
1241 for (i = 0; i < c->fieldscount; i++)
1242 if ((c->fields[i].name == name) && (c->fields[i].descriptor == desc))
1243 return &(c->fields[i]);
1246 return class_findfield(c->super.cls, name, desc);
1252 /* class_findfield_approx ******************************************************
1254 Searches in 'classinfo'-structure for a field with the specified
1257 *******************************************************************************/
1259 fieldinfo *class_findfield_by_name(classinfo *c, utf *name)
1263 /* get field index */
1265 i = class_findfield_index_by_name(c, name);
1267 /* field was not found, return */
1272 /* return field address */
1274 return &(c->fields[i]);
1278 s4 class_findfield_index_by_name(classinfo *c, utf *name)
1282 for (i = 0; i < c->fieldscount; i++) {
1283 /* compare field names */
1285 if ((c->fields[i].name == name))
1289 /* field was not found, raise exception */
1291 exceptions_throw_nosuchfielderror(c, name);
1297 /****************** Function: class_resolvefield_int ***************************
1299 This is an internally used helper function. Do not use this directly.
1301 Tries to resolve a field having the given name and type.
1302 If the field cannot be resolved, NULL is returned.
1304 *******************************************************************************/
1306 static fieldinfo *class_resolvefield_int(classinfo *c, utf *name, utf *desc)
1311 /* search for field in class c */
1313 for (i = 0; i < c->fieldscount; i++) {
1314 if ((c->fields[i].name == name) && (c->fields[i].descriptor == desc)) {
1315 return &(c->fields[i]);
1319 /* try superinterfaces recursively */
1321 for (i = 0; i < c->interfacescount; i++) {
1322 fi = class_resolvefield_int(c->interfaces[i].cls, name, desc);
1327 /* try superclass */
1330 return class_resolvefield_int(c->super.cls, name, desc);
1338 /********************* Function: class_resolvefield ***************************
1340 Resolves a reference from REFERER to a field with NAME and DESC in class C.
1342 If the field cannot be resolved the return value is NULL. If EXCEPT is
1343 true *exceptionptr is set, too.
1345 *******************************************************************************/
1347 fieldinfo *class_resolvefield(classinfo *c, utf *name, utf *desc,
1348 classinfo *referer, bool throwexception)
1352 fi = class_resolvefield_int(c, name, desc);
1356 exceptions_throw_nosuchfielderror(c, name);
1361 /* XXX check access rights */
1367 /* class_issubclass ************************************************************
1369 Checks if sub is a descendant of super.
1371 *******************************************************************************/
1373 bool class_issubclass(classinfo *sub, classinfo *super)
1382 sub = sub->super.cls;
1387 /* class_isanysubclass *********************************************************
1389 Checks a subclass relation between two classes. Implemented
1390 interfaces are interpreted as super classes.
1392 Return value: 1 ... sub is subclass of super
1395 *******************************************************************************/
1397 bool class_isanysubclass(classinfo *sub, classinfo *super)
1399 castinfo classvalues;
1403 /* This is the trivial case. */
1408 /* Primitive classes are only subclasses of themselves. */
1410 if ((sub->flags & ACC_CLASS_PRIMITIVE) ||
1411 (super->flags & ACC_CLASS_PRIMITIVE))
1414 /* Check for interfaces. */
1416 if (super->flags & ACC_INTERFACE) {
1417 result = (sub->vftbl->interfacetablelength > super->index) &&
1418 (sub->vftbl->interfacetable[-super->index] != NULL);
1421 /* java.lang.Object is the only super class of any
1424 if (sub->flags & ACC_INTERFACE)
1425 return (super == class_java_lang_Object);
1427 ASM_GETCLASSVALUES_ATOMIC(super->vftbl, sub->vftbl, &classvalues);
1429 diffval = classvalues.sub_baseval - classvalues.super_baseval;
1430 result = diffval <= (u4) classvalues.super_diffval;
1437 /* class_printflags ************************************************************
1439 Prints flags of a class.
1441 *******************************************************************************/
1443 #if !defined(NDEBUG)
1444 void class_printflags(classinfo *c)
1451 if (c->flags & ACC_PUBLIC) printf(" PUBLIC");
1452 if (c->flags & ACC_PRIVATE) printf(" PRIVATE");
1453 if (c->flags & ACC_PROTECTED) printf(" PROTECTED");
1454 if (c->flags & ACC_STATIC) printf(" STATIC");
1455 if (c->flags & ACC_FINAL) printf(" FINAL");
1456 if (c->flags & ACC_SYNCHRONIZED) printf(" SYNCHRONIZED");
1457 if (c->flags & ACC_VOLATILE) printf(" VOLATILE");
1458 if (c->flags & ACC_TRANSIENT) printf(" TRANSIENT");
1459 if (c->flags & ACC_NATIVE) printf(" NATIVE");
1460 if (c->flags & ACC_INTERFACE) printf(" INTERFACE");
1461 if (c->flags & ACC_ABSTRACT) printf(" ABSTRACT");
1466 /* class_print *****************************************************************
1468 Prints classname plus flags.
1470 *******************************************************************************/
1472 #if !defined(NDEBUG)
1473 void class_print(classinfo *c)
1480 utf_display_printable_ascii(c->name);
1481 class_printflags(c);
1486 /* class_classref_print ********************************************************
1488 Prints classname plus referer class.
1490 *******************************************************************************/
1492 #if !defined(NDEBUG)
1493 void class_classref_print(constant_classref *cr)
1500 utf_display_printable_ascii(cr->name);
1503 class_print(cr->referer);
1511 /* class_println ***************************************************************
1513 Prints classname plus flags and new line.
1515 *******************************************************************************/
1517 #if !defined(NDEBUG)
1518 void class_println(classinfo *c)
1526 /* class_classref_println ******************************************************
1528 Prints classname plus referer class and new line.
1530 *******************************************************************************/
1532 #if !defined(NDEBUG)
1533 void class_classref_println(constant_classref *cr)
1535 class_classref_print(cr);
1541 /* class_classref_or_classinfo_print *******************************************
1543 Prints classname plus referer class.
1545 *******************************************************************************/
1547 #if !defined(NDEBUG)
1548 void class_classref_or_classinfo_print(classref_or_classinfo c)
1550 if (c.any == NULL) {
1551 printf("(classref_or_classinfo) NULL");
1555 class_classref_print(c.ref);
1562 /* class_classref_or_classinfo_println *****************************************
1564 Prints classname plus referer class and a newline.
1566 *******************************************************************************/
1568 void class_classref_or_classinfo_println(classref_or_classinfo c)
1570 class_classref_or_classinfo_println(c);
1575 /* class_showconstantpool ******************************************************
1577 Dump the constant pool of the given class to stdout.
1579 *******************************************************************************/
1581 #if !defined(NDEBUG)
1582 void class_showconstantpool (classinfo *c)
1587 printf ("---- dump of constant pool ----\n");
1589 for (i=0; i<c->cpcount; i++) {
1590 printf ("#%d: ", (int) i);
1592 e = c -> cpinfos [i];
1595 switch (c -> cptags [i]) {
1596 case CONSTANT_Class:
1597 printf ("Classreference -> ");
1598 utf_display_printable_ascii ( ((constant_classref*)e) -> name );
1600 case CONSTANT_Fieldref:
1601 printf ("Fieldref -> ");
1602 field_fieldref_print((constant_FMIref *) e);
1604 case CONSTANT_Methodref:
1605 printf ("Methodref -> ");
1606 method_methodref_print((constant_FMIref *) e);
1608 case CONSTANT_InterfaceMethodref:
1609 printf ("InterfaceMethod -> ");
1610 method_methodref_print((constant_FMIref *) e);
1612 case CONSTANT_String:
1613 printf ("String -> ");
1614 utf_display_printable_ascii (e);
1616 case CONSTANT_Integer:
1617 printf ("Integer -> %d", (int) ( ((constant_integer*)e) -> value) );
1619 case CONSTANT_Float:
1620 printf ("Float -> %f", ((constant_float*)e) -> value);
1622 case CONSTANT_Double:
1623 printf ("Double -> %f", ((constant_double*)e) -> value);
1627 u8 v = ((constant_long*)e) -> value;
1629 printf ("Long -> %ld", (long int) v);
1631 printf ("Long -> HI: %ld, LO: %ld\n",
1632 (long int) v.high, (long int) v.low);
1636 case CONSTANT_NameAndType:
1638 constant_nameandtype *cnt = e;
1639 printf ("NameAndType: ");
1640 utf_display_printable_ascii (cnt->name);
1642 utf_display_printable_ascii (cnt->descriptor);
1646 printf ("Utf8 -> ");
1647 utf_display_printable_ascii (e);
1650 log_text("Invalid type of ConstantPool-Entry");
1658 #endif /* !defined(NDEBUG) */
1661 /* class_showmethods ***********************************************************
1663 Dump info about the fields and methods of the given class to stdout.
1665 *******************************************************************************/
1667 #if !defined(NDEBUG)
1668 void class_showmethods (classinfo *c)
1672 printf("--------- Fields and Methods ----------------\n");
1674 class_printflags(c);
1678 utf_display_printable_ascii(c->name);
1683 utf_display_printable_ascii(c->super.cls->name);
1687 printf("Index: %d\n", c->index);
1689 printf("Interfaces:\n");
1690 for (i = 0; i < c->interfacescount; i++) {
1692 utf_display_printable_ascii(c->interfaces[i].cls->name);
1693 printf (" (%d)\n", c->interfaces[i].cls->index);
1696 printf("Fields:\n");
1697 for (i = 0; i < c->fieldscount; i++)
1698 field_println(&(c->fields[i]));
1700 printf("Methods:\n");
1701 for (i = 0; i < c->methodscount; i++) {
1702 methodinfo *m = &(c->methods[i]);
1704 if (!(m->flags & ACC_STATIC))
1705 printf("vftblindex: %d ", m->vftblindex);
1710 printf ("Virtual function table:\n");
1711 for (i = 0; i < c->vftbl->vftbllength; i++)
1712 printf ("entry: %d, %ld\n", i, (long int) (c->vftbl->table[i]));
1714 #endif /* !defined(NDEBUG) */
1718 * These are local overrides for various environment variables in Emacs.
1719 * Please do not remove this and leave it at the end of the file, where
1720 * Emacs will automagically detect them.
1721 * ---------------------------------------------------------------------
1724 * indent-tabs-mode: t
1728 * vim:noexpandtab:sw=4:ts=4: