1 /* src/vmcore/class.c - class related functions
3 Copyright (C) 1996-2005, 2006, 2007, 2008
4 CACAOVM - Verein zur Foerderung der freien virtuellen Maschine CACAO
6 This file is part of CACAO.
8 This program is free software; you can redistribute it and/or
9 modify it under the terms of the GNU General Public License as
10 published by the Free Software Foundation; either version 2, or (at
11 your option) any later version.
13 This program is distributed in the hope that it will be useful, but
14 WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 General Public License for more details.
18 You should have received a copy of the GNU General Public License
19 along with this program; if not, write to the Free Software
20 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
37 #include "mm/memory.h"
39 #include "native/llni.h"
41 #include "threads/lock-common.h"
43 #include "toolbox/logging.h"
46 #include "vm/builtin.h"
47 #include "vm/exceptions.h"
48 #include "vm/global.h"
49 #include "vm/resolve.h"
51 #include "vm/jit/asmpart.h"
53 #include "vmcore/class.h"
54 #include "vmcore/classcache.h"
55 #include "vmcore/globals.hpp"
56 #include "vmcore/linker.h"
57 #include "vmcore/loader.h"
58 #include "vmcore/options.h"
60 #if defined(ENABLE_STATISTICS)
61 # include "vmcore/statistics.h"
64 #include "vmcore/suck.h"
65 #include "vmcore/utf8.h"
68 #if defined(ENABLE_JAVASE)
69 /* We need to define some reflection functions here since we cannot
70 include native/vm/reflect.h as it includes generated header
73 java_object_t *reflect_constructor_new(methodinfo *m);
74 java_object_t *reflect_field_new(fieldinfo *f);
75 java_object_t *reflect_method_new(methodinfo *m);
79 /* class_set_packagename *******************************************************
81 Derive the package name from the class name and store it in the
84 An internal package name consists of the package name plus the
85 trailing '/', e.g. "java/lang/".
87 For classes in the unnamed package, the package name is set to
90 *******************************************************************************/
92 void class_set_packagename(classinfo *c)
97 p = UTF_END(c->name) - 1;
98 start = c->name->text;
100 if (c->name->text[0] == '[') {
101 /* Set packagename of arrays to the element's package. */
103 for (; *start == '['; start++);
105 /* Skip the 'L' in arrays of references. */
111 /* Search for last '/'. */
113 for (; (p > start) && (*p != '/'); --p);
115 /* If we found a '/' we set the package name plus the trailing
116 '/'. Otherwise we set the packagename to NULL. */
119 c->packagename = utf_new(start, p - start + 1);
121 c->packagename = NULL;
125 /* class_create_classinfo ******************************************************
127 Create a new classinfo struct. The class name is set to the given utf *,
128 most other fields are initialized to zero.
130 Note: classname may be NULL. In this case a not-yet-named classinfo is
131 created. The name must be filled in later and class_set_packagename
132 must be called after that.
134 *******************************************************************************/
136 classinfo *class_create_classinfo(utf *classname)
140 #if defined(ENABLE_STATISTICS)
142 size_classinfo += sizeof(classinfo);
145 /* we use a safe name for temporarily unnamed classes */
147 if (classname == NULL)
148 classname = utf_not_named_yet;
152 log_message_utf("Creating class: ", classname);
155 #if !defined(ENABLE_GC_BOEHM)
156 c = (classinfo *) heap_alloc_uncollectable(sizeof(classinfo));
157 /*c = NEW(classinfo);
158 MZERO(c, classinfo, 1);*/
160 c = GCNEW_UNCOLLECTABLE(classinfo, 1);
161 /* GCNEW_UNCOLLECTABLE clears the allocated memory */
166 /* Set the header.vftbl of all loaded classes to the one of
167 java.lang.Class, so Java code can use a class as object. */
169 if (class_java_lang_Class != NULL)
170 if (class_java_lang_Class->vftbl != NULL)
171 c->object.header.vftbl = class_java_lang_Class->vftbl;
173 #if defined(ENABLE_JAVASE)
174 /* check if the class is a reference class and flag it */
176 if (classname == utf_java_lang_ref_SoftReference) {
177 c->flags |= ACC_CLASS_REFERENCE_SOFT;
179 else if (classname == utf_java_lang_ref_WeakReference) {
180 c->flags |= ACC_CLASS_REFERENCE_WEAK;
182 else if (classname == utf_java_lang_ref_PhantomReference) {
183 c->flags |= ACC_CLASS_REFERENCE_PHANTOM;
187 if (classname != utf_not_named_yet)
188 class_set_packagename(c);
190 LOCK_INIT_OBJECT_LOCK(&c->object.header);
196 /* class_postset_header_vftbl **************************************************
198 Set the header.vftbl of all classes created before java.lang.Class
199 was linked. This is necessary that Java code can use a class as
202 *******************************************************************************/
204 void class_postset_header_vftbl(void)
208 classcache_name_entry *nmen;
209 classcache_class_entry *clsen;
211 assert(class_java_lang_Class);
213 for (slot = 0; slot < hashtable_classcache.size; slot++) {
214 nmen = (classcache_name_entry *) hashtable_classcache.ptr[slot];
216 for (; nmen; nmen = nmen->hashlink) {
217 /* iterate over all class entries */
219 for (clsen = nmen->classes; clsen; clsen = clsen->next) {
222 /* now set the the vftbl */
224 if (c->object.header.vftbl == NULL)
225 c->object.header.vftbl = class_java_lang_Class->vftbl;
231 /* class_define ****************************************************************
233 Calls the loader and defines a class in the VM.
235 *******************************************************************************/
237 classinfo *class_define(utf *name, classloader_t *cl, int32_t length, uint8_t *data, java_handle_t *pd)
244 /* check if this class has already been defined */
246 c = classcache_lookup_defined_or_initiated(cl, name);
249 exceptions_throw_linkageerror("duplicate class definition: ", c);
254 /* create a new classinfo struct */
256 c = class_create_classinfo(name);
258 #if defined(ENABLE_STATISTICS)
261 if (opt_getloadingtime)
265 /* build a classbuffer with the given data */
267 cb = NEW(classbuffer);
274 /* preset the defining classloader */
278 /* load the class from this buffer */
280 r = load_class_from_classbuffer(cb);
284 FREE(cb, classbuffer);
286 #if defined(ENABLE_STATISTICS)
289 if (opt_getloadingtime)
294 /* If return value is NULL, we had a problem and the class is
295 not loaded. Now free the allocated memory, otherwise we
296 could run into a DOS. */
303 #if defined(ENABLE_JAVASE)
304 # if defined(WITH_JAVA_RUNTIME_LIBRARY_OPENJDK)
305 /* Store the protection domain. */
307 c->protectiondomain = pd;
311 /* Store the newly defined class in the class cache. This call
312 also checks whether a class of the same name has already been
313 defined by the same defining loader, and if so, replaces the
314 newly created class by the one defined earlier. */
316 /* Important: The classinfo given to classcache_store must be
317 fully prepared because another thread may return
318 this pointer after the lookup at to top of this
319 function directly after the class cache lock has
322 c = classcache_store(cl, c, true);
328 /* class_load_attribute_sourcefile *********************************************
330 SourceFile_attribute {
331 u2 attribute_name_index;
336 *******************************************************************************/
338 static bool class_load_attribute_sourcefile(classbuffer *cb)
349 /* check buffer size */
351 if (!suck_check_classbuffer_size(cb, 4 + 2))
354 /* check attribute length */
356 attribute_length = suck_u4(cb);
358 if (attribute_length != 2) {
359 exceptions_throw_classformaterror(c, "Wrong size for VALUE attribute");
363 /* there can be no more than one SourceFile attribute */
365 if (c->sourcefile != NULL) {
366 exceptions_throw_classformaterror(c, "Multiple SourceFile attributes");
372 sourcefile_index = suck_u2(cb);
373 sourcefile = class_getconstant(c, sourcefile_index, CONSTANT_Utf8);
375 if (sourcefile == NULL)
378 /* store sourcefile */
380 c->sourcefile = sourcefile;
386 /* class_load_attribute_enclosingmethod ****************************************
388 EnclosingMethod_attribute {
389 u2 attribute_name_index;
395 *******************************************************************************/
397 #if defined(ENABLE_JAVASE)
398 static bool class_load_attribute_enclosingmethod(classbuffer *cb)
404 classref_or_classinfo cr;
405 constant_nameandtype *cn;
411 /* check buffer size */
413 if (!suck_check_classbuffer_size(cb, 4 + 2 + 2))
416 /* check attribute length */
418 attribute_length = suck_u4(cb);
420 if (attribute_length != 4) {
421 exceptions_throw_classformaterror(c, "Wrong size for VALUE attribute");
425 /* there can be no more than one EnclosingMethod attribute */
427 if (c->enclosingmethod != NULL) {
428 exceptions_throw_classformaterror(c, "Multiple EnclosingMethod attributes");
432 /* get class index */
434 class_index = suck_u2(cb);
435 cr.ref = innerclass_getconstant(c, class_index, CONSTANT_Class);
437 /* get method index */
439 method_index = suck_u2(cb);
440 cn = innerclass_getconstant(c, method_index, CONSTANT_NameAndType);
442 /* store info in classinfo */
444 c->enclosingclass.any = cr.any;
445 c->enclosingmethod = cn;
449 #endif /* defined(ENABLE_JAVASE) */
452 /* class_load_attributes *******************************************************
454 Read attributes from ClassFile.
457 u2 attribute_name_index;
459 u1 info[attribute_length];
462 InnerClasses_attribute {
463 u2 attribute_name_index;
467 *******************************************************************************/
469 bool class_load_attributes(classbuffer *cb)
472 uint16_t attributes_count;
473 uint16_t attribute_name_index;
475 innerclassinfo *info;
476 classref_or_classinfo inner;
477 classref_or_classinfo outer;
484 /* get attributes count */
486 if (!suck_check_classbuffer_size(cb, 2))
489 attributes_count = suck_u2(cb);
491 for (i = 0; i < attributes_count; i++) {
492 /* get attribute name */
494 if (!suck_check_classbuffer_size(cb, 2))
497 attribute_name_index = suck_u2(cb);
499 class_getconstant(c, attribute_name_index, CONSTANT_Utf8);
501 if (attribute_name == NULL)
504 if (attribute_name == utf_InnerClasses) {
507 if (c->innerclass != NULL) {
508 exceptions_throw_classformaterror(c, "Multiple InnerClasses attributes");
512 if (!suck_check_classbuffer_size(cb, 4 + 2))
515 /* skip attribute length */
518 /* number of records */
519 c->innerclasscount = suck_u2(cb);
521 if (!suck_check_classbuffer_size(cb, (2 + 2 + 2 + 2) * c->innerclasscount))
524 /* allocate memory for innerclass structure */
525 c->innerclass = MNEW(innerclassinfo, c->innerclasscount);
527 for (j = 0; j < c->innerclasscount; j++) {
528 /* The innerclass structure contains a class with an encoded
529 name, its defining scope, its simple name and a bitmask of
532 info = c->innerclass + j;
534 inner.ref = innerclass_getconstant(c, suck_u2(cb), CONSTANT_Class);
535 outer.ref = innerclass_getconstant(c, suck_u2(cb), CONSTANT_Class);
536 name = innerclass_getconstant(c, suck_u2(cb), CONSTANT_Utf8);
539 /* If the current inner-class is the currently loaded
540 class check for some special flags. */
542 if (inner.ref->name == c->name) {
543 /* If an inner-class is not a member, its
544 outer-class is NULL. */
546 if (outer.ref != NULL) {
547 c->flags |= ACC_CLASS_MEMBER;
549 /* A member class doesn't have an
550 EnclosingMethod attribute, so set the
551 enclosing-class to be the same as the
554 c->declaringclass = outer;
555 c->enclosingclass = outer;
558 /* If an inner-class is anonymous, its name is
562 c->flags |= ACC_CLASS_ANONYMOUS;
565 info->inner_class = inner;
566 info->outer_class = outer;
571 else if (attribute_name == utf_SourceFile) {
574 if (!class_load_attribute_sourcefile(cb))
577 #if defined(ENABLE_JAVASE)
578 else if (attribute_name == utf_EnclosingMethod) {
579 /* EnclosingMethod */
581 if (!class_load_attribute_enclosingmethod(cb))
584 else if (attribute_name == utf_Signature) {
587 if (!loader_load_attribute_signature(cb, &(c->signature)))
592 #if defined(ENABLE_ANNOTATIONS)
593 else if (attribute_name == utf_RuntimeVisibleAnnotations) {
594 /* RuntimeVisibleAnnotations */
595 if (!annotation_load_class_attribute_runtimevisibleannotations(cb))
598 else if (attribute_name == utf_RuntimeInvisibleAnnotations) {
599 /* RuntimeInvisibleAnnotations */
600 if (!annotation_load_class_attribute_runtimeinvisibleannotations(cb))
606 /* unknown attribute */
608 if (!loader_skip_attribute_body(cb))
617 /* class_freepool **************************************************************
619 Frees all resources used by this classes Constant Pool.
621 *******************************************************************************/
623 static void class_freecpool(classinfo *c)
629 if (c->cptags && c->cpinfos) {
630 for (idx = 0; idx < c->cpcount; idx++) {
631 tag = c->cptags[idx];
632 info = c->cpinfos[idx];
636 case CONSTANT_Fieldref:
637 case CONSTANT_Methodref:
638 case CONSTANT_InterfaceMethodref:
639 FREE(info, constant_FMIref);
641 case CONSTANT_Integer:
642 FREE(info, constant_integer);
645 FREE(info, constant_float);
648 FREE(info, constant_long);
650 case CONSTANT_Double:
651 FREE(info, constant_double);
653 case CONSTANT_NameAndType:
654 FREE(info, constant_nameandtype);
662 MFREE(c->cptags, u1, c->cpcount);
665 MFREE(c->cpinfos, voidptr, c->cpcount);
669 /* class_getconstant ***********************************************************
671 Retrieves the value at position 'pos' of the constantpool of a
672 class. If the type of the value is other than 'ctype', an error is
675 *******************************************************************************/
677 voidptr class_getconstant(classinfo *c, u4 pos, u4 ctype)
679 /* check index and type of constantpool entry */
680 /* (pos == 0 is caught by type comparison) */
682 if ((pos >= c->cpcount) || (c->cptags[pos] != ctype)) {
683 exceptions_throw_classformaterror(c, "Illegal constant pool index");
687 return c->cpinfos[pos];
691 /* innerclass_getconstant ******************************************************
693 Like class_getconstant, but if cptags is ZERO, null is returned.
695 *******************************************************************************/
697 voidptr innerclass_getconstant(classinfo *c, u4 pos, u4 ctype)
699 /* invalid position in constantpool */
701 if (pos >= c->cpcount) {
702 exceptions_throw_classformaterror(c, "Illegal constant pool index");
706 /* constantpool entry of type 0 */
708 if (c->cptags[pos] == 0)
711 /* check type of constantpool entry */
713 if (c->cptags[pos] != ctype) {
714 exceptions_throw_classformaterror(c, "Illegal constant pool index");
718 return c->cpinfos[pos];
722 /* class_free ******************************************************************
724 Frees all resources used by the class.
726 *******************************************************************************/
728 void class_free(classinfo *c)
735 if (c->interfaces != NULL)
736 MFREE(c->interfaces, classinfo*, c->interfacescount);
739 for (i = 0; i < c->fieldscount; i++)
740 field_free(&(c->fields[i]));
741 MFREE(c->fields, fieldinfo, c->fieldscount);
745 for (i = 0; i < c->methodscount; i++)
746 method_free(&(c->methods[i]));
747 MFREE(c->methods, methodinfo, c->methodscount);
750 if ((v = c->vftbl) != NULL) {
752 mem_free(v->arraydesc,sizeof(arraydescriptor));
754 for (i = 0; i < v->interfacetablelength; i++) {
755 MFREE(v->interfacetable[-i], methodptr, v->interfacevftbllength[i]);
757 MFREE(v->interfacevftbllength, s4, v->interfacetablelength);
759 i = sizeof(vftbl_t) + sizeof(methodptr) * (v->vftbllength - 1) +
760 sizeof(methodptr*) * (v->interfacetablelength -
761 (v->interfacetablelength > 0));
762 v = (vftbl_t*) (((methodptr*) v) -
763 (v->interfacetablelength - 1) * (v->interfacetablelength > 1));
768 MFREE(c->innerclass, innerclassinfo, c->innerclasscount);
770 /* if (c->classvftbl)
771 mem_free(c->header.vftbl, sizeof(vftbl) + sizeof(methodptr)*(c->vftbl->vftbllength-1)); */
777 /* get_array_class *************************************************************
779 Returns the array class with the given name for the given
780 classloader, or NULL if an exception occurred.
782 Note: This function does eager loading.
784 *******************************************************************************/
786 static classinfo *get_array_class(utf *name,classloader_t *initloader,
787 classloader_t *defloader,bool link)
791 /* lookup this class in the classcache */
792 c = classcache_lookup(initloader,name);
794 c = classcache_lookup_defined(defloader,name);
797 /* we have to create it */
798 c = class_create_classinfo(name);
799 c = load_newly_created_array(c,initloader);
805 assert(c->state & CLASS_LOADED);
806 assert(c->classloader == defloader);
808 if (link && !(c->state & CLASS_LINKED))
812 assert(!link || (c->state & CLASS_LINKED));
818 /* class_array_of **************************************************************
820 Returns an array class with the given component class. The array
821 class is dynamically created if neccessary.
823 *******************************************************************************/
825 classinfo *class_array_of(classinfo *component, bool link)
834 cl = component->classloader;
838 /* Assemble the array class name */
839 namelen = component->name->blength;
841 if (component->name->text[0] == '[') {
842 /* the component is itself an array */
843 namebuf = DMNEW(char, namelen + 1);
845 MCOPY(namebuf + 1, component->name->text, char, namelen);
849 /* the component is a non-array class */
850 namebuf = DMNEW(char, namelen + 3);
853 MCOPY(namebuf + 2, component->name->text, char, namelen);
854 namebuf[2 + namelen] = ';';
858 u = utf_new(namebuf, namelen);
860 c = get_array_class(u, cl, cl, link);
868 /* class_multiarray_of *********************************************************
870 Returns an array class with the given dimension and element class.
871 The array class is dynamically created if neccessary.
873 *******************************************************************************/
875 classinfo *class_multiarray_of(s4 dim, classinfo *element, bool link)
885 log_text("Invalid array dimension requested");
889 /* Assemble the array class name */
890 namelen = element->name->blength;
892 if (element->name->text[0] == '[') {
893 /* the element is itself an array */
894 namebuf = DMNEW(char, namelen + dim);
895 memcpy(namebuf + dim, element->name->text, namelen);
899 /* the element is a non-array class */
900 namebuf = DMNEW(char, namelen + 2 + dim);
902 memcpy(namebuf + dim + 1, element->name->text, namelen);
903 namelen += (2 + dim);
904 namebuf[namelen - 1] = ';';
906 memset(namebuf, '[', dim);
908 c = get_array_class(utf_new(namebuf, namelen),
909 element->classloader,
910 element->classloader,
919 /* class_lookup_classref *******************************************************
921 Looks up the constant_classref for a given classname in the classref
925 cls..............the class containing the reference
926 name.............the name of the class refered to
929 a pointer to a constant_classref, or
930 NULL if the reference was not found
932 *******************************************************************************/
934 constant_classref *class_lookup_classref(classinfo *cls, utf *name)
936 constant_classref *ref;
937 extra_classref *xref;
942 assert(!cls->classrefcount || cls->classrefs);
944 /* first search the main classref table */
945 count = cls->classrefcount;
946 ref = cls->classrefs;
947 for (; count; --count, ++ref)
948 if (ref->name == name)
951 /* next try the list of extra classrefs */
952 for (xref = cls->extclassrefs; xref; xref = xref->next) {
953 if (xref->classref.name == name)
954 return &(xref->classref);
962 /* class_get_classref **********************************************************
964 Returns the constant_classref for a given classname.
967 cls..............the class containing the reference
968 name.............the name of the class refered to
971 a pointer to a constant_classref (never NULL)
974 The given name is not checked for validity!
976 *******************************************************************************/
978 constant_classref *class_get_classref(classinfo *cls, utf *name)
980 constant_classref *ref;
981 extra_classref *xref;
986 ref = class_lookup_classref(cls,name);
990 xref = NEW(extra_classref);
991 CLASSREF_INIT(xref->classref,cls,name);
993 xref->next = cls->extclassrefs;
994 cls->extclassrefs = xref;
996 return &(xref->classref);
1000 /* class_get_self_classref *****************************************************
1002 Returns the constant_classref to the class itself.
1005 cls..............the class containing the reference
1008 a pointer to a constant_classref (never NULL)
1010 *******************************************************************************/
1012 constant_classref *class_get_self_classref(classinfo *cls)
1014 /* XXX this should be done in a faster way. Maybe always make */
1015 /* the classref of index 0 a self reference. */
1016 return class_get_classref(cls,cls->name);
1019 /* class_get_classref_multiarray_of ********************************************
1021 Returns an array type reference with the given dimension and element class
1025 dim..............the requested dimension
1026 dim must be in [1;255]. This is NOT checked!
1027 ref..............the component class reference
1030 a pointer to the class reference for the array type
1033 The referer of `ref` is used as the referer for the new classref.
1035 *******************************************************************************/
1037 constant_classref *class_get_classref_multiarray_of(s4 dim, constant_classref *ref)
1041 constant_classref *cr;
1045 assert(dim >= 1 && dim <= 255);
1049 /* Assemble the array class name */
1050 namelen = ref->name->blength;
1052 if (ref->name->text[0] == '[') {
1053 /* the element is itself an array */
1054 namebuf = DMNEW(char, namelen + dim);
1055 memcpy(namebuf + dim, ref->name->text, namelen);
1059 /* the element is a non-array class */
1060 namebuf = DMNEW(char, namelen + 2 + dim);
1062 memcpy(namebuf + dim + 1, ref->name->text, namelen);
1063 namelen += (2 + dim);
1064 namebuf[namelen - 1] = ';';
1066 memset(namebuf, '[', dim);
1068 cr = class_get_classref(ref->referer,utf_new(namebuf, namelen));
1076 /* class_get_classref_component_of *********************************************
1078 Returns the component classref of a given array type reference
1081 ref..............the array type reference
1084 a reference to the component class, or
1085 NULL if `ref` is not an object array type reference
1088 The referer of `ref` is used as the referer for the new classref.
1090 *******************************************************************************/
1092 constant_classref *class_get_classref_component_of(constant_classref *ref)
1099 name = ref->name->text;
1103 namelen = ref->name->blength - 1;
1108 else if (*name != '[') {
1112 return class_get_classref(ref->referer, utf_new(name, namelen));
1116 /* class_findmethod ************************************************************
1118 Searches a 'classinfo' structure for a method having the given name
1119 and descriptor. If descriptor is NULL, it is ignored.
1121 *******************************************************************************/
1123 methodinfo *class_findmethod(classinfo *c, utf *name, utf *desc)
1128 for (i = 0; i < c->methodscount; i++) {
1129 m = &(c->methods[i]);
1131 if ((m->name == name) && ((desc == NULL) || (m->descriptor == desc)))
1139 /* class_resolvemethod *********************************************************
1141 Searches a class and it's super classes for a method.
1143 Superinterfaces are *not* searched.
1145 *******************************************************************************/
1147 methodinfo *class_resolvemethod(classinfo *c, utf *name, utf *desc)
1152 m = class_findmethod(c, name, desc);
1157 /* JVM Specification bug:
1159 It is important NOT to resolve special <init> and <clinit>
1160 methods to super classes or interfaces; yet, this is not
1161 explicited in the specification. Section 5.4.3.3 should be
1162 updated appropriately. */
1164 if (name == utf_init || name == utf_clinit)
1174 /* class_resolveinterfacemethod_intern *****************************************
1176 Internally used helper function. Do not use this directly.
1178 *******************************************************************************/
1180 static methodinfo *class_resolveinterfacemethod_intern(classinfo *c,
1181 utf *name, utf *desc)
1186 /* try to find the method in the class */
1188 m = class_findmethod(c, name, desc);
1193 /* No method found? Try the super interfaces. */
1195 for (i = 0; i < c->interfacescount; i++) {
1196 m = class_resolveinterfacemethod_intern(c->interfaces[i], name, desc);
1202 /* no method found */
1208 /* class_resolveclassmethod ****************************************************
1210 Resolves a reference from REFERER to a method with NAME and DESC in
1213 If the method cannot be resolved the return value is NULL. If
1214 EXCEPT is true *exceptionptr is set, too.
1216 *******************************************************************************/
1218 methodinfo *class_resolveclassmethod(classinfo *c, utf *name, utf *desc,
1219 classinfo *referer, bool throwexception)
1225 /* if (c->flags & ACC_INTERFACE) { */
1226 /* if (throwexception) */
1227 /* *exceptionptr = */
1228 /* new_exception(string_java_lang_IncompatibleClassChangeError); */
1232 /* try class c and its superclasses */
1236 m = class_resolvemethod(cls, name, desc);
1241 /* Try the super interfaces. */
1243 for (i = 0; i < c->interfacescount; i++) {
1244 m = class_resolveinterfacemethod_intern(c->interfaces[i], name, desc);
1251 exceptions_throw_nosuchmethoderror(c, name, desc);
1256 if ((m->flags & ACC_ABSTRACT) && !(c->flags & ACC_ABSTRACT)) {
1258 exceptions_throw_abstractmethoderror();
1263 /* XXX check access rights */
1269 /* class_resolveinterfacemethod ************************************************
1271 Resolves a reference from REFERER to a method with NAME and DESC in
1274 If the method cannot be resolved the return value is NULL. If
1275 EXCEPT is true *exceptionptr is set, too.
1277 *******************************************************************************/
1279 methodinfo *class_resolveinterfacemethod(classinfo *c, utf *name, utf *desc,
1280 classinfo *referer, bool throwexception)
1284 if (!(c->flags & ACC_INTERFACE)) {
1286 exceptions_throw_incompatibleclasschangeerror(c, "Not an interface");
1291 mi = class_resolveinterfacemethod_intern(c, name, desc);
1296 /* try class java.lang.Object */
1298 mi = class_findmethod(class_java_lang_Object, name, desc);
1304 exceptions_throw_nosuchmethoderror(c, name, desc);
1310 /* class_findfield *************************************************************
1312 Searches for field with specified name and type in a classinfo
1313 structure. If no such field is found NULL is returned.
1315 *******************************************************************************/
1317 fieldinfo *class_findfield(classinfo *c, utf *name, utf *desc)
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]);
1325 if (c->super != NULL)
1326 return class_findfield(c->super, name, desc);
1332 /* class_findfield_approx ******************************************************
1334 Searches in 'classinfo'-structure for a field with the specified
1337 *******************************************************************************/
1339 fieldinfo *class_findfield_by_name(classinfo *c, utf *name)
1343 /* get field index */
1345 i = class_findfield_index_by_name(c, name);
1347 /* field was not found, return */
1352 /* return field address */
1354 return &(c->fields[i]);
1358 s4 class_findfield_index_by_name(classinfo *c, utf *name)
1362 for (i = 0; i < c->fieldscount; i++) {
1363 /* compare field names */
1365 if ((c->fields[i].name == name))
1369 /* field was not found, raise exception */
1371 exceptions_throw_nosuchfielderror(c, name);
1377 /****************** Function: class_resolvefield_int ***************************
1379 This is an internally used helper function. Do not use this directly.
1381 Tries to resolve a field having the given name and type.
1382 If the field cannot be resolved, NULL is returned.
1384 *******************************************************************************/
1386 static fieldinfo *class_resolvefield_int(classinfo *c, utf *name, utf *desc)
1391 /* search for field in class c */
1393 for (i = 0; i < c->fieldscount; i++) {
1394 if ((c->fields[i].name == name) && (c->fields[i].descriptor == desc)) {
1395 return &(c->fields[i]);
1399 /* Try super interfaces recursively. */
1401 for (i = 0; i < c->interfacescount; i++) {
1402 fi = class_resolvefield_int(c->interfaces[i], name, desc);
1408 /* Try super class. */
1410 if (c->super != NULL)
1411 return class_resolvefield_int(c->super, name, desc);
1419 /********************* Function: class_resolvefield ***************************
1421 Resolves a reference from REFERER to a field with NAME and DESC in class C.
1423 If the field cannot be resolved the return value is NULL. If EXCEPT is
1424 true *exceptionptr is set, too.
1426 *******************************************************************************/
1428 fieldinfo *class_resolvefield(classinfo *c, utf *name, utf *desc,
1429 classinfo *referer, bool throwexception)
1433 fi = class_resolvefield_int(c, name, desc);
1437 exceptions_throw_nosuchfielderror(c, name);
1442 /* XXX check access rights */
1448 /* class_issubclass ************************************************************
1450 Checks if sub is a descendant of super.
1452 *******************************************************************************/
1454 bool class_issubclass(classinfo *sub, classinfo *super)
1461 /* We reached java/lang/Object and did not find the requested
1467 /* We found the requested super class. */
1477 /* class_isanysubclass *********************************************************
1479 Checks a subclass relation between two classes. Implemented
1480 interfaces are interpreted as super classes.
1482 Return value: 1 ... sub is subclass of super
1485 *******************************************************************************/
1487 bool class_isanysubclass(classinfo *sub, classinfo *super)
1492 /* This is the trivial case. */
1497 /* Primitive classes are only subclasses of themselves. */
1499 if (class_is_primitive(sub) || class_is_primitive(super))
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 LOCK_MONITOR_ENTER(linker_classrenumber_lock);
1517 diffval = sub->vftbl->baseval - super->vftbl->baseval;
1518 result = diffval <= (uint32_t) super->vftbl->diffval;
1520 LOCK_MONITOR_EXIT(linker_classrenumber_lock);
1527 /* class_is_assignable_from ****************************************************
1529 Return whether an instance of the "from" class parameter would be
1530 an instance of this class "to" as well.
1537 true .... is assignable
1538 false ... is not assignable
1540 *******************************************************************************/
1542 bool class_is_assignable_from(classinfo *to, classinfo *from)
1544 if (!(to->state & CLASS_LINKED))
1545 if (!link_class(to))
1548 if (!(from->state & CLASS_LINKED))
1549 if (!link_class(from))
1552 return class_isanysubclass(from, to);
1556 /* class_is_instance ***********************************************************
1558 Return if the given Java object is an instance of the given class.
1565 true .... is instance
1566 false ... is not instance
1568 *******************************************************************************/
1570 bool class_is_instance(classinfo *c, java_handle_t *h)
1572 if (!(c->state & CLASS_LINKED))
1576 return builtin_instanceof(h, c);
1580 /* class_get_componenttype *****************************************************
1582 Return the component class of the given class. If the given class
1583 is not an array, return NULL.
1585 *******************************************************************************/
1587 classinfo *class_get_componenttype(classinfo *c)
1589 classinfo *component;
1590 arraydescriptor *ad;
1592 /* XXX maybe we could find a way to do this without linking. */
1593 /* This way should be safe and easy, however. */
1595 if (!(c->state & CLASS_LINKED))
1599 ad = c->vftbl->arraydesc;
1604 if (ad->arraytype == ARRAYTYPE_OBJECT)
1605 component = ad->componentvftbl->clazz;
1607 component = Primitive_get_class_by_type(ad->arraytype);
1613 /* class_get_declaredclasses ***************************************************
1615 Return an array of declared classes of the given class.
1617 *******************************************************************************/
1619 java_handle_objectarray_t *class_get_declaredclasses(classinfo *c, bool publicOnly)
1621 classref_or_classinfo inner;
1622 classref_or_classinfo outer;
1624 int declaredclasscount; /* number of declared classes */
1625 int pos; /* current declared class */
1626 java_handle_objectarray_t *oa; /* array of declared classes */
1630 declaredclasscount = 0;
1632 if (!class_is_primitive(c) && !class_is_array(c)) {
1633 /* Determine number of declared classes. */
1635 for (i = 0; i < c->innerclasscount; i++) {
1636 /* Get outer-class. If the inner-class is not a member
1637 class, the outer-class is NULL. */
1639 outer = c->innerclass[i].outer_class;
1641 if (outer.any == NULL)
1644 /* Check if outer-class is a classref or a real class and
1645 get the class name from the structure. */
1647 outername = IS_CLASSREF(outer) ? outer.ref->name : outer.cls->name;
1649 /* Outer class is this class. */
1651 if ((outername == c->name) &&
1652 ((publicOnly == 0) || (c->innerclass[i].flags & ACC_PUBLIC)))
1653 declaredclasscount++;
1657 /* Allocate Class[] and check for OOM. */
1659 oa = builtin_anewarray(declaredclasscount, class_java_lang_Class);
1664 for (i = 0, pos = 0; i < c->innerclasscount; i++) {
1665 inner = c->innerclass[i].inner_class;
1666 outer = c->innerclass[i].outer_class;
1668 /* Get outer-class. If the inner-class is not a member class,
1669 the outer-class is NULL. */
1671 if (outer.any == NULL)
1674 /* Check if outer_class is a classref or a real class and get
1675 the class name from the structure. */
1677 outername = IS_CLASSREF(outer) ? outer.ref->name : outer.cls->name;
1679 /* Outer class is this class. */
1681 if ((outername == c->name) &&
1682 ((publicOnly == 0) || (c->innerclass[i].flags & ACC_PUBLIC))) {
1684 ic = resolve_classref_or_classinfo_eager(inner, false);
1689 if (!(ic->state & CLASS_LINKED))
1690 if (!link_class(ic))
1693 LLNI_array_direct(oa, pos++) = (java_object_t *) ic;
1702 * Return an array of declared constructors of the given class.
1704 * @param c class to get the constructors of
1705 * @param publicOnly show only public fields
1707 * @return array of java.lang.reflect.Constructor
1709 #if defined(ENABLE_JAVASE)
1710 java_handle_objectarray_t *class_get_declaredconstructors(classinfo *c, bool publicOnly)
1713 java_handle_objectarray_t* oa;
1719 /* Determine number of constructors. */
1723 for (i = 0; i < c->methodscount; i++) {
1724 m = &(c->methods[i]);
1726 if (((m->flags & ACC_PUBLIC) || (publicOnly == 0)) &&
1727 (m->name == utf_init))
1731 /* Create array of constructors. */
1733 oa = builtin_anewarray(count, class_java_lang_reflect_Constructor);
1738 /* Get the constructors and store them in the array. */
1740 for (i = 0, index = 0; i < c->methodscount; i++) {
1741 m = &(c->methods[i]);
1743 if (((m->flags & ACC_PUBLIC) || (publicOnly == 0)) &&
1744 (m->name == utf_init)) {
1745 /* Create Constructor object. This is actualy a
1746 java_lang_reflect_Constructor pointer, but we use a
1747 java_handle_t here, because we don't have the header
1748 available when building vmcore. */
1750 rc = reflect_constructor_new(m);
1752 /* Store object into array. */
1754 array_objectarray_element_set(oa, index, rc);
1764 /* class_get_declaredfields ****************************************************
1766 Return an array of declared fields of the given class.
1769 c ............ class to get the fields of
1770 publicOnly ... show only public fields
1773 array of java.lang.reflect.Field
1775 *******************************************************************************/
1777 #if defined(ENABLE_JAVASE)
1778 java_handle_objectarray_t *class_get_declaredfields(classinfo *c, bool publicOnly)
1780 java_handle_objectarray_t *oa;
1787 /* Determine number of fields. */
1791 for (i = 0; i < c->fieldscount; i++)
1792 if ((c->fields[i].flags & ACC_PUBLIC) || (publicOnly == 0))
1795 /* Create array of fields. */
1797 oa = builtin_anewarray(count, class_java_lang_reflect_Field);
1802 /* Get the fields and store them in the array. */
1804 for (i = 0, index = 0; i < c->fieldscount; i++) {
1805 f = &(c->fields[i]);
1807 if ((f->flags & ACC_PUBLIC) || (publicOnly == 0)) {
1808 /* Create Field object. This is actualy a
1809 java_lang_reflect_Field pointer, but we use a
1810 java_handle_t here, because we don't have the header
1811 available when building vmcore. */
1813 h = reflect_field_new(f);
1815 /* Store object into array. */
1817 array_objectarray_element_set(oa, index, h);
1827 /* class_get_declaredmethods ***************************************************
1829 Return an array of declared methods of the given class.
1832 c ............ class to get the methods of
1833 publicOnly ... show only public methods
1836 array of java.lang.reflect.Method
1838 *******************************************************************************/
1840 #if defined(ENABLE_JAVASE)
1841 java_handle_objectarray_t *class_get_declaredmethods(classinfo *c, bool publicOnly)
1843 java_handle_objectarray_t *oa; /* result: array of Method-objects */
1844 methodinfo *m; /* the current method to be represented */
1850 /* JOWENN: array classes do not declare methods according to mauve
1851 test. It should be considered, if we should return to my old
1852 clone method overriding instead of declaring it as a member
1855 if (class_is_array(c))
1856 return builtin_anewarray(0, class_java_lang_reflect_Method);
1858 /* Determine number of methods. */
1862 for (i = 0; i < c->methodscount; i++) {
1863 m = &(c->methods[i]);
1865 if (((m->flags & ACC_PUBLIC) || (publicOnly == false)) &&
1866 ((m->name != utf_init) && (m->name != utf_clinit)) &&
1867 !(m->flags & ACC_MIRANDA))
1871 /* Create array of methods. */
1873 oa = builtin_anewarray(count, class_java_lang_reflect_Method);
1878 /* Get the methods and store them in the array. */
1880 for (i = 0, index = 0; i < c->methodscount; i++) {
1881 m = &(c->methods[i]);
1883 if (((m->flags & ACC_PUBLIC) || (publicOnly == false)) &&
1884 ((m->name != utf_init) && (m->name != utf_clinit)) &&
1885 !(m->flags & ACC_MIRANDA)) {
1886 /* Create method object. This is actualy a
1887 java_lang_reflect_Method pointer, but we use a
1888 java_handle_t here, because we don't have the header
1889 available when building vmcore. */
1891 h = reflect_method_new(m);
1893 /* Store object into array. */
1895 array_objectarray_element_set(oa, index, h);
1905 /* class_get_declaringclass ****************************************************
1907 If the class or interface given is a member of another class,
1908 return the declaring class. For array and primitive classes return
1911 *******************************************************************************/
1913 classinfo *class_get_declaringclass(classinfo *c)
1915 classref_or_classinfo cr;
1918 /* Get declaring class. */
1920 cr = c->declaringclass;
1925 /* Resolve the class if necessary. */
1927 if (IS_CLASSREF(cr)) {
1928 /* dc = resolve_classref_eager(cr.ref); */
1929 dc = resolve_classref_or_classinfo_eager(cr, true);
1934 /* Store the resolved class in the class structure. */
1945 /* class_get_enclosingclass ****************************************************
1947 Return the enclosing class for the given class.
1949 *******************************************************************************/
1951 classinfo *class_get_enclosingclass(classinfo *c)
1953 classref_or_classinfo cr;
1956 /* Get enclosing class. */
1958 cr = c->enclosingclass;
1963 /* Resolve the class if necessary. */
1965 if (IS_CLASSREF(cr)) {
1966 /* ec = resolve_classref_eager(cr.ref); */
1967 ec = resolve_classref_or_classinfo_eager(cr, true);
1972 /* Store the resolved class in the class structure. */
1984 * Return the enclosing constructor as java.lang.reflect.Constructor
1985 * object for the given class.
1987 * @param c class to return the enclosing constructor for
1989 * @return java.lang.reflect.Constructor object of the enclosing
1992 #if defined(ENABLE_JAVASE)
1993 java_handle_t* class_get_enclosingconstructor(classinfo *c)
1998 m = class_get_enclosingmethod_raw(c);
2003 /* Check for <init>. */
2005 if (m->name != utf_init)
2008 /* Create Constructor object. */
2010 rc = reflect_constructor_new(m);
2017 /* class_get_enclosingmethod ***************************************************
2019 Return the enclosing method for the given class.
2022 c ... class to return the enclosing method for
2025 methodinfo of the enclosing method
2027 *******************************************************************************/
2029 methodinfo *class_get_enclosingmethod_raw(classinfo *c)
2031 constant_nameandtype *cn;
2035 /* get enclosing class and method */
2037 ec = class_get_enclosingclass(c);
2038 cn = c->enclosingmethod;
2040 /* check for enclosing class and method */
2048 /* find method in enclosing class */
2050 m = class_findmethod(ec, cn->name, cn->descriptor);
2053 exceptions_throw_internalerror("Enclosing method doesn't exist");
2062 * Return the enclosing method as java.lang.reflect.Method object for
2065 * @param c class to return the enclosing method for
2067 * @return java.lang.reflect.Method object of the enclosing method
2069 #if defined(ENABLE_JAVASE)
2070 java_handle_t* class_get_enclosingmethod(classinfo *c)
2075 m = class_get_enclosingmethod_raw(c);
2080 /* check for <init> */
2082 if (m->name == utf_init)
2085 /* create java.lang.reflect.Method object */
2087 rm = reflect_method_new(m);
2094 /* class_get_interfaces ********************************************************
2096 Return an array of interfaces of the given class.
2098 *******************************************************************************/
2100 java_handle_objectarray_t *class_get_interfaces(classinfo *c)
2103 java_handle_objectarray_t *oa;
2106 if (!(c->state & CLASS_LINKED))
2110 oa = builtin_anewarray(c->interfacescount, class_java_lang_Class);
2115 for (i = 0; i < c->interfacescount; i++) {
2116 ic = c->interfaces[i];
2118 LLNI_array_direct(oa, i) = (java_object_t *) ic;
2125 /* class_get_annotations *******************************************************
2127 Get the unparsed declared annotations in a byte array
2131 c........the class of which the annotations should be returned
2134 The unparsed declared annotations in a byte array
2135 (or NULL if there aren't any).
2137 *******************************************************************************/
2139 java_handle_bytearray_t *class_get_annotations(classinfo *c)
2141 #if defined(ENABLE_ANNOTATIONS)
2142 java_handle_t *annotations; /* unparsed annotations */
2144 LLNI_classinfo_field_get(c, annotations, annotations);
2146 return (java_handle_bytearray_t*)annotations;
2153 /* class_get_modifiers *********************************************************
2155 Get the modifier flags of the given class.
2158 c....the class of which the modifier flags should be returned
2159 ignoreInnerClassesAttrib
2163 *******************************************************************************/
2165 int32_t class_get_modifiers(classinfo *c, bool ignoreInnerClassesAttrib)
2167 classref_or_classinfo inner;
2168 classref_or_classinfo outer;
2172 if (!ignoreInnerClassesAttrib && (c->innerclasscount != 0)) {
2173 /* search for passed class as inner class */
2175 for (i = 0; i < c->innerclasscount; i++) {
2176 inner = c->innerclass[i].inner_class;
2177 outer = c->innerclass[i].outer_class;
2179 /* Check if inner is a classref or a real class and get
2180 the name of the structure */
2182 innername = IS_CLASSREF(inner) ? inner.ref->name : inner.cls->name;
2184 /* innerclass is this class */
2186 if (innername == c->name) {
2187 /* has the class actually an outer class? */
2190 /* return flags got from the outer class file */
2191 return c->innerclass[i].flags & ACC_CLASS_REFLECT_MASK;
2193 return c->flags & ACC_CLASS_REFLECT_MASK;
2198 /* passed class is no inner class or it was not requested */
2200 return c->flags & ACC_CLASS_REFLECT_MASK;
2204 /* class_get_signature *********************************************************
2206 Return the signature of the given class. For array and primitive
2207 classes return NULL.
2209 *******************************************************************************/
2211 #if defined(ENABLE_JAVASE)
2212 utf *class_get_signature(classinfo *c)
2214 /* For array and primitive classes return NULL. */
2216 if (class_is_array(c) || class_is_primitive(c))
2219 return c->signature;
2224 /* class_printflags ************************************************************
2226 Prints flags of a class.
2228 *******************************************************************************/
2230 #if !defined(NDEBUG)
2231 void class_printflags(classinfo *c)
2238 if (c->flags & ACC_PUBLIC) printf(" PUBLIC");
2239 if (c->flags & ACC_PRIVATE) printf(" PRIVATE");
2240 if (c->flags & ACC_PROTECTED) printf(" PROTECTED");
2241 if (c->flags & ACC_STATIC) printf(" STATIC");
2242 if (c->flags & ACC_FINAL) printf(" FINAL");
2243 if (c->flags & ACC_SYNCHRONIZED) printf(" SYNCHRONIZED");
2244 if (c->flags & ACC_VOLATILE) printf(" VOLATILE");
2245 if (c->flags & ACC_TRANSIENT) printf(" TRANSIENT");
2246 if (c->flags & ACC_NATIVE) printf(" NATIVE");
2247 if (c->flags & ACC_INTERFACE) printf(" INTERFACE");
2248 if (c->flags & ACC_ABSTRACT) printf(" ABSTRACT");
2253 /* class_print *****************************************************************
2255 Prints classname plus flags.
2257 *******************************************************************************/
2259 #if !defined(NDEBUG)
2260 void class_print(classinfo *c)
2267 utf_display_printable_ascii(c->name);
2268 class_printflags(c);
2273 /* class_classref_print ********************************************************
2275 Prints classname plus referer class.
2277 *******************************************************************************/
2279 #if !defined(NDEBUG)
2280 void class_classref_print(constant_classref *cr)
2287 utf_display_printable_ascii(cr->name);
2290 class_print(cr->referer);
2298 /* class_println ***************************************************************
2300 Prints classname plus flags and new line.
2302 *******************************************************************************/
2304 #if !defined(NDEBUG)
2305 void class_println(classinfo *c)
2313 /* class_classref_println ******************************************************
2315 Prints classname plus referer class and new line.
2317 *******************************************************************************/
2319 #if !defined(NDEBUG)
2320 void class_classref_println(constant_classref *cr)
2322 class_classref_print(cr);
2328 /* class_classref_or_classinfo_print *******************************************
2330 Prints classname plus referer class.
2332 *******************************************************************************/
2334 #if !defined(NDEBUG)
2335 void class_classref_or_classinfo_print(classref_or_classinfo c)
2337 if (c.any == NULL) {
2338 printf("(classref_or_classinfo) NULL");
2342 class_classref_print(c.ref);
2349 /* class_classref_or_classinfo_println *****************************************
2351 Prints classname plus referer class and a newline.
2353 *******************************************************************************/
2355 #if !defined(NDEBUG)
2356 void class_classref_or_classinfo_println(classref_or_classinfo c)
2358 class_classref_or_classinfo_print(c);
2364 /* class_showconstantpool ******************************************************
2366 Dump the constant pool of the given class to stdout.
2368 *******************************************************************************/
2370 #if !defined(NDEBUG)
2371 void class_showconstantpool (classinfo *c)
2376 printf ("---- dump of constant pool ----\n");
2378 for (i=0; i<c->cpcount; i++) {
2379 printf ("#%d: ", (int) i);
2381 e = c -> cpinfos [i];
2384 switch (c -> cptags [i]) {
2385 case CONSTANT_Class:
2386 printf ("Classreference -> ");
2387 utf_display_printable_ascii ( ((constant_classref*)e) -> name );
2389 case CONSTANT_Fieldref:
2390 printf ("Fieldref -> ");
2391 field_fieldref_print((constant_FMIref *) e);
2393 case CONSTANT_Methodref:
2394 printf ("Methodref -> ");
2395 method_methodref_print((constant_FMIref *) e);
2397 case CONSTANT_InterfaceMethodref:
2398 printf ("InterfaceMethod -> ");
2399 method_methodref_print((constant_FMIref *) e);
2401 case CONSTANT_String:
2402 printf ("String -> ");
2403 utf_display_printable_ascii (e);
2405 case CONSTANT_Integer:
2406 printf ("Integer -> %d", (int) ( ((constant_integer*)e) -> value) );
2408 case CONSTANT_Float:
2409 printf ("Float -> %f", ((constant_float*)e) -> value);
2411 case CONSTANT_Double:
2412 printf ("Double -> %f", ((constant_double*)e) -> value);
2416 u8 v = ((constant_long*)e) -> value;
2418 printf ("Long -> %ld", (long int) v);
2420 printf ("Long -> HI: %ld, LO: %ld\n",
2421 (long int) v.high, (long int) v.low);
2425 case CONSTANT_NameAndType:
2427 constant_nameandtype *cnt = e;
2428 printf ("NameAndType: ");
2429 utf_display_printable_ascii (cnt->name);
2431 utf_display_printable_ascii (cnt->descriptor);
2435 printf ("Utf8 -> ");
2436 utf_display_printable_ascii (e);
2439 log_text("Invalid type of ConstantPool-Entry");
2447 #endif /* !defined(NDEBUG) */
2450 /* class_showmethods ***********************************************************
2452 Dump info about the fields and methods of the given class to stdout.
2454 *******************************************************************************/
2456 #if !defined(NDEBUG)
2457 void class_showmethods (classinfo *c)
2461 printf("--------- Fields and Methods ----------------\n");
2463 class_printflags(c);
2467 utf_display_printable_ascii(c->name);
2472 utf_display_printable_ascii(c->super->name);
2476 printf("Index: %d\n", c->index);
2478 printf("Interfaces:\n");
2479 for (i = 0; i < c->interfacescount; i++) {
2481 utf_display_printable_ascii(c->interfaces[i]->name);
2482 printf (" (%d)\n", c->interfaces[i]->index);
2485 printf("Fields:\n");
2486 for (i = 0; i < c->fieldscount; i++)
2487 field_println(&(c->fields[i]));
2489 printf("Methods:\n");
2490 for (i = 0; i < c->methodscount; i++) {
2491 methodinfo *m = &(c->methods[i]);
2493 if (!(m->flags & ACC_STATIC))
2494 printf("vftblindex: %d ", m->vftblindex);
2499 printf ("Virtual function table:\n");
2500 for (i = 0; i < c->vftbl->vftbllength; i++)
2501 printf ("entry: %d, %ld\n", i, (long int) (c->vftbl->table[i]));
2503 #endif /* !defined(NDEBUG) */
2507 * These are local overrides for various environment variables in Emacs.
2508 * Please do not remove this and leave it at the end of the file, where
2509 * Emacs will automagically detect them.
2510 * ---------------------------------------------------------------------
2513 * indent-tabs-mode: t
2517 * vim:noexpandtab:sw=4:ts=4: