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.hpp"
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, void*, 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 void* 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 void* 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)
1341 for (int32_t i = 0; i < c->fieldscount; i++) {
1342 fieldinfo* f = &(c->fields[i]);
1344 if (f->name == name)
1349 exceptions_throw_nosuchfielderror(c, name);
1354 /****************** Function: class_resolvefield_int ***************************
1356 This is an internally used helper function. Do not use this directly.
1358 Tries to resolve a field having the given name and type.
1359 If the field cannot be resolved, NULL is returned.
1361 *******************************************************************************/
1363 static fieldinfo *class_resolvefield_int(classinfo *c, utf *name, utf *desc)
1368 /* search for field in class c */
1370 for (i = 0; i < c->fieldscount; i++) {
1371 if ((c->fields[i].name == name) && (c->fields[i].descriptor == desc)) {
1372 return &(c->fields[i]);
1376 /* Try super interfaces recursively. */
1378 for (i = 0; i < c->interfacescount; i++) {
1379 fi = class_resolvefield_int(c->interfaces[i], name, desc);
1385 /* Try super class. */
1387 if (c->super != NULL)
1388 return class_resolvefield_int(c->super, name, desc);
1396 /********************* Function: class_resolvefield ***************************
1398 Resolves a reference from REFERER to a field with NAME and DESC in class C.
1400 If the field cannot be resolved, an exception is thrown and the
1401 return value is NULL.
1403 *******************************************************************************/
1405 fieldinfo *class_resolvefield(classinfo *c, utf *name, utf *desc, classinfo *referer)
1409 fi = class_resolvefield_int(c, name, desc);
1412 exceptions_throw_nosuchfielderror(c, name);
1416 /* XXX check access rights */
1422 /* class_issubclass ************************************************************
1424 Checks if sub is a descendant of super.
1426 *******************************************************************************/
1428 bool class_issubclass(classinfo *sub, classinfo *super)
1435 /* We reached java/lang/Object and did not find the requested
1441 /* We found the requested super class. */
1451 /* class_isanysubclass *********************************************************
1453 Checks a subclass relation between two classes. Implemented
1454 interfaces are interpreted as super classes.
1456 Return value: 1 ... sub is subclass of super
1459 *******************************************************************************/
1461 bool class_isanysubclass(classinfo *sub, classinfo *super)
1466 /* This is the trivial case. */
1471 /* Primitive classes are only subclasses of themselves. */
1473 if (class_is_primitive(sub) || class_is_primitive(super))
1476 /* Check for interfaces. */
1478 if (super->flags & ACC_INTERFACE) {
1479 result = (sub->vftbl->interfacetablelength > super->index) &&
1480 (sub->vftbl->interfacetable[-super->index] != NULL);
1483 /* java.lang.Object is the only super class of any
1486 if (sub->flags & ACC_INTERFACE)
1487 return (super == class_java_lang_Object);
1489 LOCK_MONITOR_ENTER(linker_classrenumber_lock);
1491 diffval = sub->vftbl->baseval - super->vftbl->baseval;
1492 result = diffval <= (uint32_t) super->vftbl->diffval;
1494 LOCK_MONITOR_EXIT(linker_classrenumber_lock);
1501 /* class_is_assignable_from ****************************************************
1503 Return whether an instance of the "from" class parameter would be
1504 an instance of this class "to" as well.
1511 true .... is assignable
1512 false ... is not assignable
1514 *******************************************************************************/
1516 bool class_is_assignable_from(classinfo *to, classinfo *from)
1518 if (!(to->state & CLASS_LINKED))
1519 if (!link_class(to))
1522 if (!(from->state & CLASS_LINKED))
1523 if (!link_class(from))
1526 return class_isanysubclass(from, to);
1530 /* class_is_instance ***********************************************************
1532 Return if the given Java object is an instance of the given class.
1539 true .... is instance
1540 false ... is not instance
1542 *******************************************************************************/
1544 bool class_is_instance(classinfo *c, java_handle_t *h)
1546 if (!(c->state & CLASS_LINKED))
1550 return builtin_instanceof(h, c);
1554 /* class_get_componenttype *****************************************************
1556 Return the component class of the given class. If the given class
1557 is not an array, return NULL.
1559 *******************************************************************************/
1561 classinfo *class_get_componenttype(classinfo *c)
1563 classinfo *component;
1564 arraydescriptor *ad;
1566 /* XXX maybe we could find a way to do this without linking. */
1567 /* This way should be safe and easy, however. */
1569 if (!(c->state & CLASS_LINKED))
1573 ad = c->vftbl->arraydesc;
1578 if (ad->arraytype == ARRAYTYPE_OBJECT)
1579 component = ad->componentvftbl->clazz;
1581 component = Primitive_get_class_by_type(ad->arraytype);
1587 /* class_get_declaredclasses ***************************************************
1589 Return an array of declared classes of the given class.
1591 *******************************************************************************/
1593 java_handle_objectarray_t *class_get_declaredclasses(classinfo *c, bool publicOnly)
1595 classref_or_classinfo inner;
1596 classref_or_classinfo outer;
1598 int declaredclasscount; /* number of declared classes */
1599 int pos; /* current declared class */
1600 java_handle_objectarray_t *oa; /* array of declared classes */
1604 declaredclasscount = 0;
1606 if (!class_is_primitive(c) && !class_is_array(c)) {
1607 /* Determine number of declared classes. */
1609 for (i = 0; i < c->innerclasscount; i++) {
1610 /* Get outer-class. If the inner-class is not a member
1611 class, the outer-class is NULL. */
1613 outer = c->innerclass[i].outer_class;
1615 if (outer.any == NULL)
1618 /* Check if outer-class is a classref or a real class and
1619 get the class name from the structure. */
1621 outername = IS_CLASSREF(outer) ? outer.ref->name : outer.cls->name;
1623 /* Outer class is this class. */
1625 if ((outername == c->name) &&
1626 ((publicOnly == 0) || (c->innerclass[i].flags & ACC_PUBLIC)))
1627 declaredclasscount++;
1631 /* Allocate Class[] and check for OOM. */
1633 oa = builtin_anewarray(declaredclasscount, class_java_lang_Class);
1638 for (i = 0, pos = 0; i < c->innerclasscount; i++) {
1639 inner = c->innerclass[i].inner_class;
1640 outer = c->innerclass[i].outer_class;
1642 /* Get outer-class. If the inner-class is not a member class,
1643 the outer-class is NULL. */
1645 if (outer.any == NULL)
1648 /* Check if outer_class is a classref or a real class and get
1649 the class name from the structure. */
1651 outername = IS_CLASSREF(outer) ? outer.ref->name : outer.cls->name;
1653 /* Outer class is this class. */
1655 if ((outername == c->name) &&
1656 ((publicOnly == 0) || (c->innerclass[i].flags & ACC_PUBLIC))) {
1658 ic = resolve_classref_or_classinfo_eager(inner, false);
1663 if (!(ic->state & CLASS_LINKED))
1664 if (!link_class(ic))
1667 LLNI_array_direct(oa, pos++) = (java_object_t *) ic;
1676 * Return an array of declared constructors of the given class.
1678 * @param c class to get the constructors of
1679 * @param publicOnly show only public fields
1681 * @return array of java.lang.reflect.Constructor
1683 #if defined(ENABLE_JAVASE)
1684 java_handle_objectarray_t *class_get_declaredconstructors(classinfo *c, bool publicOnly)
1687 java_handle_objectarray_t* oa;
1693 /* Determine number of constructors. */
1697 for (i = 0; i < c->methodscount; i++) {
1698 m = &(c->methods[i]);
1700 if (((m->flags & ACC_PUBLIC) || (publicOnly == 0)) &&
1701 (m->name == utf_init))
1705 /* Create array of constructors. */
1707 oa = builtin_anewarray(count, class_java_lang_reflect_Constructor);
1712 /* Get the constructors and store them in the array. */
1714 for (i = 0, index = 0; i < c->methodscount; i++) {
1715 m = &(c->methods[i]);
1717 if (((m->flags & ACC_PUBLIC) || (publicOnly == 0)) &&
1718 (m->name == utf_init)) {
1719 /* Create Constructor object. This is actualy a
1720 java_lang_reflect_Constructor pointer, but we use a
1721 java_handle_t here, because we don't have the header
1722 available when building vmcore. */
1724 rc = reflect_constructor_new(m);
1726 /* Store object into array. */
1728 array_objectarray_element_set(oa, index, rc);
1738 /* class_get_declaredfields ****************************************************
1740 Return an array of declared fields of the given class.
1743 c ............ class to get the fields of
1744 publicOnly ... show only public fields
1747 array of java.lang.reflect.Field
1749 *******************************************************************************/
1751 #if defined(ENABLE_JAVASE)
1752 java_handle_objectarray_t *class_get_declaredfields(classinfo *c, bool publicOnly)
1754 java_handle_objectarray_t *oa;
1761 /* Determine number of fields. */
1765 for (i = 0; i < c->fieldscount; i++)
1766 if ((c->fields[i].flags & ACC_PUBLIC) || (publicOnly == 0))
1769 /* Create array of fields. */
1771 oa = builtin_anewarray(count, class_java_lang_reflect_Field);
1776 /* Get the fields and store them in the array. */
1778 for (i = 0, index = 0; i < c->fieldscount; i++) {
1779 f = &(c->fields[i]);
1781 if ((f->flags & ACC_PUBLIC) || (publicOnly == 0)) {
1782 /* Create Field object. This is actualy a
1783 java_lang_reflect_Field pointer, but we use a
1784 java_handle_t here, because we don't have the header
1785 available when building vmcore. */
1787 h = reflect_field_new(f);
1789 /* Store object into array. */
1791 array_objectarray_element_set(oa, index, h);
1801 /* class_get_declaredmethods ***************************************************
1803 Return an array of declared methods of the given class.
1806 c ............ class to get the methods of
1807 publicOnly ... show only public methods
1810 array of java.lang.reflect.Method
1812 *******************************************************************************/
1814 #if defined(ENABLE_JAVASE)
1815 java_handle_objectarray_t *class_get_declaredmethods(classinfo *c, bool publicOnly)
1817 java_handle_objectarray_t *oa; /* result: array of Method-objects */
1818 methodinfo *m; /* the current method to be represented */
1824 /* JOWENN: array classes do not declare methods according to mauve
1825 test. It should be considered, if we should return to my old
1826 clone method overriding instead of declaring it as a member
1829 if (class_is_array(c))
1830 return builtin_anewarray(0, class_java_lang_reflect_Method);
1832 /* Determine number of methods. */
1836 for (i = 0; i < c->methodscount; i++) {
1837 m = &(c->methods[i]);
1839 if (((m->flags & ACC_PUBLIC) || (publicOnly == false)) &&
1840 ((m->name != utf_init) && (m->name != utf_clinit)) &&
1841 !(m->flags & ACC_MIRANDA))
1845 /* Create array of methods. */
1847 oa = builtin_anewarray(count, class_java_lang_reflect_Method);
1852 /* Get the methods and store them in the array. */
1854 for (i = 0, index = 0; i < c->methodscount; i++) {
1855 m = &(c->methods[i]);
1857 if (((m->flags & ACC_PUBLIC) || (publicOnly == false)) &&
1858 ((m->name != utf_init) && (m->name != utf_clinit)) &&
1859 !(m->flags & ACC_MIRANDA)) {
1860 /* Create method object. This is actualy a
1861 java_lang_reflect_Method pointer, but we use a
1862 java_handle_t here, because we don't have the header
1863 available when building vmcore. */
1865 h = reflect_method_new(m);
1867 /* Store object into array. */
1869 array_objectarray_element_set(oa, index, h);
1879 /* class_get_declaringclass ****************************************************
1881 If the class or interface given is a member of another class,
1882 return the declaring class. For array and primitive classes return
1885 *******************************************************************************/
1887 classinfo *class_get_declaringclass(classinfo *c)
1889 classref_or_classinfo cr;
1892 /* Get declaring class. */
1894 cr = c->declaringclass;
1899 /* Resolve the class if necessary. */
1901 if (IS_CLASSREF(cr)) {
1902 /* dc = resolve_classref_eager(cr.ref); */
1903 dc = resolve_classref_or_classinfo_eager(cr, true);
1908 /* Store the resolved class in the class structure. */
1919 /* class_get_enclosingclass ****************************************************
1921 Return the enclosing class for the given class.
1923 *******************************************************************************/
1925 classinfo *class_get_enclosingclass(classinfo *c)
1927 classref_or_classinfo cr;
1930 /* Get enclosing class. */
1932 cr = c->enclosingclass;
1937 /* Resolve the class if necessary. */
1939 if (IS_CLASSREF(cr)) {
1940 /* ec = resolve_classref_eager(cr.ref); */
1941 ec = resolve_classref_or_classinfo_eager(cr, true);
1946 /* Store the resolved class in the class structure. */
1958 * Return the enclosing constructor as java.lang.reflect.Constructor
1959 * object for the given class.
1961 * @param c class to return the enclosing constructor for
1963 * @return java.lang.reflect.Constructor object of the enclosing
1966 #if defined(ENABLE_JAVASE)
1967 java_handle_t* class_get_enclosingconstructor(classinfo *c)
1972 m = class_get_enclosingmethod_raw(c);
1977 /* Check for <init>. */
1979 if (m->name != utf_init)
1982 /* Create Constructor object. */
1984 rc = reflect_constructor_new(m);
1991 /* class_get_enclosingmethod ***************************************************
1993 Return the enclosing method for the given class.
1996 c ... class to return the enclosing method for
1999 methodinfo of the enclosing method
2001 *******************************************************************************/
2003 methodinfo *class_get_enclosingmethod_raw(classinfo *c)
2005 constant_nameandtype *cn;
2009 /* get enclosing class and method */
2011 ec = class_get_enclosingclass(c);
2012 cn = c->enclosingmethod;
2014 /* check for enclosing class and method */
2022 /* find method in enclosing class */
2024 m = class_findmethod(ec, cn->name, cn->descriptor);
2027 exceptions_throw_internalerror("Enclosing method doesn't exist");
2036 * Return the enclosing method as java.lang.reflect.Method object for
2039 * @param c class to return the enclosing method for
2041 * @return java.lang.reflect.Method object of the enclosing method
2043 #if defined(ENABLE_JAVASE)
2044 java_handle_t* class_get_enclosingmethod(classinfo *c)
2049 m = class_get_enclosingmethod_raw(c);
2054 /* check for <init> */
2056 if (m->name == utf_init)
2059 /* create java.lang.reflect.Method object */
2061 rm = reflect_method_new(m);
2068 /* class_get_interfaces ********************************************************
2070 Return an array of interfaces of the given class.
2072 *******************************************************************************/
2074 java_handle_objectarray_t *class_get_interfaces(classinfo *c)
2077 java_handle_objectarray_t *oa;
2080 if (!(c->state & CLASS_LINKED))
2084 oa = builtin_anewarray(c->interfacescount, class_java_lang_Class);
2089 for (i = 0; i < c->interfacescount; i++) {
2090 ic = c->interfaces[i];
2092 LLNI_array_direct(oa, i) = (java_object_t *) ic;
2099 /* class_get_annotations *******************************************************
2101 Get the unparsed declared annotations in a byte array
2105 c........the class of which the annotations should be returned
2108 The unparsed declared annotations in a byte array
2109 (or NULL if there aren't any).
2111 *******************************************************************************/
2113 java_handle_bytearray_t *class_get_annotations(classinfo *c)
2115 #if defined(ENABLE_ANNOTATIONS)
2116 java_handle_t *annotations; /* unparsed annotations */
2118 LLNI_classinfo_field_get(c, annotations, annotations);
2120 return (java_handle_bytearray_t*)annotations;
2127 /* class_get_modifiers *********************************************************
2129 Get the modifier flags of the given class.
2132 c....the class of which the modifier flags should be returned
2133 ignoreInnerClassesAttrib
2137 *******************************************************************************/
2139 int32_t class_get_modifiers(classinfo *c, bool ignoreInnerClassesAttrib)
2141 classref_or_classinfo inner;
2142 classref_or_classinfo outer;
2146 if (!ignoreInnerClassesAttrib && (c->innerclasscount != 0)) {
2147 /* search for passed class as inner class */
2149 for (i = 0; i < c->innerclasscount; i++) {
2150 inner = c->innerclass[i].inner_class;
2151 outer = c->innerclass[i].outer_class;
2153 /* Check if inner is a classref or a real class and get
2154 the name of the structure */
2156 innername = IS_CLASSREF(inner) ? inner.ref->name : inner.cls->name;
2158 /* innerclass is this class */
2160 if (innername == c->name) {
2161 /* has the class actually an outer class? */
2164 /* return flags got from the outer class file */
2165 return c->innerclass[i].flags & ACC_CLASS_REFLECT_MASK;
2167 return c->flags & ACC_CLASS_REFLECT_MASK;
2172 /* passed class is no inner class or it was not requested */
2174 return c->flags & ACC_CLASS_REFLECT_MASK;
2178 /* class_get_signature *********************************************************
2180 Return the signature of the given class. For array and primitive
2181 classes return NULL.
2183 *******************************************************************************/
2185 #if defined(ENABLE_JAVASE)
2186 utf *class_get_signature(classinfo *c)
2188 /* For array and primitive classes return NULL. */
2190 if (class_is_array(c) || class_is_primitive(c))
2193 return c->signature;
2198 /* class_printflags ************************************************************
2200 Prints flags of a class.
2202 *******************************************************************************/
2204 #if !defined(NDEBUG)
2205 void class_printflags(classinfo *c)
2212 if (c->flags & ACC_PUBLIC) printf(" PUBLIC");
2213 if (c->flags & ACC_PRIVATE) printf(" PRIVATE");
2214 if (c->flags & ACC_PROTECTED) printf(" PROTECTED");
2215 if (c->flags & ACC_STATIC) printf(" STATIC");
2216 if (c->flags & ACC_FINAL) printf(" FINAL");
2217 if (c->flags & ACC_SYNCHRONIZED) printf(" SYNCHRONIZED");
2218 if (c->flags & ACC_VOLATILE) printf(" VOLATILE");
2219 if (c->flags & ACC_TRANSIENT) printf(" TRANSIENT");
2220 if (c->flags & ACC_NATIVE) printf(" NATIVE");
2221 if (c->flags & ACC_INTERFACE) printf(" INTERFACE");
2222 if (c->flags & ACC_ABSTRACT) printf(" ABSTRACT");
2227 /* class_print *****************************************************************
2229 Prints classname plus flags.
2231 *******************************************************************************/
2233 #if !defined(NDEBUG)
2234 void class_print(classinfo *c)
2241 utf_display_printable_ascii(c->name);
2242 class_printflags(c);
2247 /* class_classref_print ********************************************************
2249 Prints classname plus referer class.
2251 *******************************************************************************/
2253 #if !defined(NDEBUG)
2254 void class_classref_print(constant_classref *cr)
2261 utf_display_printable_ascii(cr->name);
2264 class_print(cr->referer);
2272 /* class_println ***************************************************************
2274 Prints classname plus flags and new line.
2276 *******************************************************************************/
2278 #if !defined(NDEBUG)
2279 void class_println(classinfo *c)
2287 /* class_classref_println ******************************************************
2289 Prints classname plus referer class and new line.
2291 *******************************************************************************/
2293 #if !defined(NDEBUG)
2294 void class_classref_println(constant_classref *cr)
2296 class_classref_print(cr);
2302 /* class_classref_or_classinfo_print *******************************************
2304 Prints classname plus referer class.
2306 *******************************************************************************/
2308 #if !defined(NDEBUG)
2309 void class_classref_or_classinfo_print(classref_or_classinfo c)
2311 if (c.any == NULL) {
2312 printf("(classref_or_classinfo) NULL");
2316 class_classref_print(c.ref);
2323 /* class_classref_or_classinfo_println *****************************************
2325 Prints classname plus referer class and a newline.
2327 *******************************************************************************/
2329 #if !defined(NDEBUG)
2330 void class_classref_or_classinfo_println(classref_or_classinfo c)
2332 class_classref_or_classinfo_print(c);
2338 /* class_showconstantpool ******************************************************
2340 Dump the constant pool of the given class to stdout.
2342 *******************************************************************************/
2344 #if !defined(NDEBUG)
2345 void class_showconstantpool (classinfo *c)
2350 printf ("---- dump of constant pool ----\n");
2352 for (i=0; i<c->cpcount; i++) {
2353 printf ("#%d: ", (int) i);
2355 e = c -> cpinfos [i];
2358 switch (c -> cptags [i]) {
2359 case CONSTANT_Class:
2360 printf ("Classreference -> ");
2361 utf_display_printable_ascii ( ((constant_classref*)e) -> name );
2363 case CONSTANT_Fieldref:
2364 printf ("Fieldref -> ");
2365 field_fieldref_print((constant_FMIref *) e);
2367 case CONSTANT_Methodref:
2368 printf ("Methodref -> ");
2369 method_methodref_print((constant_FMIref *) e);
2371 case CONSTANT_InterfaceMethodref:
2372 printf ("InterfaceMethod -> ");
2373 method_methodref_print((constant_FMIref *) e);
2375 case CONSTANT_String:
2376 printf ("String -> ");
2377 utf_display_printable_ascii (e);
2379 case CONSTANT_Integer:
2380 printf ("Integer -> %d", (int) ( ((constant_integer*)e) -> value) );
2382 case CONSTANT_Float:
2383 printf ("Float -> %f", ((constant_float*)e) -> value);
2385 case CONSTANT_Double:
2386 printf ("Double -> %f", ((constant_double*)e) -> value);
2390 u8 v = ((constant_long*)e) -> value;
2392 printf ("Long -> %ld", (long int) v);
2394 printf ("Long -> HI: %ld, LO: %ld\n",
2395 (long int) v.high, (long int) v.low);
2399 case CONSTANT_NameAndType:
2401 constant_nameandtype *cnt = e;
2402 printf ("NameAndType: ");
2403 utf_display_printable_ascii (cnt->name);
2405 utf_display_printable_ascii (cnt->descriptor);
2409 printf ("Utf8 -> ");
2410 utf_display_printable_ascii (e);
2413 log_text("Invalid type of ConstantPool-Entry");
2421 #endif /* !defined(NDEBUG) */
2424 /* class_showmethods ***********************************************************
2426 Dump info about the fields and methods of the given class to stdout.
2428 *******************************************************************************/
2430 #if !defined(NDEBUG)
2431 void class_showmethods (classinfo *c)
2435 printf("--------- Fields and Methods ----------------\n");
2437 class_printflags(c);
2441 utf_display_printable_ascii(c->name);
2446 utf_display_printable_ascii(c->super->name);
2450 printf("Index: %d\n", c->index);
2452 printf("Interfaces:\n");
2453 for (i = 0; i < c->interfacescount; i++) {
2455 utf_display_printable_ascii(c->interfaces[i]->name);
2456 printf (" (%d)\n", c->interfaces[i]->index);
2459 printf("Fields:\n");
2460 for (i = 0; i < c->fieldscount; i++)
2461 field_println(&(c->fields[i]));
2463 printf("Methods:\n");
2464 for (i = 0; i < c->methodscount; i++) {
2465 methodinfo *m = &(c->methods[i]);
2467 if (!(m->flags & ACC_STATIC))
2468 printf("vftblindex: %d ", m->vftblindex);
2473 printf ("Virtual function table:\n");
2474 for (i = 0; i < c->vftbl->vftbllength; i++)
2475 printf ("entry: %d, %ld\n", i, (long int) (c->vftbl->table[i]));
2477 #endif /* !defined(NDEBUG) */
2481 * These are local overrides for various environment variables in Emacs.
2482 * Please do not remove this and leave it at the end of the file, where
2483 * Emacs will automagically detect them.
2484 * ---------------------------------------------------------------------
2487 * indent-tabs-mode: t
2491 * vim:noexpandtab:sw=4:ts=4: