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 8060 2007-06-10 20:00:40Z twisti $
41 #include "mm/memory.h"
43 #include "threads/lock-common.h"
45 #include "toolbox/logging.h"
47 #include "vm/exceptions.h"
48 #include "vm/global.h"
50 #include "vm/jit/asmpart.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_t 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 LOCK_INIT_OBJECT_LOCK(&c->object.header);
246 /* class_postset_header_vftbl **************************************************
248 Set the header.vftbl of all classes created before java.lang.Class
249 was linked. This is necessary that Java code can use a class as
252 *******************************************************************************/
254 void class_postset_header_vftbl(void)
258 classcache_name_entry *nmen;
259 classcache_class_entry *clsen;
261 assert(class_java_lang_Class);
263 for (slot = 0; slot < hashtable_classcache.size; slot++) {
264 nmen = (classcache_name_entry *) hashtable_classcache.ptr[slot];
266 for (; nmen; nmen = nmen->hashlink) {
267 /* iterate over all class entries */
269 for (clsen = nmen->classes; clsen; clsen = clsen->next) {
272 /* now set the the vftbl */
274 if (c->object.header.vftbl == NULL)
275 c->object.header.vftbl = class_java_lang_Class->vftbl;
281 /* class_define ****************************************************************
283 Calls the loader and defines a class in the VM.
285 *******************************************************************************/
287 classinfo *class_define(utf *name, java_objectheader *cl, s4 length, u1 *data)
294 /* check if this class has already been defined */
296 c = classcache_lookup_defined_or_initiated(cl, name);
299 exceptions_throw_linkageerror("duplicate class definition: ", c);
304 /* create a new classinfo struct */
306 c = class_create_classinfo(name);
308 #if defined(ENABLE_STATISTICS)
311 if (opt_getloadingtime)
315 /* build a classbuffer with the given data */
317 cb = NEW(classbuffer);
324 /* preset the defining classloader */
328 /* load the class from this buffer */
330 r = load_class_from_classbuffer(cb);
334 FREE(cb, classbuffer);
336 #if defined(ENABLE_STATISTICS)
339 if (opt_getloadingtime)
344 /* If return value is NULL, we had a problem and the class is
345 not loaded. Now free the allocated memory, otherwise we
346 could run into a DOS. */
353 /* Store the newly defined class in the class cache. This call
354 also checks whether a class of the same name has already been
355 defined by the same defining loader, and if so, replaces the
356 newly created class by the one defined earlier. */
358 /* Important: The classinfo given to classcache_store must be
359 fully prepared because another thread may return
360 this pointer after the lookup at to top of this
361 function directly after the class cache lock has
364 c = classcache_store(cl, c, true);
370 /* class_load_attribute_sourcefile *********************************************
372 SourceFile_attribute {
373 u2 attribute_name_index;
378 *******************************************************************************/
380 static bool class_load_attribute_sourcefile(classbuffer *cb)
391 /* check buffer size */
393 if (!suck_check_classbuffer_size(cb, 4 + 2))
396 /* check attribute length */
398 attribute_length = suck_u4(cb);
400 if (attribute_length != 2) {
401 exceptions_throw_classformaterror(c, "Wrong size for VALUE attribute");
405 /* there can be no more than one SourceFile attribute */
407 if (c->sourcefile != NULL) {
408 exceptions_throw_classformaterror(c, "Multiple SourceFile attributes");
414 sourcefile_index = suck_u2(cb);
415 sourcefile = class_getconstant(c, sourcefile_index, CONSTANT_Utf8);
417 if (sourcefile == NULL)
420 /* store sourcefile */
422 c->sourcefile = sourcefile;
428 /* class_load_attribute_enclosingmethod ****************************************
430 EnclosingMethod_attribute {
431 u2 attribute_name_index;
437 *******************************************************************************/
439 #if defined(ENABLE_JAVASE)
440 static bool class_load_attribute_enclosingmethod(classbuffer *cb)
446 classref_or_classinfo cr;
447 constant_nameandtype *cn;
453 /* check buffer size */
455 if (!suck_check_classbuffer_size(cb, 4 + 2 + 2))
458 /* check attribute length */
460 attribute_length = suck_u4(cb);
462 if (attribute_length != 4) {
463 exceptions_throw_classformaterror(c, "Wrong size for VALUE attribute");
467 /* there can be no more than one EnclosingMethod attribute */
469 if (c->enclosingmethod != NULL) {
470 exceptions_throw_classformaterror(c, "Multiple EnclosingMethod attributes");
474 /* get class index */
476 class_index = suck_u2(cb);
477 cr.ref = innerclass_getconstant(c, class_index, CONSTANT_Class);
479 /* get method index */
481 method_index = suck_u2(cb);
482 cn = innerclass_getconstant(c, method_index, CONSTANT_NameAndType);
484 /* store info in classinfo */
486 c->enclosingclass.any = cr.any;
487 c->enclosingmethod = cn;
491 #endif /* defined(ENABLE_JAVASE) */
494 /* class_load_attributes *******************************************************
496 Read attributes from ClassFile.
499 u2 attribute_name_index;
501 u1 info[attribute_length];
504 InnerClasses_attribute {
505 u2 attribute_name_index;
509 *******************************************************************************/
511 bool class_load_attributes(classbuffer *cb)
516 u2 attribute_name_index;
521 /* get attributes count */
523 if (!suck_check_classbuffer_size(cb, 2))
526 attributes_count = suck_u2(cb);
528 for (i = 0; i < attributes_count; i++) {
529 /* get attribute name */
531 if (!suck_check_classbuffer_size(cb, 2))
534 attribute_name_index = suck_u2(cb);
536 class_getconstant(c, attribute_name_index, CONSTANT_Utf8);
538 if (attribute_name == NULL)
541 if (attribute_name == utf_InnerClasses) {
544 if (c->innerclass != NULL) {
545 exceptions_throw_classformaterror(c, "Multiple InnerClasses attributes");
549 if (!suck_check_classbuffer_size(cb, 4 + 2))
552 /* skip attribute length */
555 /* number of records */
556 c->innerclasscount = suck_u2(cb);
558 if (!suck_check_classbuffer_size(cb, (2 + 2 + 2 + 2) * c->innerclasscount))
561 /* allocate memory for innerclass structure */
562 c->innerclass = MNEW(innerclassinfo, c->innerclasscount);
564 for (j = 0; j < c->innerclasscount; j++) {
565 /* The innerclass structure contains a class with an encoded
566 name, its defining scope, its simple name and a bitmask of
567 the access flags. If an inner class is not a member, its
568 outer_class is NULL, if a class is anonymous, its name is
571 innerclassinfo *info = c->innerclass + j;
573 info->inner_class.ref =
574 innerclass_getconstant(c, suck_u2(cb), CONSTANT_Class);
575 info->outer_class.ref =
576 innerclass_getconstant(c, suck_u2(cb), CONSTANT_Class);
578 innerclass_getconstant(c, suck_u2(cb), CONSTANT_Utf8);
579 info->flags = suck_u2(cb);
582 else if (attribute_name == utf_SourceFile) {
585 if (!class_load_attribute_sourcefile(cb))
588 #if defined(ENABLE_JAVASE)
589 else if (attribute_name == utf_EnclosingMethod) {
590 /* EnclosingMethod */
592 if (!class_load_attribute_enclosingmethod(cb))
595 else if (attribute_name == utf_Signature) {
598 if (!loader_load_attribute_signature(cb, &(c->signature)))
602 /* XXX We can't do a release with that enabled */
604 else if (attribute_name == utf_RuntimeVisibleAnnotations) {
605 /* RuntimeVisibleAnnotations */
607 if (!annotation_load_attribute_runtimevisibleannotations(cb))
613 /* unknown attribute */
615 if (!loader_skip_attribute_body(cb))
624 /* class_freepool **************************************************************
626 Frees all resources used by this classes Constant Pool.
628 *******************************************************************************/
630 static void class_freecpool(classinfo *c)
636 if (c->cptags && c->cpinfos) {
637 for (idx = 0; idx < c->cpcount; idx++) {
638 tag = c->cptags[idx];
639 info = c->cpinfos[idx];
643 case CONSTANT_Fieldref:
644 case CONSTANT_Methodref:
645 case CONSTANT_InterfaceMethodref:
646 FREE(info, constant_FMIref);
648 case CONSTANT_Integer:
649 FREE(info, constant_integer);
652 FREE(info, constant_float);
655 FREE(info, constant_long);
657 case CONSTANT_Double:
658 FREE(info, constant_double);
660 case CONSTANT_NameAndType:
661 FREE(info, constant_nameandtype);
669 MFREE(c->cptags, u1, c->cpcount);
672 MFREE(c->cpinfos, voidptr, c->cpcount);
676 /* class_getconstant ***********************************************************
678 Retrieves the value at position 'pos' of the constantpool of a
679 class. If the type of the value is other than 'ctype', an error is
682 *******************************************************************************/
684 voidptr class_getconstant(classinfo *c, u4 pos, u4 ctype)
686 /* check index and type of constantpool entry */
687 /* (pos == 0 is caught by type comparison) */
689 if ((pos >= c->cpcount) || (c->cptags[pos] != ctype)) {
690 exceptions_throw_classformaterror(c, "Illegal constant pool index");
694 return c->cpinfos[pos];
698 /* innerclass_getconstant ******************************************************
700 Like class_getconstant, but if cptags is ZERO, null is returned.
702 *******************************************************************************/
704 voidptr innerclass_getconstant(classinfo *c, u4 pos, u4 ctype)
706 /* invalid position in constantpool */
708 if (pos >= c->cpcount) {
709 exceptions_throw_classformaterror(c, "Illegal constant pool index");
713 /* constantpool entry of type 0 */
715 if (c->cptags[pos] == 0)
718 /* check type of constantpool entry */
720 if (c->cptags[pos] != ctype) {
721 exceptions_throw_classformaterror(c, "Illegal constant pool index");
725 return c->cpinfos[pos];
729 /* class_free ******************************************************************
731 Frees all resources used by the class.
733 *******************************************************************************/
735 void class_free(classinfo *c)
743 MFREE(c->interfaces, classinfo*, c->interfacescount);
746 for (i = 0; i < c->fieldscount; i++)
747 field_free(&(c->fields[i]));
748 #if defined(ENABLE_CACAO_GC)
749 MFREE(c->fields, fieldinfo, c->fieldscount);
754 for (i = 0; i < c->methodscount; i++)
755 method_free(&(c->methods[i]));
756 MFREE(c->methods, methodinfo, c->methodscount);
759 if ((v = c->vftbl) != NULL) {
761 mem_free(v->arraydesc,sizeof(arraydescriptor));
763 for (i = 0; i < v->interfacetablelength; i++) {
764 MFREE(v->interfacetable[-i], methodptr, v->interfacevftbllength[i]);
766 MFREE(v->interfacevftbllength, s4, v->interfacetablelength);
768 i = sizeof(vftbl_t) + sizeof(methodptr) * (v->vftbllength - 1) +
769 sizeof(methodptr*) * (v->interfacetablelength -
770 (v->interfacetablelength > 0));
771 v = (vftbl_t*) (((methodptr*) v) -
772 (v->interfacetablelength - 1) * (v->interfacetablelength > 1));
777 MFREE(c->innerclass, innerclassinfo, c->innerclasscount);
779 /* if (c->classvftbl)
780 mem_free(c->header.vftbl, sizeof(vftbl) + sizeof(methodptr)*(c->vftbl->vftbllength-1)); */
786 /* get_array_class *************************************************************
788 Returns the array class with the given name for the given
789 classloader, or NULL if an exception occurred.
791 Note: This function does eager loading.
793 *******************************************************************************/
795 static classinfo *get_array_class(utf *name,java_objectheader *initloader,
796 java_objectheader *defloader,bool link)
800 /* lookup this class in the classcache */
801 c = classcache_lookup(initloader,name);
803 c = classcache_lookup_defined(defloader,name);
806 /* we have to create it */
807 c = class_create_classinfo(name);
808 c = load_newly_created_array(c,initloader);
814 assert(c->state & CLASS_LOADED);
815 assert(c->classloader == defloader);
817 if (link && !(c->state & CLASS_LINKED))
821 assert(!link || (c->state & CLASS_LINKED));
827 /* class_array_of **************************************************************
829 Returns an array class with the given component class. The array
830 class is dynamically created if neccessary.
832 *******************************************************************************/
834 classinfo *class_array_of(classinfo *component, bool link)
841 dumpsize = dump_size();
843 /* Assemble the array class name */
844 namelen = component->name->blength;
846 if (component->name->text[0] == '[') {
847 /* the component is itself an array */
848 namebuf = DMNEW(char, namelen + 1);
850 MCOPY(namebuf + 1, component->name->text, char, namelen);
854 /* the component is a non-array class */
855 namebuf = DMNEW(char, namelen + 3);
858 MCOPY(namebuf + 2, component->name->text, char, namelen);
859 namebuf[2 + namelen] = ';';
863 c = get_array_class(utf_new(namebuf, namelen),
864 component->classloader,
865 component->classloader,
868 dump_release(dumpsize);
874 /* class_multiarray_of *********************************************************
876 Returns an array class with the given dimension and element class.
877 The array class is dynamically created if neccessary.
879 *******************************************************************************/
881 classinfo *class_multiarray_of(s4 dim, classinfo *element, bool link)
888 dumpsize = dump_size();
891 log_text("Invalid array dimension requested");
895 /* Assemble the array class name */
896 namelen = element->name->blength;
898 if (element->name->text[0] == '[') {
899 /* the element is itself an array */
900 namebuf = DMNEW(char, namelen + dim);
901 memcpy(namebuf + dim, element->name->text, namelen);
905 /* the element is a non-array class */
906 namebuf = DMNEW(char, namelen + 2 + dim);
908 memcpy(namebuf + dim + 1, element->name->text, namelen);
909 namelen += (2 + dim);
910 namebuf[namelen - 1] = ';';
912 memset(namebuf, '[', dim);
914 c = get_array_class(utf_new(namebuf, namelen),
915 element->classloader,
916 element->classloader,
919 dump_release(dumpsize);
925 /* class_lookup_classref *******************************************************
927 Looks up the constant_classref for a given classname in the classref
931 cls..............the class containing the reference
932 name.............the name of the class refered to
935 a pointer to a constant_classref, or
936 NULL if the reference was not found
938 *******************************************************************************/
940 constant_classref *class_lookup_classref(classinfo *cls, utf *name)
942 constant_classref *ref;
943 extra_classref *xref;
948 assert(!cls->classrefcount || cls->classrefs);
950 /* first search the main classref table */
951 count = cls->classrefcount;
952 ref = cls->classrefs;
953 for (; count; --count, ++ref)
954 if (ref->name == name)
957 /* next try the list of extra classrefs */
958 for (xref = cls->extclassrefs; xref; xref = xref->next) {
959 if (xref->classref.name == name)
960 return &(xref->classref);
968 /* class_get_classref **********************************************************
970 Returns the constant_classref for a given classname.
973 cls..............the class containing the reference
974 name.............the name of the class refered to
977 a pointer to a constant_classref (never NULL)
980 The given name is not checked for validity!
982 *******************************************************************************/
984 constant_classref *class_get_classref(classinfo *cls, utf *name)
986 constant_classref *ref;
987 extra_classref *xref;
992 ref = class_lookup_classref(cls,name);
996 xref = NEW(extra_classref);
997 CLASSREF_INIT(xref->classref,cls,name);
999 xref->next = cls->extclassrefs;
1000 cls->extclassrefs = xref;
1002 return &(xref->classref);
1006 /* class_get_self_classref *****************************************************
1008 Returns the constant_classref to the class itself.
1011 cls..............the class containing the reference
1014 a pointer to a constant_classref (never NULL)
1016 *******************************************************************************/
1018 constant_classref *class_get_self_classref(classinfo *cls)
1020 /* XXX this should be done in a faster way. Maybe always make */
1021 /* the classref of index 0 a self reference. */
1022 return class_get_classref(cls,cls->name);
1025 /* class_get_classref_multiarray_of ********************************************
1027 Returns an array type reference with the given dimension and element class
1031 dim..............the requested dimension
1032 dim must be in [1;255]. This is NOT checked!
1033 ref..............the component class reference
1036 a pointer to the class reference for the array type
1039 The referer of `ref` is used as the referer for the new classref.
1041 *******************************************************************************/
1043 constant_classref *class_get_classref_multiarray_of(s4 dim, constant_classref *ref)
1048 constant_classref *cr;
1051 assert(dim >= 1 && dim <= 255);
1053 dumpsize = dump_size();
1055 /* Assemble the array class name */
1056 namelen = ref->name->blength;
1058 if (ref->name->text[0] == '[') {
1059 /* the element is itself an array */
1060 namebuf = DMNEW(char, namelen + dim);
1061 memcpy(namebuf + dim, ref->name->text, namelen);
1065 /* the element is a non-array class */
1066 namebuf = DMNEW(char, namelen + 2 + dim);
1068 memcpy(namebuf + dim + 1, ref->name->text, namelen);
1069 namelen += (2 + dim);
1070 namebuf[namelen - 1] = ';';
1072 memset(namebuf, '[', dim);
1074 cr = class_get_classref(ref->referer,utf_new(namebuf, namelen));
1076 dump_release(dumpsize);
1082 /* class_get_classref_component_of *********************************************
1084 Returns the component classref of a given array type reference
1087 ref..............the array type reference
1090 a reference to the component class, or
1091 NULL if `ref` is not an object array type reference
1094 The referer of `ref` is used as the referer for the new classref.
1096 *******************************************************************************/
1098 constant_classref *class_get_classref_component_of(constant_classref *ref)
1105 name = ref->name->text;
1109 namelen = ref->name->blength - 1;
1114 else if (*name != '[') {
1118 return class_get_classref(ref->referer, utf_new(name, namelen));
1122 /* class_findmethod ************************************************************
1124 Searches a 'classinfo' structure for a method having the given name
1125 and descriptor. If descriptor is NULL, it is ignored.
1127 *******************************************************************************/
1129 methodinfo *class_findmethod(classinfo *c, utf *name, utf *desc)
1134 for (i = 0; i < c->methodscount; i++) {
1135 m = &(c->methods[i]);
1137 if ((m->name == name) && ((desc == NULL) || (m->descriptor == desc)))
1145 /* class_resolvemethod *********************************************************
1147 Searches a class and it's super classes for a method.
1149 Superinterfaces are *not* searched.
1151 *******************************************************************************/
1153 methodinfo *class_resolvemethod(classinfo *c, utf *name, utf *desc)
1158 m = class_findmethod(c, name, desc);
1163 /* JVM Specification bug:
1165 It is important NOT to resolve special <init> and <clinit>
1166 methods to super classes or interfaces; yet, this is not
1167 explicited in the specification. Section 5.4.3.3 should be
1168 updated appropriately. */
1170 if (name == utf_init || name == utf_clinit)
1180 /* class_resolveinterfacemethod_intern *****************************************
1182 Internally used helper function. Do not use this directly.
1184 *******************************************************************************/
1186 static methodinfo *class_resolveinterfacemethod_intern(classinfo *c,
1187 utf *name, utf *desc)
1192 /* try to find the method in the class */
1194 m = class_findmethod(c, name, desc);
1199 /* no method found? try the superinterfaces */
1201 for (i = 0; i < c->interfacescount; i++) {
1202 m = class_resolveinterfacemethod_intern(c->interfaces[i].cls,
1209 /* no method found */
1215 /* class_resolveclassmethod ****************************************************
1217 Resolves a reference from REFERER to a method with NAME and DESC in
1220 If the method cannot be resolved the return value is NULL. If
1221 EXCEPT is true *exceptionptr is set, too.
1223 *******************************************************************************/
1225 methodinfo *class_resolveclassmethod(classinfo *c, utf *name, utf *desc,
1226 classinfo *referer, bool throwexception)
1232 /* if (c->flags & ACC_INTERFACE) { */
1233 /* if (throwexception) */
1234 /* *exceptionptr = */
1235 /* new_exception(string_java_lang_IncompatibleClassChangeError); */
1239 /* try class c and its superclasses */
1243 m = class_resolvemethod(cls, name, desc);
1248 /* try the superinterfaces */
1250 for (i = 0; i < c->interfacescount; i++) {
1251 m = class_resolveinterfacemethod_intern(c->interfaces[i].cls,
1259 exceptions_throw_nosuchmethoderror(c, name, desc);
1264 if ((m->flags & ACC_ABSTRACT) && !(c->flags & ACC_ABSTRACT)) {
1266 exceptions_throw_abstractmethoderror();
1271 /* XXX check access rights */
1277 /* class_resolveinterfacemethod ************************************************
1279 Resolves a reference from REFERER to a method with NAME and DESC in
1282 If the method cannot be resolved the return value is NULL. If
1283 EXCEPT is true *exceptionptr is set, too.
1285 *******************************************************************************/
1287 methodinfo *class_resolveinterfacemethod(classinfo *c, utf *name, utf *desc,
1288 classinfo *referer, bool throwexception)
1292 if (!(c->flags & ACC_INTERFACE)) {
1294 exceptions_throw_incompatibleclasschangeerror(c, "Not an interface");
1299 mi = class_resolveinterfacemethod_intern(c, name, desc);
1304 /* try class java.lang.Object */
1306 mi = class_findmethod(class_java_lang_Object, name, desc);
1312 exceptions_throw_nosuchmethoderror(c, name, desc);
1318 /* class_findfield *************************************************************
1320 Searches for field with specified name and type in a classinfo
1321 structure. If no such field is found NULL is returned.
1323 *******************************************************************************/
1325 fieldinfo *class_findfield(classinfo *c, utf *name, utf *desc)
1329 for (i = 0; i < c->fieldscount; i++)
1330 if ((c->fields[i].name == name) && (c->fields[i].descriptor == desc))
1331 return &(c->fields[i]);
1334 return class_findfield(c->super.cls, name, desc);
1340 /* class_findfield_approx ******************************************************
1342 Searches in 'classinfo'-structure for a field with the specified
1345 *******************************************************************************/
1347 fieldinfo *class_findfield_by_name(classinfo *c, utf *name)
1351 /* get field index */
1353 i = class_findfield_index_by_name(c, name);
1355 /* field was not found, return */
1360 /* return field address */
1362 return &(c->fields[i]);
1366 s4 class_findfield_index_by_name(classinfo *c, utf *name)
1370 for (i = 0; i < c->fieldscount; i++) {
1371 /* compare field names */
1373 if ((c->fields[i].name == name))
1377 /* field was not found, raise exception */
1379 exceptions_throw_nosuchfielderror(c, name);
1385 /****************** Function: class_resolvefield_int ***************************
1387 This is an internally used helper function. Do not use this directly.
1389 Tries to resolve a field having the given name and type.
1390 If the field cannot be resolved, NULL is returned.
1392 *******************************************************************************/
1394 static fieldinfo *class_resolvefield_int(classinfo *c, utf *name, utf *desc)
1399 /* search for field in class c */
1401 for (i = 0; i < c->fieldscount; i++) {
1402 if ((c->fields[i].name == name) && (c->fields[i].descriptor == desc)) {
1403 return &(c->fields[i]);
1407 /* try superinterfaces recursively */
1409 for (i = 0; i < c->interfacescount; i++) {
1410 fi = class_resolvefield_int(c->interfaces[i].cls, name, desc);
1415 /* try superclass */
1418 return class_resolvefield_int(c->super.cls, name, desc);
1426 /********************* Function: class_resolvefield ***************************
1428 Resolves a reference from REFERER to a field with NAME and DESC in class C.
1430 If the field cannot be resolved the return value is NULL. If EXCEPT is
1431 true *exceptionptr is set, too.
1433 *******************************************************************************/
1435 fieldinfo *class_resolvefield(classinfo *c, utf *name, utf *desc,
1436 classinfo *referer, bool throwexception)
1440 fi = class_resolvefield_int(c, name, desc);
1444 exceptions_throw_nosuchfielderror(c, name);
1449 /* XXX check access rights */
1455 /* class_issubclass ************************************************************
1457 Checks if sub is a descendant of super.
1459 *******************************************************************************/
1461 bool class_issubclass(classinfo *sub, classinfo *super)
1470 sub = sub->super.cls;
1475 /* class_isanysubclass *********************************************************
1477 Checks a subclass relation between two classes. Implemented
1478 interfaces are interpreted as super classes.
1480 Return value: 1 ... sub is subclass of super
1483 *******************************************************************************/
1485 bool class_isanysubclass(classinfo *sub, classinfo *super)
1487 castinfo classvalues;
1491 /* This is the trivial case. */
1496 /* Primitive classes are only subclasses of themselves. */
1498 if ((sub->flags & ACC_CLASS_PRIMITIVE) ||
1499 (super->flags & ACC_CLASS_PRIMITIVE))
1502 /* Check for interfaces. */
1504 if (super->flags & ACC_INTERFACE) {
1505 result = (sub->vftbl->interfacetablelength > super->index) &&
1506 (sub->vftbl->interfacetable[-super->index] != NULL);
1509 /* java.lang.Object is the only super class of any
1512 if (sub->flags & ACC_INTERFACE)
1513 return (super == class_java_lang_Object);
1515 ASM_GETCLASSVALUES_ATOMIC(super->vftbl, sub->vftbl, &classvalues);
1517 diffval = classvalues.sub_baseval - classvalues.super_baseval;
1518 result = diffval <= (u4) classvalues.super_diffval;
1525 /* class_printflags ************************************************************
1527 Prints flags of a class.
1529 *******************************************************************************/
1531 #if !defined(NDEBUG)
1532 void class_printflags(classinfo *c)
1539 if (c->flags & ACC_PUBLIC) printf(" PUBLIC");
1540 if (c->flags & ACC_PRIVATE) printf(" PRIVATE");
1541 if (c->flags & ACC_PROTECTED) printf(" PROTECTED");
1542 if (c->flags & ACC_STATIC) printf(" STATIC");
1543 if (c->flags & ACC_FINAL) printf(" FINAL");
1544 if (c->flags & ACC_SYNCHRONIZED) printf(" SYNCHRONIZED");
1545 if (c->flags & ACC_VOLATILE) printf(" VOLATILE");
1546 if (c->flags & ACC_TRANSIENT) printf(" TRANSIENT");
1547 if (c->flags & ACC_NATIVE) printf(" NATIVE");
1548 if (c->flags & ACC_INTERFACE) printf(" INTERFACE");
1549 if (c->flags & ACC_ABSTRACT) printf(" ABSTRACT");
1554 /* class_print *****************************************************************
1556 Prints classname plus flags.
1558 *******************************************************************************/
1560 #if !defined(NDEBUG)
1561 void class_print(classinfo *c)
1568 utf_display_printable_ascii(c->name);
1569 class_printflags(c);
1574 /* class_classref_print ********************************************************
1576 Prints classname plus referer class.
1578 *******************************************************************************/
1580 #if !defined(NDEBUG)
1581 void class_classref_print(constant_classref *cr)
1588 utf_display_printable_ascii(cr->name);
1591 class_print(cr->referer);
1599 /* class_println ***************************************************************
1601 Prints classname plus flags and new line.
1603 *******************************************************************************/
1605 #if !defined(NDEBUG)
1606 void class_println(classinfo *c)
1614 /* class_classref_println ******************************************************
1616 Prints classname plus referer class and new line.
1618 *******************************************************************************/
1620 #if !defined(NDEBUG)
1621 void class_classref_println(constant_classref *cr)
1623 class_classref_print(cr);
1629 /* class_classref_or_classinfo_print *******************************************
1631 Prints classname plus referer class.
1633 *******************************************************************************/
1635 #if !defined(NDEBUG)
1636 void class_classref_or_classinfo_print(classref_or_classinfo c)
1638 if (c.any == NULL) {
1639 printf("(classref_or_classinfo) NULL");
1643 class_classref_print(c.ref);
1650 /* class_classref_or_classinfo_println *****************************************
1652 Prints classname plus referer class and a newline.
1654 *******************************************************************************/
1656 void class_classref_or_classinfo_println(classref_or_classinfo c)
1658 class_classref_or_classinfo_println(c);
1663 /* class_showconstantpool ******************************************************
1665 Dump the constant pool of the given class to stdout.
1667 *******************************************************************************/
1669 #if !defined(NDEBUG)
1670 void class_showconstantpool (classinfo *c)
1675 printf ("---- dump of constant pool ----\n");
1677 for (i=0; i<c->cpcount; i++) {
1678 printf ("#%d: ", (int) i);
1680 e = c -> cpinfos [i];
1683 switch (c -> cptags [i]) {
1684 case CONSTANT_Class:
1685 printf ("Classreference -> ");
1686 utf_display_printable_ascii ( ((constant_classref*)e) -> name );
1688 case CONSTANT_Fieldref:
1689 printf ("Fieldref -> ");
1690 field_fieldref_print((constant_FMIref *) e);
1692 case CONSTANT_Methodref:
1693 printf ("Methodref -> ");
1694 method_methodref_print((constant_FMIref *) e);
1696 case CONSTANT_InterfaceMethodref:
1697 printf ("InterfaceMethod -> ");
1698 method_methodref_print((constant_FMIref *) e);
1700 case CONSTANT_String:
1701 printf ("String -> ");
1702 utf_display_printable_ascii (e);
1704 case CONSTANT_Integer:
1705 printf ("Integer -> %d", (int) ( ((constant_integer*)e) -> value) );
1707 case CONSTANT_Float:
1708 printf ("Float -> %f", ((constant_float*)e) -> value);
1710 case CONSTANT_Double:
1711 printf ("Double -> %f", ((constant_double*)e) -> value);
1715 u8 v = ((constant_long*)e) -> value;
1717 printf ("Long -> %ld", (long int) v);
1719 printf ("Long -> HI: %ld, LO: %ld\n",
1720 (long int) v.high, (long int) v.low);
1724 case CONSTANT_NameAndType:
1726 constant_nameandtype *cnt = e;
1727 printf ("NameAndType: ");
1728 utf_display_printable_ascii (cnt->name);
1730 utf_display_printable_ascii (cnt->descriptor);
1734 printf ("Utf8 -> ");
1735 utf_display_printable_ascii (e);
1738 log_text("Invalid type of ConstantPool-Entry");
1746 #endif /* !defined(NDEBUG) */
1749 /* class_showmethods ***********************************************************
1751 Dump info about the fields and methods of the given class to stdout.
1753 *******************************************************************************/
1755 #if !defined(NDEBUG)
1756 void class_showmethods (classinfo *c)
1760 printf("--------- Fields and Methods ----------------\n");
1762 class_printflags(c);
1766 utf_display_printable_ascii(c->name);
1771 utf_display_printable_ascii(c->super.cls->name);
1775 printf("Index: %d\n", c->index);
1777 printf("Interfaces:\n");
1778 for (i = 0; i < c->interfacescount; i++) {
1780 utf_display_printable_ascii(c->interfaces[i].cls->name);
1781 printf (" (%d)\n", c->interfaces[i].cls->index);
1784 printf("Fields:\n");
1785 for (i = 0; i < c->fieldscount; i++)
1786 field_println(&(c->fields[i]));
1788 printf("Methods:\n");
1789 for (i = 0; i < c->methodscount; i++) {
1790 methodinfo *m = &(c->methods[i]);
1792 if (!(m->flags & ACC_STATIC))
1793 printf("vftblindex: %d ", m->vftblindex);
1798 printf ("Virtual function table:\n");
1799 for (i = 0; i < c->vftbl->vftbllength; i++)
1800 printf ("entry: %d, %ld\n", i, (long int) (c->vftbl->table[i]));
1802 #endif /* !defined(NDEBUG) */
1806 * These are local overrides for various environment variables in Emacs.
1807 * Please do not remove this and leave it at the end of the file, where
1808 * Emacs will automagically detect them.
1809 * ---------------------------------------------------------------------
1812 * indent-tabs-mode: t
1816 * vim:noexpandtab:sw=4:ts=4: