1 /* src/vm/class.c - class related functions
3 Copyright (C) 1996-2005, 2006 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 Contact: cacao@cacaojvm.org
27 Authors: Reinhard Grafl
33 $Id: class.c 6251 2006-12-27 23:15:56Z twisti $
47 #include "mm/memory.h"
49 #if defined(ENABLE_THREADS)
50 # include "threads/native/threads.h"
53 #include "toolbox/logging.h"
55 #include "vm/classcache.h"
56 #include "vm/exceptions.h"
57 #include "vm/global.h"
58 #include "vm/loader.h"
59 #include "vm/options.h"
60 #include "vm/resolve.h"
61 #include "vm/statistics.h"
62 #include "vm/stringlocal.h"
67 /* global variables ***********************************************************/
69 list 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(ENABLE_JAVASE)
101 classinfo *class_java_lang_AbstractMethodError;
102 classinfo *class_java_lang_NoSuchMethodError;
105 #if defined(WITH_CLASSPATH_GNU)
106 classinfo *class_java_lang_VMThrowable;
109 classinfo *class_java_lang_Exception;
110 classinfo *class_java_lang_ClassCastException;
111 classinfo *class_java_lang_ClassNotFoundException;
112 classinfo *class_java_lang_IllegalArgumentException;
113 classinfo *class_java_lang_IllegalMonitorStateException;
115 #if defined(ENABLE_JAVASE)
116 classinfo *class_java_lang_Void;
118 classinfo *class_java_lang_Boolean;
119 classinfo *class_java_lang_Byte;
120 classinfo *class_java_lang_Character;
121 classinfo *class_java_lang_Short;
122 classinfo *class_java_lang_Integer;
123 classinfo *class_java_lang_Long;
124 classinfo *class_java_lang_Float;
125 classinfo *class_java_lang_Double;
128 /* some runtime exception */
130 classinfo *class_java_lang_NullPointerException;
133 /* some classes which may be used more often */
135 #if defined(ENABLE_JAVASE)
136 classinfo *class_java_lang_StackTraceElement;
137 classinfo *class_java_lang_reflect_Constructor;
138 classinfo *class_java_lang_reflect_Field;
139 classinfo *class_java_lang_reflect_Method;
140 classinfo *class_java_security_PrivilegedAction;
141 classinfo *class_java_util_Vector;
143 classinfo *arrayclass_java_lang_Object;
147 /* pseudo classes for the typechecker */
149 classinfo *pseudo_class_Arraystub;
150 classinfo *pseudo_class_Null;
151 classinfo *pseudo_class_New;
154 /* class_set_packagename *******************************************************
156 Derive the package name from the class name and store it in the struct.
158 *******************************************************************************/
160 void class_set_packagename(classinfo *c)
162 char *p = UTF_END(c->name) - 1;
163 char *start = c->name->text;
165 /* set the package name */
166 /* classes in the unnamed package keep packagename == NULL */
168 if (c->name->text[0] == '[') {
169 /* set packagename of arrays to the element's package */
171 for (; *start == '['; start++);
173 /* skip the 'L' in arrays of references */
177 for (; (p > start) && (*p != '/'); --p);
179 c->packagename = utf_new(start, p - start);
182 for (; (p > start) && (*p != '/'); --p);
184 c->packagename = utf_new(start, p - start);
189 /* class_create_classinfo ******************************************************
191 Create a new classinfo struct. The class name is set to the given utf *,
192 most other fields are initialized to zero.
194 Note: classname may be NULL. In this case a not-yet-named classinfo is
195 created. The name must be filled in later and class_set_packagename
196 must be called after that.
198 *******************************************************************************/
200 classinfo *class_create_classinfo(utf *classname)
204 #if defined(ENABLE_STATISTICS)
206 size_classinfo += sizeof(classinfo);
209 /* we use a safe name for temporarily unnamed classes */
211 classname = utf_not_named_yet;
215 log_message_utf("Creating class: ", classname);
218 /* GCNEW_UNCOLLECTABLE clears the allocated memory */
220 c = GCNEW_UNCOLLECTABLE(classinfo, 1);
221 /*c=NEW(classinfo);*/
224 /* set the header.vftbl of all loaded classes to the one of
225 java.lang.Class, so Java code can use a class as object */
227 if (class_java_lang_Class)
228 if (class_java_lang_Class->vftbl)
229 c->object.header.vftbl = class_java_lang_Class->vftbl;
231 if (classname != utf_not_named_yet)
232 class_set_packagename(c);
234 #if defined(ENABLE_THREADS)
235 lock_init_object_lock(&c->object.header);
242 /* class_postset_header_vftbl **************************************************
244 Set the header.vftbl of all classes created before java.lang.Class
245 was linked. This is necessary that Java code can use a class as
248 *******************************************************************************/
250 void class_postset_header_vftbl(void)
254 classcache_name_entry *nmen;
255 classcache_class_entry *clsen;
257 assert(class_java_lang_Class);
259 for (slot = 0; slot < hashtable_classcache.size; slot++) {
260 nmen = (classcache_name_entry *) hashtable_classcache.ptr[slot];
262 for (; nmen; nmen = nmen->hashlink) {
263 /* iterate over all class entries */
265 for (clsen = nmen->classes; clsen; clsen = clsen->next) {
268 /* now set the the vftbl */
270 if (c->object.header.vftbl == NULL)
271 c->object.header.vftbl = class_java_lang_Class->vftbl;
278 /* class_load_attribute_sourcefile *********************************************
280 SourceFile_attribute {
281 u2 attribute_name_index;
286 *******************************************************************************/
288 static bool class_load_attribute_sourcefile(classbuffer *cb)
299 /* check buffer size */
301 if (!suck_check_classbuffer_size(cb, 4 + 2))
304 /* check attribute length */
306 attribute_length = suck_u4(cb);
308 if (attribute_length != 2) {
309 exceptions_throw_classformaterror(c, "Wrong size for VALUE attribute");
313 /* there can be no more than one SourceFile attribute */
315 if (c->sourcefile != NULL) {
316 exceptions_throw_classformaterror(c, "Multiple SourceFile attributes");
322 sourcefile_index = suck_u2(cb);
323 sourcefile = class_getconstant(c, sourcefile_index, CONSTANT_Utf8);
325 if (sourcefile == NULL)
328 /* store sourcefile */
330 c->sourcefile = sourcefile;
336 /* class_load_attribute_enclosingmethod ****************************************
338 EnclosingMethod_attribute {
339 u2 attribute_name_index;
345 *******************************************************************************/
347 #if defined(ENABLE_JAVASE)
348 static bool class_load_attribute_enclosingmethod(classbuffer *cb)
354 classref_or_classinfo cr;
355 constant_nameandtype *cn;
361 /* check buffer size */
363 if (!suck_check_classbuffer_size(cb, 4 + 2 + 2))
366 /* check attribute length */
368 attribute_length = suck_u4(cb);
370 if (attribute_length != 4) {
371 exceptions_throw_classformaterror(c, "Wrong size for VALUE attribute");
375 /* there can be no more than one EnclosingMethod attribute */
377 if (c->enclosingmethod != NULL) {
378 exceptions_throw_classformaterror(c, "Multiple EnclosingMethod attributes");
382 /* get class index */
384 class_index = suck_u2(cb);
385 cr.ref = innerclass_getconstant(c, class_index, CONSTANT_Class);
387 /* get method index */
389 method_index = suck_u2(cb);
390 cn = innerclass_getconstant(c, method_index, CONSTANT_NameAndType);
392 /* store info in classinfo */
394 c->enclosingclass.any = cr.any;
395 c->enclosingmethod = cn;
399 #endif /* defined(ENABLE_JAVASE) */
402 /* class_load_attributes *******************************************************
404 Read attributes from ClassFile.
407 u2 attribute_name_index;
409 u1 info[attribute_length];
412 InnerClasses_attribute {
413 u2 attribute_name_index;
417 *******************************************************************************/
419 bool class_load_attributes(classbuffer *cb)
424 u2 attribute_name_index;
429 /* get attributes count */
431 if (!suck_check_classbuffer_size(cb, 2))
434 attributes_count = suck_u2(cb);
436 for (i = 0; i < attributes_count; i++) {
437 /* get attribute name */
439 if (!suck_check_classbuffer_size(cb, 2))
442 attribute_name_index = suck_u2(cb);
444 class_getconstant(c, attribute_name_index, CONSTANT_Utf8);
446 if (attribute_name == NULL)
449 if (attribute_name == utf_InnerClasses) {
452 if (c->innerclass != NULL) {
453 exceptions_throw_classformaterror(c, "Multiple InnerClasses attributes");
457 if (!suck_check_classbuffer_size(cb, 4 + 2))
460 /* skip attribute length */
463 /* number of records */
464 c->innerclasscount = suck_u2(cb);
466 if (!suck_check_classbuffer_size(cb, (2 + 2 + 2 + 2) * c->innerclasscount))
469 /* allocate memory for innerclass structure */
470 c->innerclass = MNEW(innerclassinfo, c->innerclasscount);
472 for (j = 0; j < c->innerclasscount; j++) {
473 /* The innerclass structure contains a class with an encoded
474 name, its defining scope, its simple name and a bitmask of
475 the access flags. If an inner class is not a member, its
476 outer_class is NULL, if a class is anonymous, its name is
479 innerclassinfo *info = c->innerclass + j;
481 info->inner_class.ref =
482 innerclass_getconstant(c, suck_u2(cb), CONSTANT_Class);
483 info->outer_class.ref =
484 innerclass_getconstant(c, suck_u2(cb), CONSTANT_Class);
486 innerclass_getconstant(c, suck_u2(cb), CONSTANT_Utf8);
487 info->flags = suck_u2(cb);
490 else if (attribute_name == utf_SourceFile) {
493 if (!class_load_attribute_sourcefile(cb))
496 #if defined(ENABLE_JAVASE)
497 else if (attribute_name == utf_EnclosingMethod) {
498 /* EnclosingMethod */
500 if (!class_load_attribute_enclosingmethod(cb))
503 else if (attribute_name == utf_Signature) {
506 if (!loader_load_attribute_signature(cb, &(c->signature)))
509 else if (attribute_name == utf_RuntimeVisibleAnnotations) {
510 /* RuntimeVisibleAnnotations */
512 if (!annotation_load_attribute_runtimevisibleannotations(cb))
517 /* unknown attribute */
519 if (!loader_skip_attribute_body(cb))
528 /* class_freepool **************************************************************
530 Frees all resources used by this classes Constant Pool.
532 *******************************************************************************/
534 static void class_freecpool(classinfo *c)
540 if (c->cptags && c->cpinfos) {
541 for (idx = 0; idx < c->cpcount; idx++) {
542 tag = c->cptags[idx];
543 info = c->cpinfos[idx];
547 case CONSTANT_Fieldref:
548 case CONSTANT_Methodref:
549 case CONSTANT_InterfaceMethodref:
550 FREE(info, constant_FMIref);
552 case CONSTANT_Integer:
553 FREE(info, constant_integer);
556 FREE(info, constant_float);
559 FREE(info, constant_long);
561 case CONSTANT_Double:
562 FREE(info, constant_double);
564 case CONSTANT_NameAndType:
565 FREE(info, constant_nameandtype);
573 MFREE(c->cptags, u1, c->cpcount);
576 MFREE(c->cpinfos, voidptr, c->cpcount);
580 /* class_getconstant ***********************************************************
582 Retrieves the value at position 'pos' of the constantpool of a
583 class. If the type of the value is other than 'ctype', an error is
586 *******************************************************************************/
588 voidptr class_getconstant(classinfo *c, u4 pos, u4 ctype)
590 /* check index and type of constantpool entry */
591 /* (pos == 0 is caught by type comparison) */
593 if ((pos >= c->cpcount) || (c->cptags[pos] != ctype)) {
594 exceptions_throw_classformaterror(c, "Illegal constant pool index");
598 return c->cpinfos[pos];
602 /* innerclass_getconstant ******************************************************
604 Like class_getconstant, but if cptags is ZERO, null is returned.
606 *******************************************************************************/
608 voidptr innerclass_getconstant(classinfo *c, u4 pos, u4 ctype)
610 /* invalid position in constantpool */
612 if (pos >= c->cpcount) {
613 exceptions_throw_classformaterror(c, "Illegal constant pool index");
617 /* constantpool entry of type 0 */
619 if (c->cptags[pos] == 0)
622 /* check type of constantpool entry */
624 if (c->cptags[pos] != ctype) {
625 *exceptionptr = new_classformaterror(c, "Illegal constant pool index");
629 return c->cpinfos[pos];
633 /* class_free ******************************************************************
635 Frees all resources used by the class.
637 *******************************************************************************/
639 void class_free(classinfo *c)
647 MFREE(c->interfaces, classinfo*, c->interfacescount);
650 for (i = 0; i < c->fieldscount; i++)
651 field_free(&(c->fields[i]));
652 #if defined(ENABLE_CACAO_GC)
653 MFREE(c->fields, fieldinfo, c->fieldscount);
658 for (i = 0; i < c->methodscount; i++)
659 method_free(&(c->methods[i]));
660 MFREE(c->methods, methodinfo, c->methodscount);
663 if ((v = c->vftbl) != NULL) {
665 mem_free(v->arraydesc,sizeof(arraydescriptor));
667 for (i = 0; i < v->interfacetablelength; i++) {
668 MFREE(v->interfacetable[-i], methodptr, v->interfacevftbllength[i]);
670 MFREE(v->interfacevftbllength, s4, v->interfacetablelength);
672 i = sizeof(vftbl_t) + sizeof(methodptr) * (v->vftbllength - 1) +
673 sizeof(methodptr*) * (v->interfacetablelength -
674 (v->interfacetablelength > 0));
675 v = (vftbl_t*) (((methodptr*) v) -
676 (v->interfacetablelength - 1) * (v->interfacetablelength > 1));
681 MFREE(c->innerclass, innerclassinfo, c->innerclasscount);
683 /* if (c->classvftbl)
684 mem_free(c->header.vftbl, sizeof(vftbl) + sizeof(methodptr)*(c->vftbl->vftbllength-1)); */
690 /* get_array_class *************************************************************
692 Returns the array class with the given name for the given
693 classloader, or NULL if an exception occurred.
695 Note: This function does eager loading.
697 *******************************************************************************/
699 static classinfo *get_array_class(utf *name,java_objectheader *initloader,
700 java_objectheader *defloader,bool link)
704 /* lookup this class in the classcache */
705 c = classcache_lookup(initloader,name);
707 c = classcache_lookup_defined(defloader,name);
710 /* we have to create it */
711 c = class_create_classinfo(name);
712 c = load_newly_created_array(c,initloader);
718 assert(c->state & CLASS_LOADED);
719 assert(c->classloader == defloader);
721 if (link && !(c->state & CLASS_LINKED))
725 assert(!link || (c->state & CLASS_LINKED));
731 /* class_array_of **************************************************************
733 Returns an array class with the given component class. The array
734 class is dynamically created if neccessary.
736 *******************************************************************************/
738 classinfo *class_array_of(classinfo *component, bool link)
745 dumpsize = dump_size();
747 /* Assemble the array class name */
748 namelen = component->name->blength;
750 if (component->name->text[0] == '[') {
751 /* the component is itself an array */
752 namebuf = DMNEW(char, namelen + 1);
754 MCOPY(namebuf + 1, component->name->text, char, namelen);
758 /* the component is a non-array class */
759 namebuf = DMNEW(char, namelen + 3);
762 MCOPY(namebuf + 2, component->name->text, char, namelen);
763 namebuf[2 + namelen] = ';';
767 c = get_array_class(utf_new(namebuf, namelen),
768 component->classloader,
769 component->classloader,
772 dump_release(dumpsize);
778 /* class_multiarray_of *********************************************************
780 Returns an array class with the given dimension and element class.
781 The array class is dynamically created if neccessary.
783 *******************************************************************************/
785 classinfo *class_multiarray_of(s4 dim, classinfo *element, bool link)
792 dumpsize = dump_size();
795 log_text("Invalid array dimension requested");
799 /* Assemble the array class name */
800 namelen = element->name->blength;
802 if (element->name->text[0] == '[') {
803 /* the element is itself an array */
804 namebuf = DMNEW(char, namelen + dim);
805 memcpy(namebuf + dim, element->name->text, namelen);
809 /* the element is a non-array class */
810 namebuf = DMNEW(char, namelen + 2 + dim);
812 memcpy(namebuf + dim + 1, element->name->text, namelen);
813 namelen += (2 + dim);
814 namebuf[namelen - 1] = ';';
816 memset(namebuf, '[', dim);
818 c = get_array_class(utf_new(namebuf, namelen),
819 element->classloader,
820 element->classloader,
823 dump_release(dumpsize);
829 /* class_lookup_classref *******************************************************
831 Looks up the constant_classref for a given classname in the classref
835 cls..............the class containing the reference
836 name.............the name of the class refered to
839 a pointer to a constant_classref, or
840 NULL if the reference was not found
842 *******************************************************************************/
844 constant_classref *class_lookup_classref(classinfo *cls, utf *name)
846 constant_classref *ref;
847 extra_classref *xref;
852 assert(!cls->classrefcount || cls->classrefs);
854 /* first search the main classref table */
855 count = cls->classrefcount;
856 ref = cls->classrefs;
857 for (; count; --count, ++ref)
858 if (ref->name == name)
861 /* next try the list of extra classrefs */
862 for (xref = cls->extclassrefs; xref; xref = xref->next) {
863 if (xref->classref.name == name)
864 return &(xref->classref);
872 /* class_get_classref **********************************************************
874 Returns the constant_classref for a given classname.
877 cls..............the class containing the reference
878 name.............the name of the class refered to
881 a pointer to a constant_classref (never NULL)
884 The given name is not checked for validity!
886 *******************************************************************************/
888 constant_classref *class_get_classref(classinfo *cls, utf *name)
890 constant_classref *ref;
891 extra_classref *xref;
896 ref = class_lookup_classref(cls,name);
900 xref = NEW(extra_classref);
901 CLASSREF_INIT(xref->classref,cls,name);
903 xref->next = cls->extclassrefs;
904 cls->extclassrefs = xref;
906 return &(xref->classref);
910 /* class_get_self_classref *****************************************************
912 Returns the constant_classref to the class itself.
915 cls..............the class containing the reference
918 a pointer to a constant_classref (never NULL)
920 *******************************************************************************/
922 constant_classref *class_get_self_classref(classinfo *cls)
924 /* XXX this should be done in a faster way. Maybe always make */
925 /* the classref of index 0 a self reference. */
926 return class_get_classref(cls,cls->name);
929 /* class_get_classref_multiarray_of ********************************************
931 Returns an array type reference with the given dimension and element class
935 dim..............the requested dimension
936 dim must be in [1;255]. This is NOT checked!
937 ref..............the component class reference
940 a pointer to the class reference for the array type
943 The referer of `ref` is used as the referer for the new classref.
945 *******************************************************************************/
947 constant_classref *class_get_classref_multiarray_of(s4 dim, constant_classref *ref)
952 constant_classref *cr;
955 assert(dim >= 1 && dim <= 255);
957 dumpsize = dump_size();
959 /* Assemble the array class name */
960 namelen = ref->name->blength;
962 if (ref->name->text[0] == '[') {
963 /* the element is itself an array */
964 namebuf = DMNEW(char, namelen + dim);
965 memcpy(namebuf + dim, ref->name->text, namelen);
969 /* the element is a non-array class */
970 namebuf = DMNEW(char, namelen + 2 + dim);
972 memcpy(namebuf + dim + 1, ref->name->text, namelen);
973 namelen += (2 + dim);
974 namebuf[namelen - 1] = ';';
976 memset(namebuf, '[', dim);
978 cr = class_get_classref(ref->referer,utf_new(namebuf, namelen));
980 dump_release(dumpsize);
986 /* class_get_classref_component_of *********************************************
988 Returns the component classref of a given array type reference
991 ref..............the array type reference
994 a reference to the component class, or
995 NULL if `ref` is not an object array type reference
998 The referer of `ref` is used as the referer for the new classref.
1000 *******************************************************************************/
1002 constant_classref *class_get_classref_component_of(constant_classref *ref)
1009 name = ref->name->text;
1013 namelen = ref->name->blength - 1;
1018 else if (*name != '[') {
1022 return class_get_classref(ref->referer, utf_new(name, namelen));
1026 /* class_findmethod ************************************************************
1028 Searches a 'classinfo' structure for a method having the given name
1029 and descriptor. If descriptor is NULL, it is ignored.
1031 *******************************************************************************/
1033 methodinfo *class_findmethod(classinfo *c, utf *name, utf *desc)
1038 for (i = 0; i < c->methodscount; i++) {
1039 m = &(c->methods[i]);
1041 if ((m->name == name) && ((desc == NULL) || (m->descriptor == desc)))
1049 /* class_resolvemethod *********************************************************
1051 Searches a class and it's super classes for a method.
1053 Superinterfaces are *not* searched.
1055 *******************************************************************************/
1057 methodinfo *class_resolvemethod(classinfo *c, utf *name, utf *desc)
1062 m = class_findmethod(c, name, desc);
1067 /* JVM Specification bug:
1069 It is important NOT to resolve special <init> and <clinit>
1070 methods to super classes or interfaces; yet, this is not
1071 explicited in the specification. Section 5.4.3.3 should be
1072 updated appropriately. */
1074 if (name == utf_init || name == utf_clinit)
1084 /* class_resolveinterfacemethod_intern *****************************************
1086 Internally used helper function. Do not use this directly.
1088 *******************************************************************************/
1090 static methodinfo *class_resolveinterfacemethod_intern(classinfo *c,
1091 utf *name, utf *desc)
1096 /* try to find the method in the class */
1098 m = class_findmethod(c, name, desc);
1103 /* no method found? try the superinterfaces */
1105 for (i = 0; i < c->interfacescount; i++) {
1106 m = class_resolveinterfacemethod_intern(c->interfaces[i].cls,
1113 /* no method found */
1119 /* class_resolveclassmethod ****************************************************
1121 Resolves a reference from REFERER to a method with NAME and DESC in
1124 If the method cannot be resolved the return value is NULL. If
1125 EXCEPT is true *exceptionptr is set, too.
1127 *******************************************************************************/
1129 methodinfo *class_resolveclassmethod(classinfo *c, utf *name, utf *desc,
1130 classinfo *referer, bool throwexception)
1136 /* if (c->flags & ACC_INTERFACE) { */
1137 /* if (throwexception) */
1138 /* *exceptionptr = */
1139 /* new_exception(string_java_lang_IncompatibleClassChangeError); */
1143 /* try class c and its superclasses */
1147 m = class_resolvemethod(cls, name, desc);
1152 /* try the superinterfaces */
1154 for (i = 0; i < c->interfacescount; i++) {
1155 m = class_resolveinterfacemethod_intern(c->interfaces[i].cls,
1162 if (throwexception) {
1163 #if defined(ENABLE_JAVASE)
1164 exceptions_throw_nosuchmethoderror(c, name, desc);
1166 exceptions_throw_virtualmachineerror();
1173 if ((m->flags & ACC_ABSTRACT) && !(c->flags & ACC_ABSTRACT)) {
1174 if (throwexception) {
1175 #if defined(ENABLE_JAVASE)
1176 exceptions_throw_abstractmethoderror();
1178 exceptions_throw_virtualmachineerror();
1185 /* XXX check access rights */
1191 /* class_resolveinterfacemethod ************************************************
1193 Resolves a reference from REFERER to a method with NAME and DESC in
1196 If the method cannot be resolved the return value is NULL. If
1197 EXCEPT is true *exceptionptr is set, too.
1199 *******************************************************************************/
1201 methodinfo *class_resolveinterfacemethod(classinfo *c, utf *name, utf *desc,
1202 classinfo *referer, bool throwexception)
1206 if (!(c->flags & ACC_INTERFACE)) {
1209 new_exception(string_java_lang_IncompatibleClassChangeError);
1214 mi = class_resolveinterfacemethod_intern(c, name, desc);
1219 /* try class java.lang.Object */
1221 mi = class_findmethod(class_java_lang_Object, name, desc);
1226 if (throwexception) {
1227 #if defined(ENABLE_JAVASE)
1228 exceptions_throw_nosuchmethoderror(c, name, desc);
1230 exceptions_throw_virtualmachineerror();
1238 /* class_findfield *************************************************************
1240 Searches for field with specified name and type in a classinfo
1241 structure. If no such field is found NULL is returned.
1243 *******************************************************************************/
1245 fieldinfo *class_findfield(classinfo *c, utf *name, utf *desc)
1249 for (i = 0; i < c->fieldscount; i++)
1250 if ((c->fields[i].name == name) && (c->fields[i].descriptor == desc))
1251 return &(c->fields[i]);
1254 return class_findfield(c->super.cls, name, desc);
1260 /* class_findfield_approx ******************************************************
1262 Searches in 'classinfo'-structure for a field with the specified
1265 *******************************************************************************/
1267 fieldinfo *class_findfield_by_name(classinfo *c, utf *name)
1271 /* get field index */
1273 i = class_findfield_index_by_name(c, name);
1275 /* field was not found, return */
1280 /* return field address */
1282 return &(c->fields[i]);
1286 s4 class_findfield_index_by_name(classinfo *c, utf *name)
1290 for (i = 0; i < c->fieldscount; i++) {
1291 /* compare field names */
1293 if ((c->fields[i].name == name))
1297 /* field was not found, raise exception */
1299 *exceptionptr = new_exception(string_java_lang_NoSuchFieldException);
1305 /****************** Function: class_resolvefield_int ***************************
1307 This is an internally used helper function. Do not use this directly.
1309 Tries to resolve a field having the given name and type.
1310 If the field cannot be resolved, NULL is returned.
1312 *******************************************************************************/
1314 static fieldinfo *class_resolvefield_int(classinfo *c, utf *name, utf *desc)
1319 /* search for field in class c */
1321 for (i = 0; i < c->fieldscount; i++) {
1322 if ((c->fields[i].name == name) && (c->fields[i].descriptor == desc)) {
1323 return &(c->fields[i]);
1327 /* try superinterfaces recursively */
1329 for (i = 0; i < c->interfacescount; i++) {
1330 fi = class_resolvefield_int(c->interfaces[i].cls, name, desc);
1335 /* try superclass */
1338 return class_resolvefield_int(c->super.cls, name, desc);
1346 /********************* Function: class_resolvefield ***************************
1348 Resolves a reference from REFERER to a field with NAME and DESC in class C.
1350 If the field cannot be resolved the return value is NULL. If EXCEPT is
1351 true *exceptionptr is set, too.
1353 *******************************************************************************/
1355 fieldinfo *class_resolvefield(classinfo *c, utf *name, utf *desc,
1356 classinfo *referer, bool throwexception)
1360 fi = class_resolvefield_int(c, name, desc);
1365 new_exception_utfmessage(string_java_lang_NoSuchFieldError,
1371 /* XXX check access rights */
1377 /* class_issubclass ************************************************************
1379 Checks if sub is a descendant of super.
1381 *******************************************************************************/
1383 bool class_issubclass(classinfo *sub, classinfo *super)
1392 sub = sub->super.cls;
1397 /* class_printflags ************************************************************
1399 Prints flags of a class.
1401 *******************************************************************************/
1403 #if !defined(NDEBUG)
1404 void class_printflags(classinfo *c)
1411 if (c->flags & ACC_PUBLIC) printf(" PUBLIC");
1412 if (c->flags & ACC_PRIVATE) printf(" PRIVATE");
1413 if (c->flags & ACC_PROTECTED) printf(" PROTECTED");
1414 if (c->flags & ACC_STATIC) printf(" STATIC");
1415 if (c->flags & ACC_FINAL) printf(" FINAL");
1416 if (c->flags & ACC_SYNCHRONIZED) printf(" SYNCHRONIZED");
1417 if (c->flags & ACC_VOLATILE) printf(" VOLATILE");
1418 if (c->flags & ACC_TRANSIENT) printf(" TRANSIENT");
1419 if (c->flags & ACC_NATIVE) printf(" NATIVE");
1420 if (c->flags & ACC_INTERFACE) printf(" INTERFACE");
1421 if (c->flags & ACC_ABSTRACT) printf(" ABSTRACT");
1426 /* class_print *****************************************************************
1428 Prints classname plus flags.
1430 *******************************************************************************/
1432 #if !defined(NDEBUG)
1433 void class_print(classinfo *c)
1440 utf_display_printable_ascii(c->name);
1441 class_printflags(c);
1446 /* class_classref_print ********************************************************
1448 Prints classname plus referer class.
1450 *******************************************************************************/
1452 #if !defined(NDEBUG)
1453 void class_classref_print(constant_classref *cr)
1460 utf_display_printable_ascii(cr->name);
1463 class_print(cr->referer);
1471 /* class_println ***************************************************************
1473 Prints classname plus flags and new line.
1475 *******************************************************************************/
1477 #if !defined(NDEBUG)
1478 void class_println(classinfo *c)
1486 /* class_classref_println ******************************************************
1488 Prints classname plus referer class and new line.
1490 *******************************************************************************/
1492 #if !defined(NDEBUG)
1493 void class_classref_println(constant_classref *cr)
1495 class_classref_print(cr);
1501 /* class_classref_or_classinfo_print *******************************************
1503 Prints classname plus referer class.
1505 *******************************************************************************/
1507 #if !defined(NDEBUG)
1508 void class_classref_or_classinfo_print(classref_or_classinfo c)
1510 if (c.any == NULL) {
1511 printf("(classref_or_classinfo) NULL");
1515 class_classref_print(c.ref);
1522 /* class_classref_or_classinfo_println *****************************************
1524 Prints classname plus referer class and a newline.
1526 *******************************************************************************/
1528 void class_classref_or_classinfo_println(classref_or_classinfo c)
1530 class_classref_or_classinfo_println(c);
1535 /* class_showconstantpool ******************************************************
1537 Dump the constant pool of the given class to stdout.
1539 *******************************************************************************/
1541 #if !defined(NDEBUG)
1542 void class_showconstantpool (classinfo *c)
1547 printf ("---- dump of constant pool ----\n");
1549 for (i=0; i<c->cpcount; i++) {
1550 printf ("#%d: ", (int) i);
1552 e = c -> cpinfos [i];
1555 switch (c -> cptags [i]) {
1556 case CONSTANT_Class:
1557 printf ("Classreference -> ");
1558 utf_display_printable_ascii ( ((constant_classref*)e) -> name );
1560 case CONSTANT_Fieldref:
1561 printf ("Fieldref -> ");
1562 field_fieldref_print((constant_FMIref *) e);
1564 case CONSTANT_Methodref:
1565 printf ("Methodref -> ");
1566 method_methodref_print((constant_FMIref *) e);
1568 case CONSTANT_InterfaceMethodref:
1569 printf ("InterfaceMethod -> ");
1570 method_methodref_print((constant_FMIref *) e);
1572 case CONSTANT_String:
1573 printf ("String -> ");
1574 utf_display_printable_ascii (e);
1576 case CONSTANT_Integer:
1577 printf ("Integer -> %d", (int) ( ((constant_integer*)e) -> value) );
1579 case CONSTANT_Float:
1580 printf ("Float -> %f", ((constant_float*)e) -> value);
1582 case CONSTANT_Double:
1583 printf ("Double -> %f", ((constant_double*)e) -> value);
1587 u8 v = ((constant_long*)e) -> value;
1589 printf ("Long -> %ld", (long int) v);
1591 printf ("Long -> HI: %ld, LO: %ld\n",
1592 (long int) v.high, (long int) v.low);
1596 case CONSTANT_NameAndType:
1598 constant_nameandtype *cnt = e;
1599 printf ("NameAndType: ");
1600 utf_display_printable_ascii (cnt->name);
1602 utf_display_printable_ascii (cnt->descriptor);
1606 printf ("Utf8 -> ");
1607 utf_display_printable_ascii (e);
1610 log_text("Invalid type of ConstantPool-Entry");
1618 #endif /* !defined(NDEBUG) */
1621 /* class_showmethods ***********************************************************
1623 Dump info about the fields and methods of the given class to stdout.
1625 *******************************************************************************/
1627 #if !defined(NDEBUG)
1628 void class_showmethods (classinfo *c)
1632 printf("--------- Fields and Methods ----------------\n");
1634 class_printflags(c);
1638 utf_display_printable_ascii(c->name);
1643 utf_display_printable_ascii(c->super.cls->name);
1647 printf("Index: %d\n", c->index);
1649 printf("Interfaces:\n");
1650 for (i = 0; i < c->interfacescount; i++) {
1652 utf_display_printable_ascii(c->interfaces[i].cls->name);
1653 printf (" (%d)\n", c->interfaces[i].cls->index);
1656 printf("Fields:\n");
1657 for (i = 0; i < c->fieldscount; i++)
1658 field_println(&(c->fields[i]));
1660 printf("Methods:\n");
1661 for (i = 0; i < c->methodscount; i++) {
1662 methodinfo *m = &(c->methods[i]);
1664 if (!(m->flags & ACC_STATIC))
1665 printf("vftblindex: %d ", m->vftblindex);
1670 printf ("Virtual function table:\n");
1671 for (i = 0; i < c->vftbl->vftbllength; i++)
1672 printf ("entry: %d, %ld\n", i, (long int) (c->vftbl->table[i]));
1674 #endif /* !defined(NDEBUG) */
1678 * These are local overrides for various environment variables in Emacs.
1679 * Please do not remove this and leave it at the end of the file, where
1680 * Emacs will automagically detect them.
1681 * ---------------------------------------------------------------------
1684 * indent-tabs-mode: t
1688 * vim:noexpandtab:sw=4:ts=4: